uCOS-II(2)

2020-05-23 14:25

实验三、消息队列

本节我们主要介绍的是uC/OS-II的通信方式--消息队列 1、队列介绍

为了使用uC/OS-II的消息队列,需要将OS_CFG.H中的OS_Q_EN及其下面的函数使能宏置位,并设置OS_MAX_QS为应用程序中最多可以设置的消息队列个数。消息队列使用的是先入先出的方式进行异步通信,即对先来的事件先处理,uC/OS-II也可以使用OSQPostFront将消息加入到队列头来实现后入先出。下图是任务、中断服务子程序和消息队列之间的关系。

2、队列操作

uC/OS-II提供了一系列函数对队列进行创建、接收和发送等。 1)创建队列OSQCreate()

OS_EVENT *OSQCreate(void **start, INT16U size)

start 二级指针,类型为void 数组的起始地址

size 队列长度

返回值 NULL表示没有空闲的事件控制块 OS_EVENT类型的指针指向生成的队列

2)将数据发送到队列尾OSQPost()与头OSQPostFront()

INT8U OSQPost (OS_EVENT *pevent, void *msg) INT8U OSQPostFront (OS_EVENT *pevent, void*msg) pevent 创建队列时返回的指针 msg 发送数据的指针。 返回值 有三个可能的返回值:

1.OS_NO_ERR 数据被成功发送到队列中。 2.OS_ERR_EVENT_TYPE 事件类型错误 3.OS_Q_FULL 队列满

3)从消息队列中获取一个消息OSQPend()等待和OSQAccept()立即返回 void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) void *OSQAccept (OS_EVENT *pevent)

pevent 创建队列时返回的指针 timeout 阻塞超时时间 err 错误类型指针 返回值 有两个可能的返回值: 1.NULL 没有获取到数据 2.数据指针

4)清空消息队列OSQFlush()

INT8U OSQFlush (OS_EVENT *pevent)

pevent 创建队列时返回的指针 返回值 有两个可能的返回值:

1.OS_NO_ERR 清空成功 2.OS_ERR_EVENT_TYPE 事件类型错误 5)查询队列的当前状态OSQQuery()

INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *pdata) pevent 创建队列时返回的指针 pdata 消息队列的信息 返回值 有两个可能的返回值:

1.OS_NO_ERR 清空成功 2.OS_ERR_EVENT_TYPE 事件类型错误 3、实验分析

实验创建两个任务,并创建一个长度为10的队列,一个任务用于每500ms向队列发送字符串,另一个任务用于每隔1s等待接收字符串。接收到字符串后将其打印出来,由于发送间隔时间比接收间隔时间短,因此实验到后来会出现队列满的现象。其源代码如下: OS_EVENT *CommQ;

void *CommMsg[OS_MAX_QS]; //OS_MAX_QS(在os_cfg.h里定义)个指针的数组 int main (void) {

INT8U err;

SysTick_Configuration(); //系统定时器初始化

USART_Configuration(); //串口初始化

LED_Configuration();

OSInit(); //usos ii初始化

CommQ= OSQCreate(&CommMsg[0], 10); //建立消息队列 长度为10 OSQFlush(CommQ);

AppTaskCreate();//创建任务 OSStart(); //开始任务调度

}

static void AppTaskCreate(void) {

INT8U err;

OSTaskCreateExt(AppTask1,(void*)0,(OS_STK )&AppTask1Stk[APP_TASK1_STK_SIZE-1],APP_TASK1_PRIO,APP_TASK1_PRIO,(OS_STK)&AppTask1Stk[0],APP_TASK1_STK_SIZE,(void )0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); //创建任务1

OSTaskNameSet(APP_TASK1_PRIO, \&err);

OSTaskCreateExt(AppTask2,(void*)0,(OS_STK )&AppTask2Stk[APP_TASK2_STK_SIZE-1],APP_TASK2_PRIO,APP_TASK2_PRIO,(OS_STK )&AppTask2Stk[0],APP_TASK2_STK_SIZE,(void*)0,OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); //创建任务2

OSTaskNameSet(APP_TASK2_PRIO, \&err); }

//任务1

static void AppTask1 (void *p_arg) {

INT8U err;

void *msg; while(1) {

msg= OSQPend(CommQ, 100, &err);

if (err == OS_NO_ERR){//读取成功,打印消息

printf(\读取队列成功:%s\\r\\n\*)msg); } else{

printf(\读取失败\\r\\n\ //读取失败 }

OSTimeDlyHMSM(0,0,0,500); LED1(1);

OSTimeDlyHMSM(0,0,0,500); LED1(0); } }

INT8U *CommRxBuf=\//任务2

static void AppTask2 (void *p_arg)

{

INT8U err; while(1) {

err= OSQPost(CommQ, (void *)&CommRxBuf[0]); if (err == OS_NO_ERR){

printf(\消息加入队列中 \\r\\n\ //将消息放入消息队列

} else{

printf(\队列已满 \\r\\n\ //消息队列已满

}

OSTimeDlyHMSM(0,0,0,500); } }

由于写入消息队列的速度快于读出队列的速度,因此到实验做了一段时间后会出现消息队列满的现象,等待消息被读出后,才能继续往队列里面写数据,通过串口打印的现象如下:

实验四、信号量

本节我们主要介绍的是uC/OS-II的信号量 1、信号量介绍

信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件,外部设备)来实现进程间通信,它本身只是一种外部资源的标识。信号量在此过程中负责数据操作的互斥、同步等功能。当请求一个使用信号量来表示的资源时,进程需要先读取信号量的值来判断资源是否可用。如果大于0则资源可以请求,等于0则无资源可用,进程会进入睡眠状态直至资源可用。

μC/OS-II中的信号量由两部分组成:一个是信号量的计数值,它是一个16位的无符号整数(0到65,535之间);另一个是由等待该信号量的任务组成的等待任务表。用户要在 OS_CFG.H中将 OS_SEM_EN 开关量常数置成 1,这样μC/OS-II才能支持信号量。在使用一个信号量之前, 首先要建立该信号量, 也即调用 OSSemCreate()函数,对信号量的初始计数值赋值。该初始值为0到 65,535之间的一个数。如果信号量是用来表示一个或者多个事件的发生, 那么该信号量的初始值应设为0。如果信号量是用于对共享资源的访问,那么该信号量的初始值应设为1(例如,把它当作二值信号量使用)。最后,如果该信号量是用来表示允许任务访问n 个相同的资源,那么该初始值显然应该是n,并把该信号量作为一个可计数的信号量使用。如下图是任务、中断服务子程序和信号量之间的关系。

2、信号量操作

μC/OS-II提供了一系列函数对信号量进行创建、获取和给出等。 1)创建信号量OSSemCreate()

OS_EVENT *OSSemCreate (INT16U cnt)

cnt 信号量的初始值 返回值 NULL创建失败 否则返回事件控制块指针

2)信号量获取OSSemPend( )等待和OSSemAccept()立即返回

void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) INT16U OSSemAccept (OS_EVENT *pevent)

pevent 创建队列时返回的指针 Timeout 阻塞超时时间。 err 错误类型 返回值 信号量计数值减一 3)发出信号量OSSemPost()

INT8U OSSemPost (OS_EVENT *pevent)

pevent 创建队列时返回的指针 返回值 有两个可能的返回值: 1.OS_NO_ERR 清空成功 2.OS_ERR_EVENT_TYPE 事件类型错误 3.OS_SEM_OVF 溢出 3)查询一个信号量的当前状态OSSemQuery()


uCOS-II(2).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:当代中国政府与政治

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: