(5)基于FSP的FreeRTOS移植
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)第四部:任务入口函数编写
/* 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 */
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;
StaticSemaphore_t g_fsp_common_initialized_semaphore_memory;
void g_hal_init(void);
/** Weak reference for tx_err_callback */
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;
}
(6)第六步:观察结果
END
点击阅读原文,免费申请