概要
基于 FreeRTOS 的应用程序由一组独立的任务构成——每个任务都是具有独立权
限的小程序。这些独立的任务之间很可能会通过相互通信以提供有用的系统功能。
FreeRTOS 中所有的通信与同步机制都是基于队列实现的。
学习任务:
如何实现一个任务。
如何创建一个或多个任务的实例。
如何使用任务参数。
如何改变一个已创建任务的优先级。
如何删除任务。
如何实现周期性处理。
空闲任务何时运行,可以用来干什么。
队列特性:
可被多任务使用(读写),但是同时只能有一个任务操作。
读写阻塞,即满空阻塞。
函数:
创建队列:
xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength,//队列大小,可以存多少个数据
unsigned portBASE_TYPE uxItemSize//每个数据的大小
);//返回值句柄,失败为NULL
发送数据到队列:
xQueueSend()//发送数据到队列尾:
xQueueSendToBack()//发送数据到队列尾,完全等同于xQueueSend():
xQueueSendToFront()//发送到队列头。
函数参数三个函数相同:
portBASE_TYPE xQueueSendToFront( xQueueHandle xQueue,//队列句柄
const void * pvItemToQueue,//数据指针
portTickType xTicksToWait /*阻塞超时时间,单位是心跳周期,同任务管理需要用portTICK_RATE_MS转换,设置为0表示直接返回不等待,设置为portMAX_DELAY表示一直阻塞等待,直到队列有位置*/
);返回值为pdPASS为成功,其余为失败。
接受队列数据:
xQueueReceive()//接受数据,并删除队列里的数据
xQueuePeek() //接受数据,不删除队列里的数据
xQueueReceiveFromISR()//中断中代替xQueueReceive();
参数:
portBASE_TYPE xQueueSendToFront( xQueueHandle xQueue,//句柄
void * pvItemToQueue,//缓冲区指针,将队列里的数据复制出来,
portTickType xTicksToWait
/*阻塞超时时间,单位是心跳周期,同任务管理需要用portTICK_RATE_MS转换,设置为0表示直接返回不等待,设置为portMAX_DELAY表示一直阻塞等待,直到队列有位置*/;
);//返回值为pdPASS为成功,其余为失败。
查看队列有效数据个数:
unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue //句柄
);//返回有效个数。0为队列空。
注意
1、写队列任务在每次循环中都调用 taskYIELD()。 taskYIELD()通知调度器立即进行任
务切换,而不必等到当前任务的时间片耗尽。某个任务调用 taskYIELD()等效于其自愿
放弃运行态。进入准备态(就绪态)
2、一般队列会接受不同任务的数据,那么要分清楚是谁的数据就需要加密或者发送结构体,接受者再进行解析。
3、当数据过大时,最好传递数据的指针;
4、一定要保证数据有效,不会因为局部变量等问题被释放。
基于 FreeRTOS 的应用程序由一组独立的任务构成——每个任务都是具有独立权
限的小程序。这些独立的任务之间很可能会通过相互通信以提供有用的系统功能。
FreeRTOS 中所有的通信与同步机制都是基于队列实现的。
学习任务:
如何实现一个任务。
如何创建一个或多个任务的实例。
如何使用任务参数。
如何改变一个已创建任务的优先级。
如何删除任务。
如何实现周期性处理。
空闲任务何时运行,可以用来干什么。
队列特性:
可被多任务使用(读写),但是同时只能有一个任务操作。
读写阻塞,即满空阻塞。
函数:
创建队列:
xQueueHandle xQueueCreate( unsigned portBASE_TYPE uxQueueLength,//队列大小,可以存多少个数据
unsigned portBASE_TYPE uxItemSize//每个数据的大小
);//返回值句柄,失败为NULL
发送数据到队列:
xQueueSend()//发送数据到队列尾:
xQueueSendToBack()//发送数据到队列尾,完全等同于xQueueSend():
xQueueSendToFront()//发送到队列头。
函数参数三个函数相同:
portBASE_TYPE xQueueSendToFront( xQueueHandle xQueue,//队列句柄
const void * pvItemToQueue,//数据指针
portTickType xTicksToWait /*阻塞超时时间,单位是心跳周期,同任务管理需要用portTICK_RATE_MS转换,设置为0表示直接返回不等待,设置为portMAX_DELAY表示一直阻塞等待,直到队列有位置*/
);返回值为pdPASS为成功,其余为失败。
接受队列数据:
xQueueReceive()//接受数据,并删除队列里的数据
xQueuePeek() //接受数据,不删除队列里的数据
xQueueReceiveFromISR()//中断中代替xQueueReceive();
参数:
portBASE_TYPE xQueueSendToFront( xQueueHandle xQueue,//句柄
void * pvItemToQueue,//缓冲区指针,将队列里的数据复制出来,
portTickType xTicksToWait
/*阻塞超时时间,单位是心跳周期,同任务管理需要用portTICK_RATE_MS转换,设置为0表示直接返回不等待,设置为portMAX_DELAY表示一直阻塞等待,直到队列有位置*/;
);//返回值为pdPASS为成功,其余为失败。
查看队列有效数据个数:
unsigned portBASE_TYPE uxQueueMessagesWaiting( xQueueHandle xQueue //句柄
);//返回有效个数。0为队列空。
注意
1、写队列任务在每次循环中都调用 taskYIELD()。 taskYIELD()通知调度器立即进行任
务切换,而不必等到当前任务的时间片耗尽。某个任务调用 taskYIELD()等效于其自愿
放弃运行态。进入准备态(就绪态)
2、一般队列会接受不同任务的数据,那么要分清楚是谁的数据就需要加密或者发送结构体,接受者再进行解析。
3、当数据过大时,最好传递数据的指针;
4、一定要保证数据有效,不会因为局部变量等问题被释放。