This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

A nasty feature of RTX

Hello,

Why does not RTX implement a reference counter for its "tsk_lock"/"tsk_unlock" mechanism?
The way things are implemented at the moment, any task that calls "tsk_unlock" enables the scheduler. But this can cause problems in nested calls; And, can cause a RTX kernel corruption if some code calls this from interrupt mode while a task is executing a RTX API (which assumes scheduler is disabled). There is no indication in the user manual that the kernel can be damaged if the scheduler is enabled from interrupt mode (NOTE: enabling the scheduler from interrupt mode only sets an interrupt line which is inherently safe!).
FreeRTOS has this feature (and much more). Why not RTX?

I know who I vote for...

Parents
  • Actually, the source of the problem was this code:

    #define SERVICE_WATCHDOG   tsk_lock() ;\ 
                               g_application_alive_signals |= ( (int32u)1<<(os_tsk_self() - g_first_task_id) ) ;\ 
                               tsk_unlock() ;\ 
    

    Which allows tasks to set their "alive bit" regularly without servicing the watchdog directly (which happens in one place only if all alive bits are set). Originally, it used a mutex, but "tsk_lock" and "tsk_unlock" are much cheaper, computation wise. However, given the nature of the code, what should have been done is disabling of _all_ interrupts for this short period of time, not just the scheduler (thus, a mutex was insufficient as well).
    Then, this code was introduced into a function that was called both from user mode and interrupt mode (LPC2478) which was called during a long data transfer via the SSP bus. That was enough to cause a arbitrary, random data corruption resulting in entry into abort mode or hanging in a loop in a RTX API.

Reply
  • Actually, the source of the problem was this code:

    #define SERVICE_WATCHDOG   tsk_lock() ;\ 
                               g_application_alive_signals |= ( (int32u)1<<(os_tsk_self() - g_first_task_id) ) ;\ 
                               tsk_unlock() ;\ 
    

    Which allows tasks to set their "alive bit" regularly without servicing the watchdog directly (which happens in one place only if all alive bits are set). Originally, it used a mutex, but "tsk_lock" and "tsk_unlock" are much cheaper, computation wise. However, given the nature of the code, what should have been done is disabling of _all_ interrupts for this short period of time, not just the scheduler (thus, a mutex was insufficient as well).
    Then, this code was introduced into a function that was called both from user mode and interrupt mode (LPC2478) which was called during a long data transfer via the SSP bus. That was enough to cause a arbitrary, random data corruption resulting in entry into abort mode or hanging in a loop in a RTX API.

Children