完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、队列
1.创建三个任务一个队列: ``` /*声明一个类型为xQueueHandle的变量,其用于保存队列句柄,以便三个任务都可以引用此队列*/ xQueueHandle xQueue; static void AppTaskCreate (void) { /*创建的队列用于保存最多5个值,每个数据单元都有足够的空间来存储一个long型变量*/ xQueue=xQueueCreate(5,sizeof(long)); if(xQueue != NULL) { /*创建连个写队列任务实例,任务入口参数用于传递发送到队列的值。所以一个实例 不停的发送100,而另一个任务实例不停的往队列发送200.两个任务的优先级都设为1.*/ xTaskCreate(vSenderTask,"Sender1",1000,(void*)100,1,NULL); xTaskCreate(vSenderTask,"Sender2",1000,(void*)200,1,NULL); /*创建一个读队列任务实例。其优先级设为2,高于写任务优先级*/ xTaskCreate(vReceiverTask,"Receiver",1000,NULL,2,NULL); } } ``` 2.发送任务(有两个实列): ``` static void vSenderTask(void *pvParameters) { long ValueToSend; portBASE_TYPE xStatus; /*该任务会被创建两个实例,所以写入队列的值通过任务入口参数传递; 这种方式使得每个实例使用不同的值。队列创建时指定其数据单元为long型, 所以把入口参数强制转换为数据单元要求的类型*/ ValueToSend = (long) pvParameters; for(;;) { /*往队列发送数据 第一个参数是要写入的队列。队列在调度器启动之前就被创建了,所以先于此任务执行; 第二个参数是被发送数据的地址,本例中即变量ValueToSend的地址; 第三个参数是阻塞超时时间-当队列满时,任务转入阻塞状态以等待队列空间有效。本例 中没有设定超时时间,因为此独列绝不会保持超过一个数据单元的的机会(因为读数据的 任务优先级更高),所以也绝不会满,这正是我们要测试的特性*/ xStatus = xQueueSendToBack(xQueue,&ValueToSend,0); if(xStatus != pdPASS) { /*发送操作由于队列满而无法完成-这是不可能发生的,本例中队列不可能满*/ printf("Could not send to the queue.rn"); } /*允许其它发送任务执行。taskYIELD()通知调度器现在就切换到其它任务,而不必等到 本任务的时间片耗尽,这个非常有必要否则无法立即转而执行实例2*/ taskYIELD(); } } ``` 3.接收队列数据任务: ``` static void vReceiverTask(void *pvParameters) { /*声明变量,用于保存从队列中接收的值*/ long ReceivedValue; portBASE_TYPE xStatus; const portTickType xTicksToWait = 100/portTICK_RATE_MS; for(;;) { /*此调用会发现队列一直为空,因为本任务将立即删除刚写入的数据单元(首先因为 任务优先级高,第一次会发现队列为空,因为写任务优先级低,而当写任务写入了数 据后又被该任务立即读取了,也就是删除了,所以永远为空)*/ if(uxQueueMessagesWaiting(xQueue)!=0) { printf("Queue should have been emptyrn"); } /*往队列接收数据 第一个参数是要被读取的队列。队列在调度器启动之前就被创建了,所于优先于此任务 执行; 第二个参数是保存接收到数据的缓冲区地址。此变量类型与队列数据单元类型相同, 所以有足够的大小来存储接收到的数据; 第三个参数是阻塞超时时间-当队列为空时,任务转入阻塞状态以等待队列数据有效。 本例中常量portTICK_RATE_MS用来将100ms绝对时间转换为系统心跳为单位的时间值*/ xStatus = xQueueSendToBack(xQueue,&ReceivedValue,xTicksToWait); if(xStatus == pdPASS) { /*成功读出数据,打印出来*/ printf("Received= %ldrn",ReceivedValue); } else { /*等待100ms也没有收到任何数据 必然存在错误,因为发送任务在不停的往队列中写入数据*/ printf("Could not receive from the queue.rn"); } } } 4.串口截图: 按理应该交叉打印100和200的 这个是为什么呢? 5.分析: 首先执行读取任务,读取任务进入100ms阻塞,写入任务实例1得以运行,当任务1写入数据100后,读取任务 立刻返回读取,数据被删除了,读取任务重新进入阻塞状态,程序返回到taskYIELD()立即切换到实例2, 写入数据200,立刻又被读取任务读取,数据被删除,循环往复,所以串口应该交叉打印100和200. |
|
相关推荐
1个回答
|
|
|
|
只有小组成员才能发言,加入小组>>
771 浏览 0 评论
1148 浏览 1 评论
2527 浏览 5 评论
2858 浏览 9 评论
移植了freeRTOS到STMf103之后显示没有定义的原因?
2709 浏览 6 评论
keil5中manage run-time environment怎么是灰色,不可以操作吗?
1060浏览 3评论
189浏览 2评论
453浏览 2评论
365浏览 2评论
M0518 PWM的电压输出只有2V左右,没有3.3V是怎么回事?
452浏览 1评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 11:09 , Processed in 1.106120 second(s), Total 78, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号