作者:鱼柯
概述(说明应用产生的背景、实现功能)
在一些低频采集设备中,典型的运行策略是,采集数据,上传数据,关闭外设进入睡眠状态;但是,在运行过程中,需要根据实际需求,更改采集频率,连接不同的设备,如果每次通过修改代码解决,通用性就很难保证,这个项目将一些 uart
型的传感器进行归类,通过文件设置数据交互过程中的命令,解析方式等,可以适配大多数的 uart
型传感器;同时,对一些网络摄像头也以同样的方式进行处理;
实现数据采集调度配置,数据采集,数据上传,图片采集,图片上传, 配置文件解析,固件远程更新;由于contab
配置文件中的 event
使用的是 MSH_CMD_EXPRT
宏导出的命令。所以,它也支持系统需要定时执行的相对时间间隔需要变化的任务,比如:12:00. 13:10, 15:35, 18:23
分别执行一次任务;
开发环境(
硬件:art-pi, INDUSTRY-IO, 微气象仪, 网络摄像头
RT-Thread版本:rt-thread 4.0.3
开发工具及版本:ubuntu 18.04
, gcc-arm-none-eabi-6_2-2016q4
, scons v3.0.1
, python 3.6.9
, pkgs
RT-Thread使用情况概述(简要总结下应用中RT-Thread使用情况:内核部分、组件部分、软件包部分、内核、其他)
内核部分
-
Inter-thread communication
-
Event
-
Semaphore
-
mutex
-
memory management
-
device object
组件部分
-
Finsh
-
DFS (device virtual file system)
-
serial device, mtd nor flash device, gpio device, ntp rtc device, sd/mmc device, spi device, serial flash universal driver (device driver)
-
posix layer and c stand library
-
SAL (socket abstraction layer)
-
ping, ifconfig, netstat, netdev (network interface)
-
LwIP 2.0.2
-
Ymodem
-
ulog
软件包部分
-
agile_console-v1.0.0
-
fal-v0.5.0
-
ota_downloader-v1.0.0
-
agile_telnet-v2.0.0
-
littlefs-v2.2.1
-
SignalLed-latest
-
cJSON-v1.0.2
-
netutils-v1.2.0
-
vi-latest
-
EasyFlash-v4.1.0
-
webclient-v2.1.1
硬件框架(概述应用所采用的硬件方案框图,并对核心部分做介绍)
软件框架说明(介绍应用所采用的软件方案框图、流程图等,并加以解说)
软件模块说明(介绍应用软件关键部分的逻辑、采用的实现方式等)
类似 linux定时任务contab
解析相关 json
配置文件,构建设备运行数据树:
"contab": [
{
"event": "misc_check",
"time": "0 18"
},
{
"event": "img_cap_start",
"time": "20 7,9,14"
},
{
"event": "app_image_upload",
"time": "20 7,9,14"
},
{
"event": "sensor_acq_start",
"time": "5,10,15,20,25,30,35,40,45,50,55 *"
},
{
"event": "app_data_upload",
"time": "5,10,15,20,25,30,35,40,45,50,55 *"
}
]
事件执行分钟: 表示 xx:5, xx:25, xx:30, xx:36, xx:45, xx:54
事件执行小时:*
通配符,表示1-24小时
上面参数表示:每个小时的 5,25,30,45,54
分,执行img_upload_invl
事件;
上传数据
每次采集数据后,将数据存在本地一个缓存文件中,按照采集时间从前到后写入;同时会生成一个读取位置的缓存文件指示,下一次从哪个文件的那一行读取数据进行上传,上传成功后,更新读取位置的缓存;如20201217,227
, 表示从文件 20201217.txt
的 227
个字符后读取一行数据进行上传,避免文件过大引起设备死机;
上传图片
每次拍照时,将拍照成功的照片名及端口追加记录到一个缓存文件中,每次从缓存文件中,读取需要上传的图片构造 form-data
上传图片;如4,/sd/1608167012_4.jpg
;如果上传成功,则删除该条记录;
固件更新
固件更新的逻辑比较简单,http get
服务器是否有新的固件,如果有,返回新固件的 url
地址,设备从服务器拉下固件到 flash 的 download 分区,重启设备即可;
配置文件更新
配置文件更新的逻辑也比较简单,http get
向服务器查询当前设备的配置文件是否发生变化,如果发生变化,返回1,设备从服务器固定位置拉下配置文件,拆解成 contab
, data
, image
三个文件即可;
web接口
服务器端口配置
通过 url_cfg {url}
可配置设备数据上传的服务器地址;
例如:
url_cfg
http://xxx.xxx.xxx.xxx:xxx
上传单条数据
/d/{dId}/c/{cId}/sd
上传图片文件
/device/{dId}/config/{cId}/image/{iKey}
获取设备配置文件是否一致
/device/{deviceId}/config/{id}
返回:
{n:1}
返回1
,版本一致;
返回0
,版本不一致;
获取设备配置文件
/device/{dId}/config
返回配置文件
获取固件信息
/device/{dId}/version/{v}/firmware
返回:
{"device_id": "4", "device_type": "abc", "version": "null", "addr": "null"}
如果addr
不为null
, 从其提供的地址下拉固件升级;
演示效果(演示效果请采用3张高清图片,并录制一段不少于1min视频解说应用所实现的效果,视频上传至B站或者腾讯视频或其他视频平台,给出链接即可)
全家福
简单看看一段运行日志,此时的配置信息如下
{
"contab": [{
"event": "ntp_sync",
"time": "0 18"
}, {
"event": "img_cap_start",
"time": "30,31,32 7,9,12"
}, {
"event": "img_up_start",
"time": "30,31,32 7,9,12"
}, {
"event": "sensor_acq_start",
"time": "5,10,15,20,25,30,32,34,35,40,45,50,55 *"
}, {
"event": "sensor_up_start",
"time": "5,10,15,20,25,30,32,34,35,40,45,50,55 *"
}]
}
设备在 9:05,9:10,9:15,9:20,9:25,9:25
按照配置表运行;
中途,设备上传数据失败,下次连接成功后,将以前没有上传的数据上传;
演示视频:
比赛感悟
用过RT-Thread 一段时间了,模块化,软件包,Env
配置工具,图形化快速裁减,但是,主力开发环境切换到 ubuntu
上后,还是有点问题,不同于使用 RT-Studio
, 还是要稍微折腾一下,1. 配置编译工具链; 2. 修正pkgs --upgrade
更新后kconfig
导致的一些问题; 3. 解决在 project 目录下使用 scons --dist
的一些问题;但是有了 RT-Thread 完整版的众多例子和官网文档,论坛这些都不是问题;花花时间就可以搞定;初次接触 M7
内核的东西,750
的 XIP
的引起好奇,不过百度百度也大概明白,核心也就是内存重映射,bootloader
跳转;不过在此过程中学习的烧录程序算法的原理,回收一个盲点; 使用 stm32cube programmer
connect 后下载时,发现需要disconnect,系统才可以执行,烧录过程中一度以为板子坏掉,不过发现规律后,就比较舒服;猜测,reset 后, botoloader
跳转失败,猜测 connect
连接 MCU
, 并将烧录算法写入 RAM
中,disconnect
可能清除对 MCU Core
的控制,reset
后就可进入application
部分了; 遗憾的时,搞了个腾讯云,用 aiohttp
写了个简单的服务器,没有连接数据库,没有前端,所以,配置文件的更新和固件的更新没法演示,不过,通过比赛,知道自己短板,也是不错,最后感谢电路城,感谢 RT-Thread 搞得这个活动;