有些长期习惯在单片机中实现程序裸跑的程序员并不了解实时操作系统,在初次使用AWorks实时操作系统及例程时无从下手。就此问题,本文介绍在AWorks操作系统下的CAN例程使用。
AWorks简介
AWorks是ZLG开发的IoT物联生态系统,AWorks生态系统主要包括三个方面:硬件平台、OS、云,如图1.1所示。
图1.1 AWorks生态系统
AWorks OS作为生态系统的核心,为客户提供了多任务、信号量、Shell、消息队列、消息邮箱等服务,还包含了大量丰富的组件,例如:Modbus、TCP/IP、GUI、CAN、多媒体等。
1、多任务服务
在AWorks中可以使用裸跑的方式进行程序编写,但随着系统逐渐庞大时,单一的循环会使逻辑变得复杂而且也不能体现AWorks的优越性能,极大的增加了维护和扩展系统的难度,因此应用程序使用多任务管理时,可使程序简单明了,如程序清单1.1 所示。
程序清单1.1 创建can的任务
使用任务管理时首先创建任务,创建任务步骤主要分为三步:1.定义任务实体,2.初始化任务,3.启动任务。
定义任务实体:主要为任务分配必要的内存空间,在AWorks中可定义动态和静态任务实体,函数原型如程序清单1.2所示。
程序清单1.2 定义任务相关宏
task是任务实体名,stack_size指定为该任务分配的栈空间大小。
初始化任务:定义任务实体后需要初始化,在AWorks中提供了初始化任务实体的接口,原型如程序清单1.3所示。
程序清单1.3任务初始化
启动任务:任务初始化完成后可启动任务,进入入口函数执行任务代码,函数原型如程序清单1.4所示。
程序清单1.4 启动任务
终止任务:当一个任务处理完成后不会再调用该任务时,可以将此任务释放终止,用于节省系统资源,原型如程序清单1.5所示。
程序清单1.5 终止任务
2、信号量
信号量是一种轻型的用于解决任务间同步问题的内核对象,任务可以获取或者释放它,从而达到同步或互斥的目的,在AWorks中定义了三种类型的信号量:互斥信号量、二进制信号量、计数信号量,常用的为互斥信号量和二进制信号量。
互斥信号量:用于任务间对资源的互斥访问,在一个任务使用共享资源前获取互斥信号量,在使用共享资源结束后,释放互斥信号量,任务以独占的方式使用共享资源,互斥信号量相关的宏如程序清单1.6所示。
程序清单1.6 互斥信号量相关宏
sem:互斥信号量实体的标识名;
timeout:超时时间;
options:互斥信号量选项,如表1所示。
二进制信号量:二进制信号量也可用于实现共享资源的互斥访问,即在同一个任务中获取(使用共享资源前)和释放(使用共享资源后)信号量,但其不支持在任务内递归使用,当任务获取到信号量时,若没有释放,则在该任务内继续获取信号量时,将会获取失败,对于互斥信号量,只要任务成功获取到互斥信号量,后续在该任务内继续获取互斥信号量时,将会直接获取成功,二进制信号量相关的宏如程序清单1.7所示。
程序清单1.7 二进制信号量相关宏
sem:二进制信号量实体的标识名;
initial_state:指定初始状态,有效值为1,无效为0;
options:二进制信号量选项,同互斥信号量一样;
timeout:超时时间;
通常当需要任务间互斥访问某一共享资源时,建议都使用互斥信号量,互斥信号量和二进制信号量都只有两种状态:有效(1),无效(0)。
二进制信号量可以用于任务间的同步,即:一个任务仅获取信号量,另一个任务仅释放信号量。
互斥信号量只能使用于任务间的互斥,即:只能在同一任务中获取和释放互斥信号量,不能由一个任务获取互斥信号量,另外一个任务释放互斥信号量。
3、消息队列
消息队列用于任务间消息的传输,可以存放多条消息,发消息的任务负责将消息发送至队列,接收消息的任务负责从队列中提取消息,消息队列相关的宏如程序清单1.8所示。
程序清单1.8 消息队列相关宏
msgq:消息队列实体的标识名
msg_num:消息最大条数
msg_size:每条消息大小
options:消息队列选项,即先进先出/优先级排队方式
p_buf:获取消息后,消息存储区
nbytes:指定缓冲区大小,必须能够容纳一条消息
timeout:超时时间
priority:消息优先级