FreeRTOS——使用任务参数创建任务
1. main()函数在启动调度器之前先完成两个任务的创建。如下面所示:
static void AppTaskCreate(void) { xTaskCreate(vTaskBeep,"Task Beep", 512, NULL, 1, &xHandleTaskBeep); xTaskCreate(vTaskLed1, /* 任务函数名 */ "Task Led1", /* 任务名,字符串形式,方便调试 */ 512, /* 栈大小,单位为字,即4个字节 */ NULL, /* 任务形参 */ 2, /* 优先级,数值越大,优先级越高 */ &xHandleTaskLED1); /* 任务句柄 */ }
2、从一个任务中创建另一个任务。我们可以先在 main()中创建任务 1,然后在任务 1 中创建任务2。
这样,在调度器启动之前,任务 2 还没有被创建,但是整个程序运行的输出结果还是相同的。
void vTask1( void *pvParameters ) { const char *pcTaskName = "Task 1 is running\r\n"; volatile unsigned long ul; /* 如果已经执行到本任务的代码,表明调度器已经启动。在进入死循环之前创建另一个任务。 */ xTaskCreate( vTask2, "Task 2", 1000, NULL, 1, NULL ); for( ;; ) { /* Print out the name of this task. */ vPrintString( pcTaskName ); /* Delay for a period. */ for( ul = 0; ul < mainDELAY_LOOP_COUNT; ul++ ) { /* This loop is just a very crude delay implementation. There is nothing to do in here. Later examples will replace this crude loop with a proper delay/sleep function. */ } } }
3、用唯一一个任务函数代码(vTaskFunction),
这一个任务函数代替了上例中的两个任务函数(vTask1 与 vTask2)。
void vTaskFunction(void *pvParameters) { int * pcTaskName; pcTaskName = (int *)pvParameters; while(1) { if(*pcTaskName==1) { LED1_ON; /* 阻塞延时,单位ms */ vTaskDelay( 500 ); LED1_OFF; vTaskDelay( 500 ); } else if(*pcTaskName==2) { BEEP_ON; /* 阻塞延时,单位ms */ vTaskDelay( 500 ); BEEP_OFF; vTaskDelay( 500 ); } } }
创建任务函数修改为:
static void AppTaskCreate(void) { xTaskCreate(vTaskFunction, /* 任务函数名 */ "Task 1", /* 任务名,字符串形式,方便调试 */ 512, /* 栈大小,单位为字,即4个字节 */ (void *)&pcLED, /* 任务形参 */ 1, /* 优先级,数值越大,优先级越高 */ &xHandleTaskLED1); /* 任务句柄 */ xTaskCreate(vTaskFunction,"Task 2", 512, (void *)&pcBeep, 1, &xHandleTaskBeep); }
注意任务参数处不再是NULL;
全局区增加标志定义:
static const int pcLED = 1;
static const int pcBeep = 2;
任务参数的原型:void * const pvParameters;如果我们不强制转化成void *将会报错。
官方手册源码:
字符串常量是一个特殊的东西,把字符串常量通过函数
void vTaskFunction( void *pvParameters )
从入口参数void *pvParameters传入,再强转为字符指针。
图 3 中 t1 与 t2 之间的时段就等于一个时间片。
要能够选择下一个运行的任务,调度器需要在每个时间片的结束时刻运行自己本身。一个称为心跳中断的周期性中断用于此目的。
时间片的长度通过心跳中断的频率进行设定,心跳中断频率由FreeRTOSConfig.h 中的编译时配置常量 configTICK_RATE_HZ 进行配置。
比如说,如果 configTICK_RATE_HZ 设为 100(HZ),则时间片长度为 10ms。可以将图 图 3 进行扩展,将调度器本身的执行时间在整个执行流程中体现出来。见图 4:
FreeRTOS API 函数调用中指定的时间总是以心跳中断为单位(通常的提法为心跳”ticks”)。
常量 portTICK_RATE_MS 用于将以心跳为单位的时间值转化为以毫秒为单位的时间值。
有效精度依赖于系统心跳频率。
欢迎加入作者的小圈子
扫描下方左边二维码加入QQ交流群,扫描下方右边二维码关注个人微信公众号并,获取更多隐藏干货,QQ交流群:859800032 微信公众号:Crystal软件学堂
作者:Liu_Jing bilibili视频教程地址:https://space.bilibili.com/5782182 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在转载文章页面给出原文连接。 如果你觉得文章对你有所帮助,烦请点个推荐,你的支持是我更文的动力。 文中若有错误,请您务必指出,感谢给予我建议并让我提高的你。 |