본문 바로가기

STM32

FreeRTOS - STM32F4 포팅 정보 확인

FreeRTOS를 포팅할 때 어떤 부분들을 수정하였을지 참고해보고 싶어

STM32CubeIDE(+CMSIS-RTOS v2)에 포함되어 있는 FreeRTOS의 포팅 정보를 확인해 보았습니다.

 

공식 문서에서는 소스 코드에 있는 Demo application을 통해 프로젝트를 시작해 보라고 하여,

STM32F4의 데모를 살펴보겠습니다.

 

Supported Devices - FreeRTOS™

ST STM32F4xx ARM Cortex-M4F DemoUsing IAR EWARM development tools - FreeRTOS™

 

RTOS Configuration and Usage Details

Cortex-M4F FreeRTOS port specific configuration

`FreeRTOS/Demo/CORTEX_M4F_STM32F407ZG-SK/FreeRTOSConfig.h` 파일과

STM32CubeIDE project 소스코드 내에 있는 `Core/Inc/FreeRTOSConfig.h` 파일을 비교합니다.

 

#define configUSE_IDLE_HOOK 0

idle hook 이 0으로 설정되어 Idle Task Hook을 사용할 수 없도록 되어 있습니다.

An idle task hook is a function that is called during each cycle of the idle task.
It is common to use the idle hook function to place the microcontroller CPU into a power saving mode.

 

https://www.freertos.org/Documentation/02-Kernel/03-Supported-devices/02-Customization#configuse_idle_hook

https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/01-Tasks-and-co-routines/15-Idle-task#the-idle-task-hook

 

#define configUSE_TICK_HOOK 0

tick hook 이 0으로 설정되어 Tick Hook Function을 사용할 수 없도록 되어 있습니다.

The tick interrupt can optionally call an application defined hook (or callback) function - the tick hook.
The tick hook provides a convenient place to implement timer functionality.
vApplicationTickHook() executes from within an ISR so must be very short, not use much stack, and not call any API functions that don't end in "FromISR" or "FROM_ISR".

 

https://www.freertos.org/Documentation/02-Kernel/02-Kernel-features/12-Hook-functions#tick-hook-function

https://www.freertos.org/Documentation/02-Kernel/03-Supported-devices/02-Customization#configuse_tick_hook

 

#define configSUPPORT_STATIC_ALLOCATION          1

If 'configSUPPORT_STATIC_ALLOCATION' is set to 1 then RTOS objects can be created using RAM provided by the application writer.
If  'configSUPPORT_STATIC_ALLOCATION' is set to 0 then RTOS objects can only be created using RAM allocated from the FreeRTOS heap.
If 'configSUPPORT_STATIC_ALLOCATION' is left undefined it will default to 0.
If 'configSUPPORT_STATIC_ALLOCATION' is set to 1 then the application writer must also provide two callback functions:
`vApplicationGetIdleTaskMemory()` to provide the memory for use by the RTOS Idle task, and (if `configUSE_TIMERS`  is set to 1) 
`vApplicationGetTimerTaskMemory()` to provide memory for use by the RTOS Daemon/Timer Service task.

 

https://www.freertos.org/Documentation/02-Kernel/03-Supported-devices/02-Customization#configsupport_static_allocation


#define configSUPPORT_DYNAMIC_ALLOCATION         1

If `configSUPPORT_DYNAMIC_ALLOCATION` is set to 1 then RTOS objects can be created using RAM that is automatically allocated from the FreeRTOS heap.
If `configSUPPORT_DYNAMIC_ALLOCATION` is set to 0 then RTOS objects can only be created using RAM provided by the application writer.
If `configSUPPORT_DYNAMIC_ALLOCATION` is left undefined it will default to 1.
See the Static Vs Dynamic Memory Allocation page for more information.

 

https://www.freertos.org/Documentation/02-Kernel/03-Supported-devices/02-Customization#configsupport_dynamic_allocation

 

cmsis_os2.c에 정의된 osThreadNew()를 살펴보니 

조건에 따라 `xTaskCreateStatic()`나 `xTaskCreate()'가 호출됩니다.

if (mem == 1) {
  #if (configSUPPORT_STATIC_ALLOCATION == 1)
    hTask = xTaskCreateStatic ((TaskFunction_t)func, name, stack, argument, prio, (StackType_t  *)attr->stack_mem,
                                                                                  (StaticTask_t *)attr->cb_mem);
  #endif
}
else {
  if (mem == 0) {
    #if (configSUPPORT_DYNAMIC_ALLOCATION == 1)
      if (xTaskCreate ((TaskFunction_t)func, name, (uint16_t)stack, argument, prio, &hTask) != pdPASS) {
        hTask = NULL;
      }
    #endif
  }
}

 

Thread Management

 

#define configMAX_PRIORITIES			( 5 )
#define configMINIMAL_STACK_SIZE		( ( unsigned short ) 130 )
#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 75 * 1024 ) )
#define configMAX_TASK_NAME_LEN			( 10 )

// STM32CubeIDE
#define configMAX_PRIORITIES                     ( 56 )
#define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
#define configTOTAL_HEAP_SIZE                    ((size_t)15360)
#define configMAX_TASK_NAME_LEN                  ( 16 )

#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0

 

heap과 stack (15 * 1024)의 크기는 줄였습니다.

task name length는 늘렸습니다.

task priority를 56개로 늘렸습니다.

CMSIS-RTOS2 defines 56 different priorities (see osPriority_t) and portable CMSIS-RTOS2 implementation should implement the same number of priorities.

 

#define configUSE_PORT_OPTIMISED_TASK_SELECTION  0

CMSIS-RTOS2 requires handling of 56 different priorities (see osPriority_t) while FreeRTOS port optimised selection for Cortex core only handles 32 different priorities.

 

동일한 정의들

#define configUSE_PREEMPTION                     1
#define configCPU_CLOCK_HZ                       ( SystemCoreClock )
#define configTICK_RATE_HZ                       ((TickType_t)1000)
#define configUSE_TRACE_FACILITY                 1
#define configUSE_16_BIT_TICKS                   0
#define configUSE_MUTEXES                        1
#define configQUEUE_REGISTRY_SIZE                8
#define configUSE_RECURSIVE_MUTEXES              1
#define configUSE_COUNTING_SEMAPHORES            1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES                    0
#define configMAX_CO_ROUTINE_PRIORITIES          ( 2 )

/* Software timer definitions. */
#define configUSE_TIMERS                         1
#define configTIMER_TASK_PRIORITY                ( 2 )
#define configTIMER_QUEUE_LENGTH                 10

#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY   0xf
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5

 

#define configMINIMAL_STACK_SIZE		( ( unsigned short ) 130 )
#define configTIMER_TASK_STACK_DEPTH	( configMINIMAL_STACK_SIZE * 2 )

// STM32CubeIDE
#define configMINIMAL_STACK_SIZE                 ((uint16_t)128)
#define configTIMER_TASK_STACK_DEPTH             256

 

`configTIMER_TASK_STACK_DEPTH` 256 값도 `configMINIMAL_STACK_SIZE`의 2배로 할당한 값입니다.