基于ucos的实时温度检测
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于ucos的实时温度检测相关的知识,希望对你有一定的参考价值。
如下图所示,温度检测模块以单线方式连接了多个18B20(数字温度传感器)作为温度监测点,它将各点温度定时采集后,发送给数据传输模块,然后传输模块将这些数据整合为一帧发送到云端。
现就以上需求设计一个采用uC/OS内核的系统模型,要求如下:
1)实现定时采集,可以使用uC/OS的软件定时器,激发定时器回调,发送信号量激活温度检测任务;
2)单线挂载多个18B20,每个18B20有唯一ID值区分,采集单点数据格式为:ID+温度整数部分+温度小数部分。可以使用uC/OS的消息队列,温度检测任务每检测一点数据,以固定格式发送消息,消息会激活数据传送模块的数据传送任务。这个任务判断接收温度数据的个数,当<N(N为挂载的18B20数量)时,保存数据到缓存;当>=N时,从缓存区取出全部N组数据整合成一帧,并发送出去;
3)所有驱动函数(如:测温、发送网络等)可以使用伪代码代替;
4)发送信号量和消息皆为同一固定格式,请对OSSemPend()和OSQPend()函数进行重新封装成新的函数,留有固定且最简的接口(即传入参数);
UCOS明白解析
UCOSII 是一个可以基于 ROM 运行的、可裁减的、抢占式、实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统(RTOS)。为了提供最好的移植性能, UCOSII 最大程度上使用 ANSI C 语言进行开发,并且已经移植到近 40 多种处理器体系上,涵盖了从 8 位到 64 位各种 CPU(包括 DSP)。
UCOSII 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用 C 语言编写的。 CPU 硬件相关部分是用汇编语言编写的、总量约 200 行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的 CPU 上。用户只要有标准的 ANSI 的 C 交叉编译器,有汇编器、连接器等软件工具,就可以将 UCOSII 嵌人到开发的产品中。 UCOSII 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。 UCOSII 已经移植到了几乎所有知名的 CPU 上。UCOSII 构思巧妙。结构简洁精练,可读性强,同时又具备了实时操作系统的全部功能,虽然它只是一个内核,但非常适合初次接触嵌入式实时操作系统的友,可以说是麻雀虽小,五脏俱全。
其实,使用UCOS最重要的还是了解信号量,信号量集,邮箱,消息队列等的用法。在这里我主要以自己的理解来说明这个相关函数的用法。
1.信号量:用于从一个任务向另一个任务传递一个开关量的BOOL信号。
创建信号量指针:OS_EVENT *OSSemFlag。
创建信号量函数:OS_EVENT *OSSemCreate (INT16U cnt)。
发送信号量函数:INT8U OSSemPost(OS_EVENT *pevent)。
请求信号量函数:void OSSemPend( OS_EVENT *pevent, INT16U timeout, INT8U *err);其中需要注意的是Timeout,这个参数为0的时候表示无限等待,大于0就为表示演示多少个时钟节拍。
删除信号量好函数:OS_EVENT *OSSemDel (OS_EVENT *pevent,INT8U opt, INT8U *err)。
创建邮箱函数:OSMboxPost (OS_EVENT *pevent,void *msg)
请求邮箱函数:void *OSMboxPend (OS_EVENT *pevent, INT16U timeout,INT8U *err)其中需要注意的是Timeout,这个参数为0的时候表示无限等待,大于0就为表示演示多少个时钟节拍。
查询邮箱状态函数:OSMboxQuery(OS_EVENT *pevent,OS_MBOX_DATA *pdata) 。
UCOSII 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用 C 语言编写的。 CPU 硬件相关部分是用汇编语言编写的、总量约 200 行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的 CPU 上。用户只要有标准的 ANSI 的 C 交叉编译器,有汇编器、连接器等软件工具,就可以将 UCOSII 嵌人到开发的产品中。 UCOSII 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。 UCOSII 已经移植到了几乎所有知名的 CPU 上。UCOSII 构思巧妙。结构简洁精练,可读性强,同时又具备了实时操作系统的全部功能,虽然它只是一个内核,但非常适合初次接触嵌入式实时操作系统的友,可以说是麻雀虽小,五脏俱全。
其实,使用UCOS最重要的还是了解信号量,信号量集,邮箱,消息队列等的用法。在这里我主要以自己的理解来说明这个相关函数的用法。
1.信号量:用于从一个任务向另一个任务传递一个开关量的BOOL信号。
创建信号量指针:OS_EVENT *OSSemFlag。
创建信号量函数:OS_EVENT *OSSemCreate (INT16U cnt)。
发送信号量函数:INT8U OSSemPost(OS_EVENT *pevent)。
请求信号量函数:void OSSemPend( OS_EVENT *pevent, INT16U timeout, INT8U *err);其中需要注意的是Timeout,这个参数为0的时候表示无限等待,大于0就为表示演示多少个时钟节拍。
删除信号量好函数:OS_EVENT *OSSemDel (OS_EVENT *pevent,INT8U opt, INT8U *err)。
2.邮箱 :用于从一个任务向另一个任务传递一个字节的数据。
创建邮箱指针:OS_EVENT *OSMbox;创建邮箱函数:OSMboxPost (OS_EVENT *pevent,void *msg)
请求邮箱函数:void *OSMboxPend (OS_EVENT *pevent, INT16U timeout,INT8U *err)其中需要注意的是Timeout,这个参数为0的时候表示无限等待,大于0就为表示演示多少个时钟节拍。
查询邮箱状态函数:OSMboxQuery(OS_EVENT *pevent,OS_MBOX_DATA *pdata) 。
删除邮箱函数:OS_EVENT *OSMboxDel(OS_EVENT *pevent,INT8U opt,INT8U *err)。
3.信号量集:用于从一个任务向另一个任务传递最多32个开关量的BOOL信号集。
创建信号量集指针:OS_FLAG_GRP *OutEnableCfgFlag。
创建信号量集函数:OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags,INT8U *err )
创建信号量集函数:OS_FLAG_GRP *OSFlagCreate (OS_FLAGS flags,INT8U *err )
发送信号量集函数:OS_FLAGS OSFlagPost (OS_FLAG_GRP *pgrp, OS_FLAGS flags, INT8U opt, INT8U *err)
请求信号量集函数:OS_FLAGS OSFlagPend(OS_FLAG_GRP*pgrp, OS_FLAGS flags, INT8U wait_type, INT16Utimeout, INT8U *err)。注意:为了防止请求失效,一般使用OS_FLAGS+OS_FLAG_CONSUME的组合。
查询信号量状态函数:OS_FLAG_GRP *OSFlagQuery(OS_FLAG_GRP *pgrp,INT8U *err ),我们可以使用这个函数来不断查询这个信号量集的状态来做一些开关量的控制。
查询信号量状态函数:OS_FLAG_GRP *OSFlagQuery(OS_FLAG_GRP *pgrp,INT8U *err ),我们可以使用这个函数来不断查询这个信号量集的状态来做一些开关量的控制。
删除信号量集函数:OS_EVENT *OSFlagDel(OS_FLAG_GRP *pgrp,INT8U *err )
4.消息队列:用于从一个任务向另一个任务传递多个字节的数据。
创建消息队列指针:OS_EVENT * MainMenuUI;
创建消息队列存储数组:void * MsgGrp[16];
创建消息队列函数:OS_EVENT *OSQCreate(void**start,INT16U size)
请求消息队列函数:void*OSQPend(OS_EVENT*pevent,INT16U timeout,INT8U *err)
查询消息队列函数: INT8U OSQQuery(OS_EVENT*pevent,OS_Q_DATA *pdata).
4.消息队列:用于从一个任务向另一个任务传递多个字节的数据。
创建消息队列指针:OS_EVENT * MainMenuUI;
创建消息队列存储数组:void * MsgGrp[16];
创建消息队列函数:OS_EVENT *OSQCreate(void**start,INT16U size)
请求消息队列函数:void*OSQPend(OS_EVENT*pevent,INT16U timeout,INT8U *err)
查询消息队列函数: INT8U OSQQuery(OS_EVENT*pevent,OS_Q_DATA *pdata).
发送消息队列函数:INT8U OSQPost(OS_EVENT*pevent,void *msg)和 INT8U OSQPost(OS_EVENT*pevent,void*msg)。
清空消息队列函数: INT8U OSQFlush(OS_EVENT*pevent)。
清空消息队列函数: INT8U OSQFlush(OS_EVENT*pevent)。
删除消息队列函数:OS_EVENT *OSQDel(OS_EVENT*pevent)。
5.软件定时器:用于产生非硬件的定时器中断,可以用计时。创建软件定时器指针:OS_TMR * ADCheckTime;
创建软件定时器函数:OS_TMR *OSTmrCreateINT32U dly, INT32U period, INT8U opt, OS_TMR_CALLBACK callback,void
*callback_arg, INT8U *pname, INT8U *perr)。
打开软件定时器函数:BOOLEAN OSTmrStart (OS_TMR *ptmr, INT8U *perr)。
关闭软件定时器函数:BOOLEAN OSTmrStop (OS_TMR *ptmr,INT8U opt,void *callback_arg,INT8U *perr)。
以上是关于基于ucos的实时温度检测的主要内容,如果未能解决你的问题,请参考以下文章