【瑞萨 RA6M4】开发环境搭建(1)
【瑞萨 RA6M4】快速傅里叶变换(FFT)测试(2)
【瑞萨 RA6M4】定时器实现SPWM(3)
【瑞萨 RA6M4】基于RS232 接口的 Modbus-RTU 从机实现 (4)
【瑞萨 RA6M4】基于FSP的FreeRTOS移植 (5)


1、FreeRTOS
FreeRTOS是一个迷你的实时操作系统内核。作为一个轻量级的操作系统,功能包括:任务管理、时间管理、信号量、消息队列、内存管理、记录功能、软件定时器、协程等,可基本满足较小系统的需要。由于RTOS需占用一定的系统资源(尤其是RAM资源),只有μC/OS-II、embOS、salvo、FreeRTOS等少数实时操作系统能在小RAM单片机上运行。相对μC/OS-II、embOS等商业操作系统,FreeRTOS操作系统是完全免费的操作系统,具有源码公开、可移植、可裁减、调度策略灵活的特点,可以方便地移植到各种单片机上运行。
2、移植
(1)、第一步:创建工程
修改时钟
image.png
(2)、第二步:LED配置
image.png
(3)、第三步:FreeRTOS配置
FreeRTOS公共部分配置
image.png

LED线程配置
image.png
(4)、第四部:任务入口函数编写
#include "led_task.h"
  • #include "led.h"
  •                 /* led entry function */
  •                 /* pvParameters contains TaskHandle_t */
  •                 void led_task_entry(void * pvParameters)
  •                 {
  •                     FSP_PARAMETER_NOT_USED(pvParameters);
  •                     /* TODO: add your own code here */
  •                     while(1)
  •                     {
  •                                                 led_on();
  •                         vTaskDelay(750);
  •                                                 led_off();
  •                                                 vTaskDelay(750);
  •                     }
  •                 }
  • 复制代码
    (5)、第五步:主函数处理
    /* generated main source file - do not edit */
  • #include "bsp_api.h"
  •                 #include "FreeRTOS.h"
  •                 #include "task.h"
  •                 #include "semphr.h"
  •                 extern void prt_task_create(void);
  •                 extern TaskHandle_t prt_task;
  •                                 extern void led_task_create(void);
  •                 extern TaskHandle_t led_task;
  •                 uint32_t g_fsp_common_thread_count;
  •                 bool g_fsp_common_initialized;
  •                 SemaphoreHandle_t g_fsp_common_initialized_semaphore;
  •                 #if configSUPPORT_STATIC_ALLOCATION
  •                 StaticSemaphore_t g_fsp_common_initialized_semaphore_memory;
  •                 #endif
  •                 void g_hal_init(void);
  •                 /** Weak reference for tx_err_callback */
  •                 #if defined(__ICCARM__)
  •                 #define rtos_startup_err_callback_WEAK_ATTRIBUTE
  •                 #pragma weak rtos_startup_err_callback = rtos_startup_err_callback_internal
  •                 #elif defined(__GNUC__)
  •                 #define rtos_startup_err_callback_WEAK_ATTRIBUTE __attribute__ ((weak, alias("rtos_startup_err_callback_internal")))
  •                 #endif
  •                 void rtos_startup_err_callback_internal(void * p_instance, void * p_data);
  •                 void rtos_startup_err_callback(void * p_instance, void * p_data) rtos_startup_err_callback_WEAK_ATTRIBUTE;
  •                 /*********************************************************************************************************************
  •                 * @brief This is a weak example initialization error function. It should be overridden by defining a user function
  •                 * with the prototype below.
  •                 * - void rtos_startup_err_callback(void * p_instance, void * p_data)
  •                 *
  •                 * @param[in] p_instance arguments used to identify which instance caused the error and p_data Callback arguments used to identify what error caused the callback.
  •                 **********************************************************************************************************************/
  •                 void rtos_startup_err_callback_internal(void * p_instance, void * p_data);
  •                 void rtos_startup_err_callback_internal(void * p_instance, void * p_data)
  •                 {
  •                     /** Suppress compiler warning for not using parameters. */
  •                     FSP_PARAMETER_NOT_USED(p_instance);
  •                     FSP_PARAMETER_NOT_USED(p_data);
  •                     /** An error has occurred. Please check function arguments for more information. */
  •                     BSP_CFG_HANDLE_UNRECOVERABLE_ERROR(0);
  •                 }
  •                 void rtos_startup_common_init(void);
  •                 void rtos_startup_common_init(void)
  •                 {
  •                     /* First thread will take care of common initialization. */
  •                     BaseType_t err;
  •                     err = xSemaphoreTake(g_fsp_common_initialized_semaphore, portMAX_DELAY);
  •                     if (pdPASS != err)
  •                     {
  •                         /* Check err, problem occurred. */
  •                         rtos_startup_err_callback(g_fsp_common_initialized_semaphore, 0);
  •                     }
  •                     /* Only perform common initialization if this is the first thread to execute. */
  •                     if (false == g_fsp_common_initialized)
  •                     {
  •                         /* Later threads will not run this code. */
  •                         g_fsp_common_initialized = true;
  •                         /* Perform common module initialization. */
  •                         g_hal_init();
  •                         /* Now that common initialization is done, let other threads through. */
  •                         /* First decrement by 1 since 1 thread has already come through. */
  •                         g_fsp_common_thread_count--;
  •                         while (g_fsp_common_thread_count > 0)
  •                         {
  •                             err = xSemaphoreGive(g_fsp_common_initialized_semaphore);
  •                             if (pdPASS != err)
  •                             {
  •                                 /* Check err, problem occurred. */
  •                                 rtos_startup_err_callback(g_fsp_common_initialized_semaphore, 0);
  •                             }
  •                             g_fsp_common_thread_count--;
  •                         }
  •                     }
  •                 }
  •                 int main(void)
  •                 {
  •                     g_fsp_common_thread_count = 0;
  •                     g_fsp_common_initialized = false;
  •                     /* Create semaphore to make sure common init is done before threads start running. */
  •                     g_fsp_common_initialized_semaphore =
  •                     #if configSUPPORT_STATIC_ALLOCATION
  •                     xSemaphoreCreateCountingStatic(
  •                     #else
  •                     xSemaphoreCreateCounting(
  •                     #endif
  •                         256,
  •                         1
  •                         #if configSUPPORT_STATIC_ALLOCATION
  •                         , &g_fsp_common_initialized_semaphore_memory
  •                         #endif
  •                     );
  •                     if (NULL == g_fsp_common_initialized_semaphore) {
  •                         rtos_startup_err_callback(g_fsp_common_initialized_semaphore, 0);
  •                     }
  •                     /* Init RTOS tasks. */
  • //                    prt_task_create();
  • led_task_create();
  •                     /* Start the scheduler. */
  •                     vTaskStartScheduler();
  •                     return 0;
  •                 }
  •                 #if configSUPPORT_STATIC_ALLOCATION
  •                 void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer,
  •                 uint32_t *pulIdleTaskStackSize) BSP_WEAK_REFERENCE;
  •                 void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer,
  •                 uint32_t *pulTimerTaskStackSize) BSP_WEAK_REFERENCE;
  •                 /* If configSUPPORT_STATIC_ALLOCATION is set to 1, the application must provide an
  •                 * implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
  •                 * used by the Idle task. */
  •                 void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
  •                                                     StackType_t **  ppxIdleTaskStackBuffer,
  •                                                     uint32_t * pulIdleTaskStackSize )
  •                 {
  •                     /* If the buffers to be provided to the Idle task are declared inside this
  •                     * function then they must be declared static - otherwise they will be allocated on
  •                     * the stack and so not exists after this function exits. */
  •                     static StaticTask_t xIdleTaskTCB;
  •                     static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
  •                     /* Pass out a pointer to the StaticTask_t structure in which the Idle
  •                     * task's state will be stored. */
  •                     *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
  •                     /* Pass out the array that will be used as the Idle task's stack. */
  •                     *ppxIdleTaskStackBuffer = uxIdleTaskStack;
  •                     /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
  •                     * Note that, as the array is necessarily of type StackType_t,
  •                     * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
  •                     *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
  •                 }
  •                 /* If configSUPPORT_STATIC_ALLOCATION is set to 1, the application must provide an
  •                 * implementation of vApplicationGetTimerTaskMemory() to provide the memory that is
  •                 * used by the RTOS daemon/time task. */
  •                 void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
  •                                                      StackType_t **  ppxTimerTaskStackBuffer,
  •                                                      uint32_t *      pulTimerTaskStackSize )
  •                 {
  •                     /* If the buffers to be provided to the Timer task are declared inside this
  •                     * function then they must be declared static - otherwise they will be allocated on
  •                     * the stack and so not exists after this function exits. */
  •                     static StaticTask_t xTimerTaskTCB;
  •                     static StackType_t uxTimerTaskStack[ configMINIMAL_STACK_SIZE ];
  •                     /* Pass out a pointer to the StaticTask_t structure in which the Idle
  •                     * task's state will be stored. */
  •                     *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
  •                     /* Pass out the array that will be used as the Timer task's stack. */
  •                     *ppxTimerTaskStackBuffer = uxTimerTaskStack;
  •                     /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
  •                     * Note that, as the array is necessarily of type StackType_t,
  •                     * configMINIMAL_STACK_SIZE is specified in words, not bytes. */
  •                     *pulTimerTaskStackSize = configMINIMAL_STACK_SIZE;
  •                 }
  •                 #endif
  • 复制代码
    (6)、第六步:观察结果
    VID20230617163320 -middle-original.gif