联网设备显示有一个rtthread

联网设备显示有一个rtthread,第1张

你好,一、RT-Thread的定义

RT-Thread,全称是 Real Time-Thread, 是一款主要由中国开源社区主导开发的开源实时 *** 作系统(许可证GPLv2),包含了实时、嵌入式系统相关的各个组件:TCP/IP协议栈、图形用户界面等。

相较于Linux,RT-Thread 具有体积小,成本低,功耗低、启动快速的优势。除此以外,实时性高、占用资源小等特点,使得它也非常适用于各种资源受限(如成本、功耗限制等)的场合。

在物联网设备的应用中,RT-Thread 能使用在线软件包管理工具,配合系统配置工具,实现直观、快速的模块化裁剪、无缝导入丰富的软件功能包,以及类似 Android 的图形界面和触摸滑动、智能语音交互等复杂功能。

RT-Thread 系统完全开源,可以免费在商业产品中使用,并且不需要公开私有代码。

二、RT-Thread的架构

相对于一些传统的RTOS 如 FreeRTOS、uC/OS 等,RT-Thread 架构上最大的区别在于:它是一个物联网 *** 作系统(IoT OS)。

即RT-Thread 除了包含一个实时内核外,还包括如文件系统、图形库等较为完整的中间件组件,是具备低功耗、安全、通信协议支持和云端连接能力的软件平台,如下图所示:

在这里插入图片描述

具体包括以下部分:

内核层:

① RT-Thread 内核:系统核心部分,包括了内核系统中对象的实现,例如多线程及其调度、消息队列、内存管理等;

② libcpu/BSP(芯片移植相关文件 / 板级支持包):与硬件密切相关,由外设驱动和 CPU 移植构成;

组件与服务层:

组件是基于内核之上的上层软件,例如虚拟文件系统、FinSH 命令行界面、网络框架、设备框架等。采用模块化设计,做到组件内部高内聚,组件之间低耦合;

RT-Thread 软件包:

运行于 RT-Thread 物联网 *** 作系统平台上,面向不同应用领域的通用软件组件,由描述信息、源代码或库文件组成。开发者可依据自身需求,选择、组合不同软件包,打造自己想要的系统。

目前支持的软件包有且不仅有:

① 物联网相关:Paho MQTT、WebClient、mongoose、WebTerminal 等;

② 脚本语言相关:JerryScript、MicroPython ;

③ 多媒体相关:Openmv、mupdf;

④ 系统相关:RTGUI、Persimmon UI、lwext4、partition、SQLite 等。

三、RT-Thread的开发工具

Env 是 RT-Thread 的开发辅助工具,提供编译构建环境、图形化系统配置、软件包管理等功能。主要特性如下:

使用 scons 作为构建工具(根据一定的规则或指令,将源代码编译成可执行的二进制程序),提供编译环境,生成工程;

内置简单易用的配置剪裁工具——menuconfig,可对内核、组件和软件包进行自由裁剪,以搭积木的方式构建系统;

借助由 Kconfig 语法 编写的Kconfig 文件,生成系统配置文件 rtconfig.h。rtconfig.h 文件,负责在执行 menuconfig 命令时,指导生成 RT-Thread 系统的配置、剪裁界面;

提供多种软件包,可在线下载,各包耦合关联少,具有良好的可维护性。

在学习之前可以先去了解一下工作队列的使用场景: 工作队列 ( workqueue ) 。

简而言之,工作队列就是将一些工作任务的执行延迟,交由内核线程异步执行。

最简单的使用方式就是开启 RT-Thread 的系统工作线程(System workqueue),而我们往系统工作线程里提交工作项(work item)即可。

RT-Thread 其实给我们提供了一个系统工作线程了,但很少有人知道。配置选项路径如下图所示:

依次选中上述这些选项,就能够开启系统工作队列了。而且还可以看到工作队列线程的栈大小默认为 2048,优先级为 23 。

这样系统在初始化的时候就创建了系统工作队列了,名字叫作 sys_work ,在终端输入 ps 能够看到该线程。

如何向系统工作线程里添加工作项呢?

rt_work_submit() 用于向系统工作队列添加工作项, rt_work_cancel() 用于从系统工作队列中取消某一个工作项。

当然,在提交工作项时,需要初始化该工作项,绑定相应的回调函数和用户指针,接口如下:

这样,我们就可以随时随地地提交工作任务执行了,极大地方便了程序的组织。

用一个小例程测试一下:

在 qemu 项目里的 main.c 里输入:

然后执行就能看到下述效果,与工作项绑定的任务被异步执行了,而且工作项 1 延迟了 2 个 tick 才执行。

rt_workqueue 的接口有很多,我们只需要关注常用的即可。

首先使用 rt_workqueue_create() 创建一个工作队列,然后使用 rt_workqueue_submit_work() 提交工作项,使用 rt_workqueue_cancel_work() 取消工作项,当然还可以使用 rt_workqueue_destroy() 销毁一个工作队列。其他的接口有兴趣的可以了解,但常用的就是上面这四种。

这里提交任务与上述使用系统工作队列的唯一不同之处就是我们需要手动指定工作队列,其他的都是一模一样的。

用一个小例程测试一下:

在 qemu 项目里的 main.c 里输入:

然后执行就能看到下述效果,与工作项绑定的任务被异步执行了,而且工作项 1 延迟了 2 个 tick 才执行。

关于实现部分我这里不介绍具体细节,做了一些动画给大家展示一下内部过程

工作队列里面有一个线程(workthread),这个线程的任务就是不断地从挂载链表(worklist)里提取工作项执行,若没有则休眠。

然后提交工作项时,若延迟时间 time 大于 0,则启动该工作项的定时器,定时结束后再加入挂载链表(worklist)。

若提交工作项时延迟实际等于 0,则直接将该工作项挂加入到挂载链表(worklist)。

当然,工作项的定时器超时后,会自动将该工作项加入到挂载链表(worklist)。

当重启开发板直接挂载文件系统,就会看到 spi flash mount to /spi failed! 的提示,因为此时在 SPI Flash 中还没有创建相应类型的文件系统。

文件系统的挂载指的是将文件系统和具体的存储设备关联起来,并挂载到某个挂载点,这个挂载点即为这个文件系统的根目录。

[图片上传失败...(image-dd0ae4-1563508716000)]

在 github 上有一份独立仓库: rtthread-apps ,这份仓库中放置了一些和动态模块。

​ 编译成功会生成xxx.mo文件,将文件放置到rt-thread的文件系统上,就可以执行。

在msh命令中输入list_symbol命令。可以看到内核符号表(kernel symbol table)所映射的函数,这些函数就是模块模块开发当前能使用的函数

上述函数主要来自于rt-thread/src/xx.c文件、rt-thread/components/使用的组件xxx/src/xx.c文件

通过宏定义RTM_EXPORT(symbol) ,可以将函数导出到符号表。

rt_dlmodule结构体

动态模块API函数在rt-thread\components\libc\libdl\dlmodule.c文件中定义。

停止动态模块


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/8157392.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存