main.c
模板关于嵌入式常用的轮询系统,前后台系统,实时操作系统:
main
函数里,先进行初始化,初始化完毕进入循环且不退出。SystemCoreClock
。configCPU_CLOCK_HZ
configTICK_RATE_HZ
configUSE_16_BIT_TICK
1
TickType_t 定义的就是 16 位无符号数,用于 8 位和 16 位架构的处理器。0
TickType_t 定义的就是 32 位无符号数,用于 32 位架构的处理器。vTaskDelay()
开始,延时指定的时间结束。vTaskDelayUntil()
函数的任务,即以固定频率执行任务。/* FreeRTOS内核自带的延时函数 */
/** vTaskDelay
* @brief 相对延时。
* @param xTicksToDelay 延时周期
* @retval None.
*/
void vTaskDelay( const TickType_t xTicksToDelay );
/** vTaskDelayUntil
* @brief 绝对延时。
* @param pxPreviousWakeTime 上次唤醒的时间
* @param xTimeIncrement 以这个参数的频率执行任务 单位Ticks
* @retval None.
*/
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement );
/* 内核自带宏 配合延时函数使用*/
/**
* 传入需要延时的MS,转换为Ticks。
*/
pdMS_TO_TICKS( xTimeInMs );
/* 相对延时使用方法 */
static void LED_task( void * pvParameters )
{
(void)pvParameters;
for( ;; ) {
printf("LED_task is running.");
LED0=!LED0;
vTaskDelay(pdMS_TO_TICKS(500)); //延时500ms
}
}
/* 绝对延时使用方法 */
static void LED_task( void * pvParameters )
{
(void)pvParameters;
static portTickType xLastWakeTime;
const portTickType xFrequency = pdMS_TO_TICKS(500);
// 使用当前时间初始化变量xLastWakeTime
xLastWakeTime = xTaskGetTickCount();
for( ;; ) {
printf("LED_task is running.");
LED0=!LED0;
vTaskDelayUntil( &xLastWakeTime,xFrequency ); // 周期阻塞500ms
}
}
\0
不超过configMAX_TASK_NAME_LEN
。vTaskSuspend()
API,可以挂起这个任务,或者其他任务。vTaskResume()
API恢复这个任务。FreeRTOSConfig.h
中,通过配置configMAX_PRIORITIES
宏可以配置FreeRTOS任务的优先级范围。0
是最低优先级,configMAX_PRIORITIES-1
是最高优先级。vTaskPrioritySet()
API接口。task.h
中有定义typedef void * TaskHandle_t;
。FreeRTOSConfig.h
中的宏configUSE_PREEMPTION
1
使能抢占式调度器。0
使能合作式调度器。FreeRTOSConfig.h
中的宏configUSE_TIME_SLICING
1
使能时间片调度(默认使能)0
,IDLE不会抢占其他任务,其他任务优先级只要比IDLE高就可以抢占IDLE。FreeRTOSConfig.h
中的宏configUSE_IDLE_HOOK
配置为1
使能空闲任务的钩子函数。
FreeRTOSConfig.h
中的宏configIDLE_SHOULD_YIELD
/** xTaskCreate
* @brief Create a task dynamically.
* @param pxTaskCode task code to be executed.
* @param pcName the name of the task.
* @param usStackDepth the stack size of the task.
* @param uxPriority the priority of the task.
* @param pxCreatedTask Used to pass back a handle by which the created task
* can be referenced.
* @retval pdPASS if the task was successfully created and added to a ready
* list, otherwise an error code defined in the file projdefs.h
*/
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
const char * const pcName,
const uint16_t usStackDepth,
void * const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t * const pxCreatedTask );
/** vTaskDelete
* @brief The task being
* deleted will be removed from all ready, blocked, suspended and event lists.
* @param xTask The handle of the task.
* @retval None.
*/
void vTaskDelete( TaskHandle_t xTask );
/* 不包含中断版本 */
/* 临界区API */
taskENTER_CRITICAL();
taskEXIT_CRITICAL();
/* 任务阻塞延时 */
void vTaskDelay( const TickType_t xTicksToDelay );
void vTaskDelayUntil( TickType_t * const pxPreviousWakeTime, const TickType_t xTimeIncrement );
/* 任务优先级 */
UBaseType_t uxTaskPriorityGet( TaskHandle_t xTask );
/* 调度器相关 */
void vTaskSuspendAll( void );
BaseType_t xTaskResumeAll( void );
pxTaskCode
:即该任务的具体执行函数;pcName
:作为Debug使用;usStackDepth
:应大于任务的所有局部变量 + CPU寄存器 + 函数调用深度 + 预留;pvParameters
:这个一般不使用;uxPriority
:参考上文《2. 任务优先级设置》;pxCreatedTask
:参考下文main.c模板中设置方式;FreeRTOS 内存管理方案有5个。
malloc
和free
函数,通过暂时暂停FreeRTOS调度程序,让malloc
和free
函数具备线程保护,效率低。FreeRTOS所有通信都是基于队列的
任务通知比较特殊,不需要创建直接使用,可以模拟其他同步或通信机制,也有局限性
1.队列
queue.h
添加queue.c
。queue.h
添加queue.c
。0
和1
的信号量,只有2种状态1
或0
。FreeRTOSConfig.h
中的configUSE_16_BIT_TICKS
配置宏:
1
,则每个事件组包含8个可用事件位。0
,则每个事件组包含24个可用事件位。xTaskNotify( xTaskToNotify, ulValue, eAction )
xTaskNotifyGive()
FreeRTOSConfig.h
中将宏configUSE_TASK_NOTIFICATIONS
置为0来禁止这个功能。(默认开启)。void vTaskSuspendAll( void );
接口挂起调度器。BaseType_t xTaskResumeAll( void );
接口恢复调度器。main.c
模板使用FreeRTOS的一般步骤:
/************************************************************************************
* @file: main.c
* @author: Fang XS.
* @date: Create on 2021-05-22
***********************************************************************************/
/* Includes -----------------------------------------------------------------------*/
#include "freertos.h"
#include "task.h"
#include "printf.h"
#include "hardware.h"
/* variables ----------------------------------------------------------------------*/
static TaskHandle_t LEDTaskHandle_t = NULL ;
static TaskHandle_t DBGTaskHandle_t = NULL ;
/* Macros -------------------------------------------------------------------------*/
#define LEDTaskStackSize (512)
#define LEDTaskPriority (8)
#define DBGTaskStackSize (512)
#define DBGTaskPriority (5)
/* Exported functions -------------------------------------------------------------*/
static void LED_task(void* pvParameters);
static void DBG_task(void* pvParameters);
int main(void)
{
/* System Clock Init */
SystemInit();
/* User Hardware Init */
Hardware_Init();
/* variables Init */
BaseType_t xReturn = pdPASS;
/* Task Init */
xReturn = xTaskCreate((TaskFunction_t )DBG_task, /* 任务入口函数 */
(const char* )"DBG_Task", /* 任务名字 */
(uint16_t )DBGTaskStackSize, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )DBGTaskPriority, /* 任务的优先级 */
(TaskHandle_t* )&DBGTaskHandle_t); /* 任务控制块指针 */
// if(pdPASS == xReturn){ }
xReturn = xTaskCreate((TaskFunction_t )LED_task, /* 任务入口函数 */
(const char* )"LED_Task", /* 任务名字 */
(uint16_t )LEDTaskStackSize, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )LEDTaskPriority, /* 任务的优先级 */
(TaskHandle_t* )&LEDTaskHandle_t); /* 任务控制块指针 */
if(pdPASS == xReturn)
vTaskStartScheduler(); /* 启动任务 开启调度 */
else
return -1;
while(1){
;/* 启动任务调度器不会运行到这里 */
}
}
static void DBG_task( void * pvParameters )
{
(void)pvParameters;
for( ;; ) {
printf("DBG_task is running.");
vTaskDelay(500);
}
}
static void LED_task( void * pvParameters )
{
(void)pvParameters;
for( ;; ) {
printf("LED_task is running.");
LED0=!LED0;
vTaskDelay(500);
}
}
/*********************************** END OF FILE ***********************************/