Hi everyone
We use the RL-Arm RTX V4.20 with Cortex-M3 (STM32F101VC).
In my software I use a Mutex to make the access to a shared Buffer thread safe. This buffer is accessed from two different Tasks. The software is working well sometimes a day, sometimes only 1 hour. After this the LowPrio Task is in Wait for Mutex state forever, the High prio task is running well.
I checked the source code of the RL-Arm rt_Mutex.c and found no thread safety functionality for the mutex functions. My question is now, why there is no task_lock while accessing the Mutex Data? If a task switch is generated while execution is in rt_mut_wait or rt_mut_release, the Mutex Data could be corrupt. Is there an implementation mistake on my side?
Example Code: Tick every 1ms, Robinout every 5ms.
// High prio task __task void task1 (void) { for(;;) { os_evt_wait_or(0xffff, 0xffff) os_mut_wait( Mutex, 0xffff); // using the buffer os_mut_release(Mutex); } } // Low prio task __task void task2 (void) { for(;;) { os_mut_wait( Mutex, 0xffff); // using the buffer os_mut_release(Mutex); // doing some other stuff os_dly_wait (100); } } // Timer Interrupt generated by a communication protocol void TIM1_UP_IRQHandler( void ) { //... isr_evt_set( flag, TASK1_ID ); //... }
On the Cortex-M3, the OS function calls are called through the SVC mechanism. The processor is running at interrupt priority level 14, which will block out any "higher" level interrupts from running (i.e. PENDSV and SYSTICK) all other interrupts will run fine. All tasks switches take place through the SYSTICK interrupt therefore no task switching can take place until the SVC is complete. (you can take a look at RTL.h and see how the function calls are made for the Cortex-M3)
You are right, I use the priority grouping as follows:
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Enable the USART1 Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable the TIM1 UP Interrupt */ NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure);
Docu: The lowest two pre-emption priorities are reserved for RTX kernel, all remaining pre-emption priorities are available to use in your application. I will put now the NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2
Could this solve my bug with the hanging task2?
What I don't understand is, what does lock the task switch while executing the mutex functions? I know the RTX handles this issue. But how?
Are you using interrupt priority grouping?
The priority grouping is not supported in MDK4.20 yet, but will be in the next MDK release.
www.keil.com/.../rlarm_ar_hints_cortex.htm
View all questions in Keil forum