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.

robust task switching

Other Parts Discussed in Thread: SYSBIOS

Hello!

I have two algorithms, and I wan to only run one of them at a time.  So, I've created two tasks (one for each algorithm).

There is also a third task I have created, to act as a "middle man", or a "switch".  This third task has the highest priority (5), and my other two tasks have low priority (-1) such that they only run when I directly tell them to.

This solution has been working quite well for me, until today.  I have two CCS projects, both nearly identical, except for some differences in the algorithms themselves.  Somehow one project works and the other does not work.

The broken output I see is this (sequentially):

  • First, the high priority "middle man" task starts.  It waits to be told what to do by checking a certain DDR value.
  • When that DDR value is triggered, the "middle man" task tells the appropriate other task to change his priority from -1 to +7. I use   Task_setPri(tsk0, 7)
  • I assume that now, tsk0 would have the highest priority (7), and would run my proprietary algorithm to completion.  Instead, however, it only computes the first line of code in my tsk0 function (which happens to be a printf statement I added to aid humans in debug).
  • Next, it immediately goes back to the start of my "middle man" task, starting over at the beginning.

What I also do not understand is that, at first, ROV did not show the priority changing on my tsk0.  I set a breakpoint on the "Task_setPri()" line, and after stepping over that line the task priority did not change in ROV.  So, at least with this it made sense why only my "middle man" task ran... because it was the highest priority!

So:  Since this made me doubt the Task_setPri(), I also experimented with setting all tasks to -1 priority in my .cfg file.  Then in main(), just immediately before BIOS_start(), I set the priority of my "middle man" task to 5.  This works, I see the desired result in ROV!  (tsk0 priority = 7, middle man priority = 5, & other algorithm priority = -1).

However - I still have the same problem that it does not stay in tsk0 (priority 7).  I see in ROV that tsk0 is priority 7, and my "middle man" task is priority 5.  This is exactly what it should be, but still my code never executes tsk0 past the first line (the printf statement).

How is it possible that SYSBIOS is switching back and forth between two tasks, when by definition only one task can run at a time - the task with the highest priority?

An alternate solution:

What if, instead of having three tasks, I had just one SYSBIOS task (with a larger stack, of course) and switched my two algorithms via regular function calls?  i.e.

Void task000()
{
   
 while(1) {
volatile int *x = (volatile int *)0x80000000; //DDR variable if(x == 0) do_alg1(); else if (x == 1) do_alg2(); } }

Thank you for sharing your thoughts with me!

 

[EDIT]   I also tried changing my tsk0 priority to 5, via Task_setPri(), when I want it to run.  Then, since both my "middle man" task and tsk0 will both be priority 5, I told the "middle man" task to yield via Task_yield().  Unfortunately - it just hung and did nothing; I expected that tsk0 would run because the "middle man" task was yielding to it.  I've attached a screenshot of my debug view to show this and another curious result - the ROV which shows that all of my task Stacks are maxed.  This is quite odd, because none of them have done anything yet except sit around and wait to be told to start!  :)

  • Update:

    I have switched to only one SYSBIOS task.  When I switch between my two algorithms, I do so via function calls.  My one task has a large stack.

    Unfortunately, I still have the same issue!

    Could it be that my stack pointer is somehow wrong/broken/skewed?  Is there a way I could check this?  When I get to this point in my program, and pause the cores via the JTAG debugger, it says that my core is at writemsg() for the printf statement.  The stack peak is orders of magnitude below the stack size, so I'm not getting overflow.

  • Hello TI -

    1) Should I move this post to a different forum?

    2) Are there any troubleshooting ideas I can try?  What other information do you need?

    3) How can I better understand what my code is doing?  It seems that my code is violating the laws of SYSBIOS & the laws of C programming language ... i.e. jumping back and forth between BIOS threads ... i.e. jumping back and forth between C functions without actually finishing any of them.

  • Hi Chris,


    Here are the things that could be going wrong based on your description

    1. Task stack is overflowed. Look in Tasks->Detailed ROV tab. I'd look at this before I ran the algorithm you modified and then after the algorithm is executed. You could also try increasing the Task stack sizes also.

    2. System Stack is overflowed. Again in ROV, look at Hwi->Module.

    3. Did you disable interrupts and forget to enable them?

    Todd

  • Hi Todd, I appreciate your help!

    1)  Running with only one BIOS Task:   My task stack looks good - the peak is 1076 when the size is 69,632.

    2)  (I had no idea this was the system stack!)  However, it also looks ok:   hwiStackPeak=380  & hwiStackSize=4096

    3)  I have not intentionally disabled interrupts.  In fact, I'm not trying to use any interrupts at all (other than printf/System_printf for debugging logic errors and such).


     

    Just now, I tried a scientific endeavour with my code to revert back to when it used to work.  Since it worked before I added my "second" custom algorithm, I just commented out the beef of that algorithm and now it works.  So - could it be that I have too much code (too many lines of code with variables predefined, etc) in my algorithm and that it confuses the stack?  Or could some other memory section be growing too large during run time, and writing over part of the stack?

     I'm relatively new to this and I'm eager to learn, thanks for your help.

  • It sounds like you have memory corruption in the code that you commented out. I'd look for un-initialized variables or writing past the end of an array. You can add assert calls into code to help. For example

    #include <xdc/runtime/Assert.h>
    ...
    Assert_isTrue((somePtr != NULL) , NULL);

    If the assert fails and you are in CCS, it's easy to debug.

    You can enable and disable the asserts during the build step. So you can leave the calls in and just disable them for production builds (or once the system is stable).

    Todd

  • I'm sure it has to do with this - this is the first time I've coded this algorithm in C and I wouldn't be surprised to find an indexing problem with my looping & arrays!

    I'll add some asserts also - they should help a great deal.

    Thanks again

  • Good news - I did have problems with uninitialized variables.  This is very fixable.

    Also, I found that my RTSC package was different that I had thought... so I was working with only half the L2 available!  Now I can make some easy changes to drastically improve my program.

  • Hi Chris,

    Glad to hear you found the problem (and the extra memory!).

    Todd