1.2 智能产品开发基础
1.2.1 硬件产品开发平台
1.智能产品原型机
通过智能产品原型机可以快速地开发智能产品,本书使用的智能产品原型机搭载了STM32F407微处理器、高清LCD显示屏、按键、RGB灯、局域网、高精度温湿度传感器等硬件,可以ZigBee、BLE、Wi-Fi、LoRa、NB-IoT、LTE进行数据传输,支持外接采集类传感器、安防类传感器、控制类传感器、识别类传感器。智能产品原型机涉及以下技术:
(1)硬件技术:电路原理图、嵌入式系统、传感器技术。
(2)嵌入式操作系统:Contiki操作系统、GUI应用开发。
(3)无线通信技术:LTE、BLE、LoRa、ZigBee、Wi-Fi、NB-IoT。
(4)云平台交互技术:智云API、ZXBee数据通信协议。
(5)应用层开发技术:Android应用技术和HTML5应用技术。
2.智能产品
本书介绍开发5个智能产品的开发,即智能台灯、智能腕表、运动手环、创意水杯和共享单车,相关硬件介绍如下:
(1)智能台灯硬件如图1.10所示。
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_23_1.jpg?sign=1739235113-fa62b05E7nQKUMiGC7OgcuCypqS05fQO-0-4d1337ae8ef0234a206a17e8772fed63)
图1.10 智能台灯硬件
(2)智能腕表硬件如图1.11示。
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_23_2.jpg?sign=1739235113-Xx1IzZ5vlC2PGGQ3PGhSJsgObBBnOHbo-0-c69565298d2bbd228f9fec2ed755863f)
图1.11 智能台灯硬件
(3)运动手环硬件如图1.12所示。
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_24_1.jpg?sign=1739235113-cr5DPr7SSuwx2KITHzMqCOmC9GYWbv38-0-b43be809359a7b0b11e5d4595975846f)
图1.12 运动手环硬件
(4)创意水杯硬件如图1.13所示。
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_24_2.jpg?sign=1739235113-HKq3IyT7mekfumWm2TLsElcqgO2N7eke-0-6e87514b4cd22523b3445e647d83dd6b)
图1.13 创意水杯硬件
(5)共享单车硬件如图1.14所示。
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_25_1.jpg?sign=1739235113-sqfZn2Cf0CRDf3FoL6Rpuy5yJbxii7By-0-9d3430015de5e49e7c76e25c7cfba052)
图1.14 共享单车硬件
1.2.2 Contiki操作系统
1.Contiki操作系统的简介及特点
(1)Contiki操作系统简介。Contiki操作系统是由瑞典计算机科学学院(Swedish Institute of Computer Science)的Adam Dunkels和他的团队开发的,是一个开源的、可灵活移植的多任务操作系统,适用于嵌入式系统和无线传感器网络。Contiki操作系统完全采用C语言开发,可移植性非常好,对硬件的要求极低,能够运行在多种微处理器和PC上,目前已经移植到了8051单片机、MSP430、AVR、ARM、PC等硬件平台上。
Contiki操作系统适用于硬件资源受限的嵌入式系统,Contiki操作系统的典型配置只占用约2KB的RAM和40KB的Flash存储器。Contiki操作系统是开源的操作系统,遵守BSD协议,开发者可以进行任意修改并发布,无须支付任何版权费用,已经应用在多个项目中。Contiki操作系统是基于事件驱动(Event-Driven)内核的操作系统,在此内核的基础上可以在运行时动态地加载应用程序,非常灵活。在事件驱动内核的基础上,Contiki操作系统构建了一个名为protothread的轻量级线程模型,通过该线程模型可以实现线性的、类似于线程的编程。protothread类似于Linux和windows中线程,多个线程共享同一个任务栈,可以减少RAM的使用。Contiki操作系统还提供了一种可选的任务抢占机制、基于事件和消息传递的进程间通信机制;包括一个可选的GUI子系统,可以支持本地串口终端、基于VNC的网络化虚拟显示或者Telnet图形化。
Contiki操作系统集成了两种类型的无线传感器网络协议栈,即uIP和Rime。uIP是一个小型的符合RFC规范的TCP/IP协议栈,可以直接连接互联网,uIP包含了IPv4和IPv6两种协议栈,支持TCP、UDP、ICMP等协议;Rime是一个为低功耗无线传感器网络设计的轻量级协议栈,该协议栈提供了大量的通信原语,能够实现从简单的一跳广播通信到复杂的可靠多跳通信。
(2)Contiki操作系统的特点。Contiki操作系统的特点如下:
① 采用了事件驱动的多任务内核。Contiki操作系统基于事件驱动的多任务内核,即多个任务共享同一个栈(Stack),而不是每个任务分别占用独立的栈。Contiki操作系统每个任务只占用几个字节的RAM空间,更适合资源受限的无线传感器网络。
② 集成了IP网络和低功耗无线传感器网络协议栈。Contiki操作系统提供完整的IP网络和低功耗无线传感器网络协议栈。对于IP网络协议栈,支持IPv4和IPv6两个版本,IPv6还包括6LoWPAN帧头压缩适配器、ROLL RPL无线网络组网的路由协议、CoRE/CoAP应用层协议,以及一些简化的Web工具(如包括Telnet、HTTP和Web服务等)。Contiki操作系统还实现了无线传感器网络领域的MAC层和路由层的协议,MAC层协议包括X-MAC、CX-MAC、ContikiMAC、CSMA-CA、LPP等,路由层协议包括AODV、RPL等。
③ 集成了无线传感器网络的仿真工具。Contiki操作系统提供了无线传感器网络仿真工具Cooja,能够在PC上对协议进行仿真,仿真通过后在下载到设备节点上进行实际测试,有利于发现问题,减少调试的工作量。
④ 集成了命令行调试工具Shell。无线传感器网络中节点数量非常多,节点的运行维护是一个难题。Contiki操作系统可以通过多种交互方式,如Web浏览器、基于文本的命令行接口,或者存储和显示传感器数据的专用程序等,对节点进行维护。Contiki操作系统集成的命令行调试工具Shell类似于UNIX操作系统中的命令行调试工具,用户通过串口输入命令就可以查看和配置无线传感器网络中节点的信息,控制节点的运行状态。
⑤ 采用了基于Flash的小型文件系统CFS。Contiki操作系统采用了一个简单、小巧、易于使用的文件系统,称为CFS(Coffee File System)。CFS是基于Flash的小型文件系统,适合在资源受限的节点上存储数据和程序。CFS是根据无线传感器网络数据采集和传输的需求,以及硬件资源受限的特点来设计的,在耗损平衡、坏块管理、掉电保护方面、垃圾回收、映射机制方等方面进行了优化,具有使用的存储空间少、支持大规模存储的特点。CFS的编程方法与常用的C语言编程类似,提供open、read、write、close等函数,易于使用。
⑥ 集成了能量分析工具。Contiki操作系统提供了一种基于软件的能量分析工具,该工具会自动记录每个节点的工作状态、时间,并计算出的能量消耗。Contiki操作系统的能量分析工具既可用于评估无线传感器网络的协议,也可用于估算无线传感器网络的生命周期。
⑦ 开源免费。Contiki操作系统遵守BSD协议,开发者可以用于科研和商业,且可以任意修改代码,无须支付任何专利以及版权费用,是彻底的开源软件。
2.Contiki操作系统的运行原理和main函数分析
(1)Contiki操作系统的运行原理。Contiki操作系统是基于事件驱动内核构建的,其运行可以看成一个不断处理事件的过程。Contiki操作系统的运行是通过事件触发完成的,一个事件绑定相应的进程。当事件被触发时,Contiki操作系统把运行权交给事件所绑定的进程。Contiki操作系统的运行原理如图1.15所示。
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_27_1.jpg?sign=1739235113-99Wj4obAKD69LbMW3c3um9v2QOyq9DKD-0-764782b54d2a3ac5a3e7e86cb469032a)
图1.15 Contiki操作系统的运行原理
从图1.15可以看出,在Contiki操作系统的运行过程中,应用程序是作为一个进程放在用户自启动进程的指针数组中。在启动Contiki操作系统后,先进行时钟初始化和进程初始化,接着启动系统进程(如管理etimer的系统进程etimer_process)和用户自启动进程,然后进入处理事件的死循环(如图1.15右侧的灰色框所示,实际上是运行process_run函数)。在处理事件的死循环中,Contiki操作系统通过遍历的方式判断是否有高优先级进程,执行完所有的高优先级进程后再去处理事件队列的事件,处理事件(执行事件对应的进程)之后,再次判断是否有高优先级进程。具体代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_27_2.jpg?sign=1739235113-YPhCFVjXZzC2qUxIS1Q6e6Vsy7qx9dLX-0-a73bba31212bb541d477af7ca9d59a8f)
(2)Contiki操作系统的main函数分析。对Contiki操作系统运行原理的理解,关键在于main函数。Contiki操作系统启动后,首先在main函数中先进行时钟初始化和进程初始化;接着启动系统进程etimer_process和指针数组autostart_processes[]里的所有进程,到这里就启动了所有的进程(当然,在后续的操作中还可能会动态地产生新的进程)。接下来的工作就是反复处理所有needspoll标记为1的进程及事件队列中的事件,在处理事件的过程中可能会产生新的事件,Contiki操作系统就是如此反复运行的。main函数的代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_28_1.jpg?sign=1739235113-UROZT0T63QXTYsbPT430oB2lFYFI4fXX-0-e8ee3ca447e8dff6b6683c5e18ab290c)
main函数中调用的函数如下所述:
① process_start()函数。process_start()函数用于启动一个进程后,首先将进程加入进程链表(需要事先验证参数,确保该进程不在进程链表中)并进行初始化(将该进程的状态设为运行状态,以及将lc设为0);然后为该给进程绑定一个PROCESS_EVENT_INIT事件后开始执行进行(需要事先参数验证,确保该进程已被设为运行态且该进程的函数指针thread不为空),执行进程实际上是执行进程结构体中的thread函数指针指向的函数,即PROCESS_THREAD(name, ev, data)函数;最后通过条件判断语句来判断进程的执行结果,如果返回值表示退出、结尾或者遇到PROCESS_EVENT_EXIT,则退出该进程,否则将挂起该进程,等待相应事件的发生。代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_28_2.jpg?sign=1739235113-hWfHyo4f5WoLtYy3Beh8P6f2MLeeuEgV-0-0c0ce1a48ce14193df125d050afda469)
② process_post_synch()函数。process_post_synch()函数会直接调用call_process()函数,在调用期间需要保存process_current,这是因为在调用call_process()函数执行进程p(程序代码中的进程p)时,process_current会指向当前进程p,而进程p可能会退出或者被挂起等待一个事件。代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_29_1.jpg?sign=1739235113-L2zb9QrtUMgYBmdoTU2B52jsVbawnurQ-0-d4d6138278161feefb9055bdc15aabe0)
③ call_process()函数。如果进程p的状态为PROCESS_STATE_RUNNING,并且进程中的函数指针thread(相当于该进程的主函数)不为空的话,就执行该进程。如果该进程的执行结果(返回值)表示退出、结尾或者遇到PROCESS_EVENT_EXIT,则退出该进程,否则该挂起进程,等待相应的事件发生。代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_29_2.jpg?sign=1739235113-GSlRq51CrG7cQULdrKXPXw4yGa47m7aQ-0-d6378da6f0b54bcec1661e098478907a)
④ exit_process()函数。exit_process()首先进行参数验证,确保即将退出的进程在进程链表中并且不是PROCESS_STATE_NONE状态,然后向其他进程发送一个同步事件PROCESS_EVENT_EXITED,通知其他进行将要该进程即将退出,让与该进程相关的其他进程进行相应的处理。如果要退出一个进程,就会向etimer_process进程发送一个PROCESS_EVENT_EXITED事件,etimer_process进程在收到这个事件后查找timerlist看看哪个timer是与将要退出的进程是相关的,把这个timer从timerlist中清除。代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_29_3.jpg?sign=1739235113-isaJvzBEZ81UvWPobxeglhXwytczzTOj-0-3dbf239735834bae1a986faa30a78593)
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_30_1.jpg?sign=1739235113-dHzEcLi0fk3WKmNFsElOb5r2TLGQPgBh-0-119f09ec8b1cdab56826a22073d09dc4)
3.基于Contiki操作系统编写温湿度传感器的驱动程序
这里以基于Contiki操作系统编写温湿度传感器的驱动程序为例,介绍在Contiki操作系统中创建用户进程的方法,以及在智云框架上编写设备节点(以温湿度传感器为例)的驱动程序的方法。
在Contiki操作系统中创建用户进程的方法比较简单,此处以编写温湿度传感器的驱动程序为例进行介绍。在Contiki操作系统中创建用户进程通常有三个步骤,即定义用户进程、在进程链表中添加用户进程信息、编写用户进程实体。创建完用户进程后,还需要编写设备节点(在sensor.c文件中编写,此处以温湿度传感器为例)的接口函数,以及无线连接进程、无线进程处理、蓝牙进程等的代码。
(1)定义用户进程。代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_30_2.jpg?sign=1739235113-4FYM8PzsZA61FqnpS8HFAtCfqOZalDDi-0-dca5bcfc8a7ac57233192c1efeed59b0)
在用户进程的定义中,PROCESS完成了两个功能:声明一个函数,该函数是用户进程的执行函数,即用户进程的函数指针thread所指的函数;定义用户进程的名称,即humiture。
(2)在进程链表中添加用户进程信息。代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_31_1.jpg?sign=1739235113-KWULH2lcQFMntOQgtpsBBLNay5jq5bOY-0-e50852f6ab19c603535ee9304a59c1b7)
上述代码将用户进程的信息添加到了进程链表中,“&humiture”用于将系统进程的执行指针指向humiture进程的执行函数地址。
(3)编写用户进程实体。代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_31_2.jpg?sign=1739235113-xYAJ68rvWEwwkR6dDHGTRY9H52LMVZv0-0-b8d00563eaa986d2615cec2918156fc5)
(4)在sensor.c文件中编写设备节点的接口函数。设备节点的接口函数如表1.1所示。
表1.1 设备节点的接口函数
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_32_1.jpg?sign=1739235113-52yXmHzA0DZH1B7wG0YHXaeltnXzwgwZ-0-09f6a98946f3a2096562d3df0335f110)
接口函数的代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_32_2.jpg?sign=1739235113-EjP6blaUgwCLncrwR6lK4Gg9Oq485CPL-0-b511c82c5063ecae2bce2e19ab2beb47)
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_33_1.jpg?sign=1739235113-ndZIWDA8cZAIjxNUyS57n01mUtCHC6tq-0-eb7a7433591a4ffce5e3298fbcc43bbe)
(5)无线连接进程的代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_33_2.jpg?sign=1739235113-zudFsUnCGjgID3YFPebaSJciB6c8rAEC-0-53709205ca497c0d20c27cb6a2175531)
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_34_1.jpg?sign=1739235113-Z9jdmRDIjxLEeJ8mHTX2SdRiB3kZ69k8-0-756daa19b4a305e44401118f93c62f2e)
(6)无线进程处理的代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_34_2.jpg?sign=1739235113-uRgSKiO39JZftiLEdVA2X2XOhjMtcpIN-0-6d8b5e09bee756500302f18230826457)
(7)蓝牙进程的代码如下:
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_35_1.jpg?sign=1739235113-RUhQf0X0fe54BF5ix4nXUYBIM2uHFLYm-0-186d4c15f5aa83a1422d44e41c87e5e3)
![](https://epubservercos.yuewen.com/6B01FC/19391577808685806/epubprivate/OEBPS/Images/40280_36_1.jpg?sign=1739235113-45IqNPPSFcQ4eWUIFlUqVFVAMFRkKEB5-0-81aa5e84047c1bd26d40f14532d34f5c)
(8)调用sensor_process进程进行温湿度数据的上报与检测。
1.2.3 小结
通过本节的学习,读者可以了解智能产品(如智能台灯、智能腕表、运动手环、创意水杯、共享单车)的硬件,以及Contiki操作系统的运行原理。