【瑞萨 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)、第一步:创建工程
修改时钟
(2)、第二步:LED配置
(3)、第三步:FreeRTOS配置
FreeRTOS公共部分配置
LED线程配置
(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); } }
复制代码/* 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
复制代码