This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Program freezes when merging image processing & UART

Other Parts Discussed in Thread: CCSTUDIO

Hi all,
I have a program that receives input from a video port, does some processing & sends the output to another video port. This program also produce some numbers based on the processing.
I have another program (from DDK 1.20 example) that sends data over the serial port using UART.

Separately, the two program works fine. However when I tried to merge them (I want to send the numbers over the serial port), the program freezes whenever the UART codes is executed.<br>
Is there any known conflict between UART & video port? Or does anyone knows why the EVM might freeze? I'm thinking that the UART does not have enough time to complete its task, but I'm not sure how to solve this. No error messag eis received. I'm running CCS 3.3/EVMDM642/WinXP combo. The code is as follows:

while (1){

.. Some image processing codes ..

if (frames % 64 == 0) {             // to test when it freezes, 64 means code not executed until 64th frame, so program freezes later than, say 8
for (j = 0; j < 6; j++) {
   GIO_write(outChan, showRadius, &size);
   if (UARTStatus < 0) {
      LOG_printf(&trace, "GIO_write failed");
      SYS_abort("GIO_write");
      }
 }
}
frames ++;
}

Thanks
Hanief

  • Please explain more what you mean by "the program freezes". What result, if any, does your test code shown above report to you and how many times?

    You will be able to implement a system that runs both the video port and the UART, but it may require somethings to be setup differently that you have it setup today.

    If GIO_write() blocks all other accesses, then you would expect to lose some video data unless GIO_write() is faster than the vertical sync period or maybe than the frame period, depending on how your "Some image processing codes" is implemented. If interrupts are blocked too long, then data could be lost.

    If you reduce "size" to a smaller value, like even to 1 or 2, does the problem go away? Maybe you should even try reducing the for loop to use j<1 just for test purposes. The intent is to figure out what part of the code merge is leading to your problem.

  • A typical issue when combining applications is a "resource collision".  That is, if both applications rely on the same interrupt number, EDMA channel, etc. then one might clobber the other and you might never realize it.  This tends to happen most frequently when using APIs to plug interrupts at run-time (e.g. HWI_dispatchPlug).

  • RandyP,
    When I say "the program freezes", I mean no further output is received, i.e. no updates to video port/display nor serial port (connected to PC).
    At the moment, "size" is just 5, if I reduce it to any other value less than 5, the display flickers & only the first element of showRadius is sent. The for loop isn't really necessary, I added it because the DDK example has a for(;;) loop and to see if it makes any difference but I forgot to add a comment, sorry. So the actual UART code is as below:

    UARTStatus = GIO_write(outChan, showRadius, &size);
       if (UARTStatus < 0) {
        LOG_printf(&trace, "GIO_write failed");
        SYS_abort("GIO_write");
       }

    To be exact, as it stands, the program sends the 1st showRadius successfully, but freezes after sending the 4th element of the second showRadius. Example, if the values are 12345 and 67890 respectively, I only get 12345 and 6789.
    I'm not too familiar with GIO_write() so I don't know if it's too slow or blocking other processes. I guess I should mention that my image processing codes aren't exactly too fast, maybe ~ 4 FPS.

    Brad Griffis,
    Yeah, I guess there's a conflict between GIO_write & the image processing codes. Are you suggesting HWI_dispatchPlug as a possible solution? I'll read up on it.

    Thanks,
    Hanief

  • I am pretty sure Brad did not mean HWI_dispatchPlug could be a possible solution. He meant that if you used HWI_dispatchPlug in both programs, it would be very easy to mistakenly use the same interrupt resource for both programs, which would cause a resource conflict once they are merged.

    If you set size to 1, will you still get the flicker and one element of showRadius?

    From how I read the DSP/BIOS API Ref Guide, spru403j, GIO_write() is a blocking call, so for sure your video tasks would be blocked until all five chars are sent to the UART. If you rework it into a GIO_submit call with a callback function, you might be able to avoid that blocking action.

    Another option would be to do a lower-level access to the UART than GIO_*. But this would mean setting up an interrupt or EDMA sequence and checking the UART status and then writing the data, so the GIO_submit might be the easiest and cleanest solution.

  • Randy is right -- I was mentioning HWI_dispatchPlug as a *cause* not a solution!

    I think Randy has the answer though.  Your blocking call to GIO_write would surely wreak havoc!  I think Randy's suggestion of using a callback function (through GIO_submit) is a great one.  That way your call to GIO_write will not block.  If you don't actually NEED a callback function (e.g. fire and forget) then you could probably use a "dummy" callback like FXN_F_nop.

  • Oh ok, I've never heard of HWI_dispatchPlug before.

    If I set size to 1, the program works just fine. No flickering, but I do get just one element since I'm only sending one.

    I'll try GIO_submit let you guys know.

    Thanks,
    Hanief

  • So I have     UARTStatus = GIO_submit(outChan, IOM_WRITE, showRadius, &size, FXN_F_nop);

    But I've got a compilation error: argument of type "void (*)()" is incompatible with parameter of type "GIO_AppCallback *"
    Any pointers?

    Thanks,
    Hanief

  • The GIO_submit function call requires a pointer to a function of a certain type. It should work to simply cast it to the proper type like

    UARTStatus = GIO_submit(outChan, IOM_WRITE, showRadius, &size, (GIO_AppCallback *)  FXN_F_nop);

  • I tried that, the project builds successfully but with a warning: nonstandard conversion between pointer to function and pointer to data.

    I run the program anyway. This time, it stops after sending the 3rd element of the 2nd iteration (1 less than GIO_write). Reducing the size of &size lets the program run longer. Again when size = 1, the program ran continously without stopping.

  • GIO_AppCallback is apparently a struct and not a function pointer. My mistake for jumping to the conclusion that all it needed was a function pointer. If you look in the BIOS API guide, it should explain what the correct syntax is, and you may need to make a specific empty function to use the right args that GIO requires for its callback.

    We can hope GIO_submit was still treating the callback as a NULL just as with GIO_write, so with the correct struct and syntax it might stop blocking.

    But it might be possible that even GIO_submit will still block for more time than you can allow. In that case, either

    • Call GIO_write multiple times, always with size=1.
    • Directly setup DMA to send the 5 chars to the serial port and bypass GIO.

    But it may help to understand more about how the video is being manipulated and what might be interfered with in your system. This might help to tailor a solution.

  • Ok, so I created a struct with:    GIO_AppCallback* callbackStruct;

    The project builds fine, no warning. But when I run it, it again stops after sending 8 elements (3th of 2nd time). However, the strange thing is, the values of the 2nd iteration seems to be the same as the 1st, e.g. I always get 12345 & 123 or 67890 & 678.

    Concerning my video application, it was based on the evmdm642 video example (default location: C:\CCStudio_v3.3\boards\evmdm642\examples\video\driver). I suppose there could be a clash with the FVID structure (which uses IOM).

  • Hi, I have similar problem with UART too.

    Did TI give you an answer?

    It may be the stack overflow of the task. I've made the TX task size be 4096 and solved the freeze problem.

    My existing problem of UART is that it prints extra character some times (up to 7 extra characters). I guess there is some problem with the GIO_write. The data inside my TX buffer is fine. Have you encountered these kind of problem? Thx