1.在最近的嵌入式工作中很多都是学习FreeRTOS系统,由于只是会对RTOS的接口进行调用,但是很多时候都是知其然而不知其所以然,所以现在对API进行总结。
2.首先还是从main函数入口,main()函数创建任务,然后启动调度器
大概的格式如下:
int main( void )
{
if(xTaskCreate(test1, (const char*)"test1", 1024, NULL,5, NULL)!=pdPASS){
Printf(“create task error\n”);
}
/* 启动调度器,任务开始执行 */
vTaskStartScheduler();
for( ;; );
}
3.在 FreeRTOS 中,多线程被称为多任务,在这里任务可以看得和线程相同。(其实并不相同)
首先创建任务的接口:
portBASE_TYPE xTaskCreate( pdTASK_CODE pvTaskCode,
const signed portCHAR * const pcName,
unsigned portSHORT usStackDepth,
void *pvParameters,
unsigned portBASE_TYPE uxPriority,
xTaskHandle *pxCreatedTask );
pvTaskCode:任务的入口,是个永不退出的函数。 一般格式:void test( void *pvParameters );
pcName:任务的名字(一般无用)
usStackDepth:任务的大小,栈的深度
pvParameters:传入任务的参数
uxPriority:此任务运行在优先级,优先级的大小可以控制的,最大值在FreeRTOSConfig.h 中的configMAX_PRIORITIES-1,但是要注意优先级数越大,那么内核的开销越大
pxCreatedTask :句柄,用于删除等功能的调用
如:
if(xTaskCreate(test1, (const char*)"test1", 1024, NULL,5, NULL)!=pdPASS){
Printf(“create task error\n”);
}
调用的函数demo如下:
void test( void *pvParameters )
{
for(;;)
{
//用户的逻辑在这里 这个是永不返回的函数
}
vTaskDelete( NULL );
}
上面是对两个接口的简单介绍,下面是注意的事项。
(1):每个任务的执行必要要有延时,如果没有延时,那么会出现单个任务一直占用CPU的现象。比如说下面的代码逻辑就会出现一直在运行任务一的现象;
void test1(void *param)
{
for(;;)
{
printf("1\n");
}
//正常是不会到这里的
vTaskDelete( NULL );
}
void test2(void *param)
{
for(;;)
{
printf("2\n");
vTaskDelay(100);
}
vTaskDelete( NULL );
}
int main{
xTaskCreate(test1, (const char*)"test1", 1024, NULL,5, NULL);
xTaskCreate(test2, (const char*)"test2", 1024, NULL,5, NULL)
vTaskStartScheduler();
for( ;; );
}
(2)由于多任务是使用的时间片轮转的方式调用,如果优先级高的任务占用的时间片过多,那么低优先级的任务会出现饿死状态。
void test1(void *param)
{
for(;;)
{
printf("1\n");
}
//正常是不会到这里的
vTaskDelete( NULL );
}
void test2(void *param)
{
for(;;)
{
printf("2\n");
}
vTaskDelete( NULL );
}
int main{
xTaskCreate(test1, (const char*)"test1", 1024, NULL,5, NULL);
xTaskCreate(test2, (const char*)"test2", 1024, NULL,4, NULL)
vTaskStartScheduler();
for( ;; );
}