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.

TMS570LC4357: portYIELD_WITHIN_API behavior

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN
I am using the TMS570LC4357 with FreeRTOS, and am finding some interesting behavior when attempting to take a system software interrupt using the SSIR1 register. I've found that program execution may continue several instructions after the writing of the SSIR1 key. I am using the HALCoGen port macro portYIELD_WITHIN_API, which expands to:

#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY;  asm( " DSB " ); asm( " ISB " ); }
I have found that the problem goes away (the interrupt is taken) if two additional DSB or ISB instructions are added, i.e.
#define portYIELD_WITHIN_API() { portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY;  asm( " DSB " ); asm( " ISB " ); asm("ISB"); asm("ISB"); }
Or even just some NOP instructions:
#define portYIELD_WITHIN_API() { \
  portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY;  \
  for (uint32_t i = 0; i < 4; ++i) { asm volatile("NOP"); } \
  asm( " DSB " ); \
  asm( " ISB " ); \
}
So it seems that this is a subtle timing related thing. Are there any kind of latency requirements related to the setting of this register to trigger a system software interrupt? This happens even with the
vPortYeildWithinAPI interrupt at very high priority (mapped to channel 3 in the VIM, just behind vPortPreemptiveTick), and is not being called from ISR context.
This is especially important when using FreeRTOS event groups, because when waiting on an event FreeRTOS places an item on the event list, makes a call to portYIELD_WITHIN_API, and then retrieves an item from the event list. If the task yields properly, the item retrieved from the list is the correctly waited on item with its proper control bits set. If portYIELD_WITHIN_API does not take the interrupt immediately and continues with program execution as described, the item fetched from the list is the item that was just placed onto the list, meaning that a call to wait on an event group does not wait at all
  • Hi Alex,

    Can you please have a look at below thread which might be useful in this context.

    (+) RM48L952ZWT FreeRtos issue - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    --
    Thanks & regards,
    Jagadish.

  • Thank you for your reply. It seems like the the issue in that thread was a privilege issue that was resulting in a prefetch entry. I have verified with a debugger that my code is calling the MPU_xEventGroupWaitBits version of the function, which handles raising/resetting privilege. I tested adding an assertion to the portYIELD_WITHIN_API macro to verify that it is being called in privileged context:

    #define portYIELD_WITHIN_API() { \
      if (!portIS_PRIVILEGED()) asm("bkpt");\
      portSYS_SSIR1_REG = portSYS_SSIR1_SSKEY;  \
      asm( " DSB " ); \
      asm( " ISB " ); \
    }
    And I do not hit the bkpt. From my reading of the datasheet, it does not look like the SSIR1 register needs to be written from privileged context anyways, so I do not think that is what's going on. 
    As a further debugging exercise, I removed all threads except for the "waiter" thread, and the FreeRTOS idle and timer threads, and I am still seeing the behavior where portYIELD_WITHIN_API finishes execution and the program proceeds for a handful of instructions
  • Hi Alex,

    My sincere apologies for the delay in my reply:

    Is it possible for you to share any simplest project for this issue? So that i can reproduce this issue at my end and can verify the behavior?

    --
    Thanks & regards,
    Jagadish.