Hello,
I am porting a legacy code to FreeRTOS (version 10.2.1 with CMSIS-RTOS version 2.0). I am using STM32H753BIT6 revision V microcontroller.
Concern 1:
I need help with finding FreeRTOS equivalents for RTXC (RTOS) APIs KS_defslice() and KS_defres().
As per RTXC document:
-
The KS_defslice kernel service defines the amount of time the specified task is permitted to run before it is forced to yield in a time-sliced scheduling situation.
-
The KS_defres kernel service defines the priority inversion attribute of the specified resource. This attribute determines if an attempt to lock a resource can result in a priority inversion and if RTXC is to handle the inversion. When enabled by ON as the condition, the attribute will cause RTXC to check for a priority inversion if an attempt to lock the resource fails. When the attribute is disabled, no such checking.
Concern 2:
After I ported three tasks and some timers from RTXC (RTOS) to FreeRTOS (with Fixed Priority Preemptive scheduling), I am observing that the lower priority task starts to execute even when the higher priority task was not blocked. I am not sure of the reason for this.
I had expected /wanted that task T_TaskEventHandler() (being the highest priority task which being *osPriorityNormal2 out of the three tasks) would have executed until the below line gets executed:
Event = xEventGroupWaitBits(H_EvtGrp_Event, dWaitForAnyBit, pdTRUE, pdFALSE, portMAX_DELAY);
I have added my test code to project present in folder FreeRTOS\Demo\Win32-MSVC . Once the project starts to execute as expected I will merge the working code to my STM32H753 project.
Below is the variable declaration that I use:
osThreadId TaskEventHandler_ThreadId, CAN_ThreadId, GatewayMain_ThreadId;
Below is the initialization that I use inside main()
osThreadAttr_t EventTaskAttributes = {
.name = "EVENTHANDLERTASK",
.priority = (osPriority_t)osPriorityNormal2,
.stack_size = configMINIMAL_STACK_SIZE * sizeof(StackType_t) // The osThreadNew() assumes the base unit as byte, where as xTaskCreate() uses sizeof(StackType_t) as the base unit.
};
TaskEventHandler_ThreadId = osThreadNew(T_TaskEventHandler, NULL, &EventTaskAttributes);
osThreadAttr_t CAN_Attributes = {
.name = "CANTASK",
.priority = (osPriority_t)osPriorityNormal1,
.stack_size = configMINIMAL_STACK_SIZE * sizeof(StackType_t) // The osThreadNew() assumes the base unit as byte, where as xTaskCreate() uses sizeof(StackType_t) as the base unit.
};
CAN_ThreadId = osThreadNew(T_CAN, NULL, &CAN_Attributes);
osThreadAttr_t GatewayAttributes = {
.name = "GATEWAYMAINTASK",
.priority = (osPriority_t)osPriorityNormal,
.stack_size = configMINIMAL_STACK_SIZE * sizeof(StackType_t) // The osThreadNew() assumes the base unit as byte, where as xTaskCreate() uses sizeof(StackType_t) as the base unit.
};
GatewayMain_ThreadId= osThreadNew(T_GatewayMain, NULL, &GatewayAttributes);
vTaskStartScheduler();
for (;;);
I assume using code similar to below in all three task functions will be an overkill:
EventBits_t uxReturn = xEventGroupSync(H_EvtGrp_Sync_3_Tasks, dSyncEventHandleTask, dAllThreeTasksSync, portMAX_DELAY);
The CAN Task and Gateway Main task have timer related implementation as shown below (followed by a while(1) { ...<code here>... }
):
TimerHandle_t H_RC_LED_OneShot = xTimerCreate("RC_LEDONESHOTEVENT", pdMS_TO_TICKS(dRC_LED_OnPeriod), pdFALSE, (void*)RC_LEDONESHOTEVENT, rvRC_LED_OneShotHandler_Signal);
xTimerStart(H_RC_LED_OneShot, 0);
which is replacement for:
`L_RC_LED_OneShot = KS_start_timer(NULL, dRC_LED_OnPeriod, 0, RC_LEDONESHOTEVENT);`
and
EventBits_t uxBits = xEventGroupClearBits(H_EvtGrp_Event, 1 << UPDATEDANV);
if (uxBits & (1 << UPDATEDANV))
{
assert_failed((uint8_t *)__FILE__, __LINE__);
}
which is replacement for:
KS_pend(UPDATEDANV);
Please help.
Thanks and regards,
Rajeev