Conditions for a flag to be ignored.

Conditions for a flag to be ignored.

Home Forums Real-Time Kernels Conditions for a flag to be ignored.

This topic contains 10 replies, has 2 voices, and was last updated by  Farukh Chaudhry 2 days, 6 hours ago.

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • #27326

    Dario Ivan vazquez
    Participant

    Hello everyone, I have the following situation:

    I am porting an application that runs correctly on an old target, for the new target, the uCOS-III was delivered ported, so we had to only port the application.

    we have 4 tasks on running, all 4 are waiting for a flag that gets raised on an IRQ, 3 of the 4 task are not running because the hardware has not been enabled so they are idle.

    we have a DMA that periodically interrupts every ~700us, the DMA only posts a flag and toggles a gpio line.
    This flag is consumed by the main task, the main task only increases a counter and toggles a gpio line.

    after some IRQ have been done (form 40 to 200 the counter always seems random) the flag stops to be consumed, I can see the IRQ toggle line but not the tasks toggle line.

    I stop the execution and check memory and the flag is posted, so the IRQ is actually posting the flag.

    Here is the question, which OS conditions could be preventing the flag from being consumed?

    #27335

    Farukh Chaudhry
    Participant

    Hello Dario,

    Can you describe how the flag pend and flag post operations are setup?

    Thanks

    #27337

    Dario Ivan vazquez
    Participant

    Hello Farukh,

    I dont understand but I will try to answer:

    The DMA Interrupt posts the flag:

    flags = OSFlagPost(&os_flag_grp_list[ShCore_Process_Task_Index], // An array of flags, the index is 2
                             SPORT4A_INTERRUPT,               // 0x0001
                             (OS_OPT)OS_OPT_POST_FLAG_SET,
                             &err);

    The Task Pends using:

    value = OSFlagPend(&os_flag_grp_list[ShCore_Process_Task_Index],
                             SPORT4A_INTERRUPT,   // 0x0001
                             (OS_TICK)WAIT_FOREVER_FOR_FLAG,
                             (OS_OPT)(OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME),
                             &ts,
                             &err);

    I am debbuging further, when the flag stops being consumed I checked the Task TCB:
    Task TBC

    Where

    .TaskState is  (2) for OS_TASK_STATE_PEND
    .PendOn is     (1) for OS_TASK_PEND_ON_FLAG
    .PendStatus is (0) for OS_STATUS_PEND_OK
    .FlagsPend is  0x0001 for 'SPORT4A_INTERRUPT'
    .FlagsRdy is   0x0000 so flag is not ready according to the TCB.

    It seems from this that the Flag is not being posted, so i checked the flag group:
    Flag Group

    Where you can see the .Flags element is 0x0001, so the Flag IS being posted.

    For some reason, when posting the flag, the Task is not being aware of the flag, remember that this flag is being consumed as shown in the .CtxSwCtr in this case is 0x52 so the flag was being consumed and then it stopped.

    any suggestions?

    • This reply was modified 4 days, 8 hours ago by  Dario Ivan vazquez. Reason: fixed image links
    #27339

    Farukh Chaudhry
    Participant

    Hello Dario,

    What return value are you getting for the pend flag call? The reason I ask is because you are using an array implementation for the OS_FLAG_GRP.

    #27340

    Dario Ivan vazquez
    Participant

    The pend call returns 0x0001, when it returns, What I meant by the flag not being consumed is that the pend call, eventually, stops returning, it gets hang, but the IRQ continues to post the flag regardless,

    the post call returns 0x0001 when the issue is NOT pressent, but returns 0x0000 when the issue appears, according to the documentation, the OSFlagPost returns: ‘The new value of the event flags’, but I can see the flag value on the debugger as 0x0001.

    #27342

    Dario Ivan vazquez
    Participant

    Hello,

    I have further development, this is my task code:

    while (1)
    {
      CPU_TS   ts;
      OS_FLAGS value;
    
      /* uC/OS-III: Waiting for SPORT4A_INTERRUPT event */
      value = OSFlagPend(&os_flag_grp_list[ShCore_Process_Task_Index],
                         SPORT4A_INTERRUPT,
                         (OS_TICK)WAIT_FOREVER_FOR_FLAG,
                         (OS_OPT)(OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME),
                         &ts,
                         &err);
      
      toggle_FlagPend_Pin();
    
      if(OS_ERR_NONE == err)
      {
         frame_process_count++;
      }
      else
      {
         /* TODO: To be removed, Invalid OSFlagPend */
         OSFlagPendError_Count++;
      }
    }

    I have added OSFlagPendGetFlagsRdy function, after the Pend, in theory it should always be equal to the flag we are waiting, in this case ‘SPORT4A_INTERRUPT’ so 0x0001, I added a check to see if at any point the return value is different from 0x0001 and set a breakpoint there, the code looks like this:

    while (1)
    {
      CPU_TS   ts;
      OS_FLAGS value;
    
      /* uC/OS-III: Waiting for SPORT4A_INTERRUPT event */
      value = OSFlagPend(&os_flag_grp_list[ShCore_Process_Task_Index],
                         SPORT4A_INTERRUPT,
                         (OS_TICK)WAIT_FOREVER_FOR_FLAG,
                         (OS_OPT)(OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME),
                         &ts,
                         &err);
      
      toggle_FlagPend_Pin();
    
      flags_rdy = OSFlagPendGetFlagsRdy(&err);
      if(flags_rdy != SPORT4A_INTERRUPT)
      {
         ts++;
      }
    
      if(OS_ERR_NONE == err)
      {
         frame_process_count++;
      }
      else
      {
         /* TODO: To be removed, Invalid OSFlagPend */
         OSFlagPendError_Count++;
      }
    }

    In theory it should never be true, but it is and the code stops on the dummy ‘ts++;’ line, ‘flags_rdy’ is equal to 0 and value is also 0.

    I have plotted the Post and Pend calls, the blue lines toggles on the IRQ before Posting the flag, and the Yellow, toggles when it stops Pending the flag, I have zoomed on the edge of then the task becoming unresponsibe, and can see that even tho, the flag gets Posted Once, the Task returns from Pending 4 times:

    Scope_capture

    So the OSFlagPend function is returning 3 extra times and returning a 0x0000 flag, instead of the expected 0x0001, what could be making us return from the Pend function?

    #27348

    Farukh Chaudhry
    Participant

    Hello Dario,

    When you mentioned “The pend call returns 0x0001, when it returns”, this code means “RTOS_ERR_FAIL” for “Generic failure for operation”. The post returns “RTOS_ERR_NONE”.

    #27349

    Dario Ivan vazquez
    Participant

    Hello

    I meant, the function ‘OSFlagPend’ will put the task on hold, untill the flag gets posted right? when the flag gets posted the RETURN value from ‘OSFlagPend’ will be the flags activated, so it should be 0x0001, but when the failure appears it is 0x0000, meaning that no flag is activated so why the ‘OSFlagPend’ function is returning?

    The error code returnin is NONE.

    #27350

    Farukh Chaudhry
    Participant

    Hello Dario,

    You are correct, the task will be waiting (pending) until the associated flag is set and will run when the flags are set by the post call.

    Just to clarify, OSFlagPend will return an error value regardless of the flag status if the call to OSFlagPend is incorrect. If your always getting a return value of “NONE”, then call to OSFlagPend is correct. Instead of looking at the internals of the flag attributes, can you use the function OSFlagPendGetFlagsRdy to see what flags are being set.

    As mentioned, maybe perform a simple test without the use of arrays for the flags.

    #27359

    Dario Ivan vazquez
    Participant

    Hello Farukh,

    I added the OSFlagPendGetFlagsRdy to the task and got the same value, 0x0000, it should be 0x0001 due to the flag, the error is still NONE.

    
    while (1)
    {
      CPU_TS   ts;
      OS_FLAGS value;
    
      /* uC/OS-III: Waiting for SPORT4A_INTERRUPT event */
      value = OSFlagPend(&os_flag_grp_list[ShCore_Process_Task_Index],
                         SPORT4A_INTERRUPT,
                         (OS_TICK)WAIT_FOREVER_FOR_FLAG,
                         (OS_OPT)(OS_OPT_PEND_FLAG_SET_ANY + OS_OPT_PEND_FLAG_CONSUME),
                         &ts,
                         &err);
      
      toggle_FlagPend_Pin();
    
      flags_rdy = OSFlagPendGetFlagsRdy(&err);
      if(flags_rdy != SPORT4A_INTERRUPT)
      {
         ts++;
      }
    
      if(OS_ERR_NONE == err)
      {
         frame_process_count++;
      }
      else
      {
         /* TODO: To be removed, Invalid OSFlagPend */
         OSFlagPendError_Count++;
      }
    }
    

    Here the error seems that “SOMETHING” is making the task run without the Flag being posted, what could it be, is there an internal mechanism I am missing? or is the UCOS implemented incorrectly on this chip?

    Thank you
    Regards

    #27361

    Farukh Chaudhry
    Participant

    Hello Dario,

    From the Micrium documentation, a 0 returned from OSFlagPend means no flags are ready. Since you are not getting an error, OSFlagPend will run if the timeout is not 0. Is WAIT_FOREVER_FOR_FLAG defined as 0?

    What micrcontroller are you using?

Viewing 11 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.

View the complete site map

x
Loading...