rtthread源码目录(rtthread源码分析)
本文目录一览:
- 1、rtt operation用法
- 2、RT_Thread组件开发
- 3、[RT-Thread]事件(event)
- 4、RT-Thread workqueue 详解
- 5、rt-thread和kernel的区别
- 6、rtthread和linux的区别
rtt operation用法
RTT的用户手册中也有介绍到,最上层一套面向嵌入式系统,专门优化过的虚拟文件系统(接口)。通过它,RT-thread操作系统能够适配下层不同的文件系统格式。
在RTT源码文件.\components\dfs\src目录下的dfs_posix.c源文件就是具体实现这些接口的源代码,其共实现了接口有20个与文件目录相关的posix接口函数:chdir 修改工作目录close 关闭一个文件closedir 关闭一个目录fstat 获取一个文件的状态信息getcwd 获取当前的工作目录seek 移动文件滑标操作mkdir 新建一个目录open 打开一个文件opendir 打开一个目录read 从一个打开的文件中读取数据readdir 读取下一个目录节点rename 重命名一个文件rewinddir 重置目录流rmdir 删除一个目录seekdir 与lseek相似,这里操作的是目录,设置目录滑标的位置stat 获取文件相关信息statfs 获取一个挂载的文件系统相关信息telldir 获取当前目录流中滑标的位置unlink 将一个目录从文件系统中移除write 将数据写入文件
RT_Thread组件开发
当重启开发板直接挂载文件系统,就会看到 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文件中定义。
停止动态模块
[RT-Thread]事件(event)
event就像是一个非定向的事件通知器,可以实现一( thread )对多( thread )、多( thread )对一( thread )、多( thread )对多( thread )的线程间同步。
一个 event 包含一个32位事件集,每一位都可以表一个单独事件。比如:
发送 event 可以任意组合:
接收 event 时也可以按需组合事件,看一下 rt_event_recv 函数用法:
那么使用就比较简单了,如果需要 EVENT_FLAG3 和 EVENT_FLAG5 都满足,则如下侦听( RT_EVENT_FLAG_CLEAR 按需):
EVENT_FLAG3 和 EVENT_FLAG5 可以是一个thread设置:
也可以是两个thread分别设置:
一个 event 的 suspended_thread 列表里的 thread 等待的事件集不一定相同,所以为做区分,在 rt_thread 中新增两个成员,用于存储 thread 等待的事件集:
RT-Thread workqueue 详解
在学习之前可以先去了解一下工作队列的使用场景: 工作队列 ( 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)。
rt-thread和kernel的区别
RT-Thread,全称是RealTime-Thread,是一款主要由中国开源社区主导开发的开源实时操作系统(许可证GPLv2),包含了实时、嵌入式系统相关的各个组件:TCP/IP协议栈、图形用户界面等。相较于Linux,RT-Thread具有体积小,成本低,功耗低、启动快速的优势,Kernel表示软件的内核,可重复使用,像种子一样。
rtthread和linux的区别
RT-Thread Smart 定位于成为一个专业的面向实时应用场合的高性能混合微内核操作系统。填补传统 RTOS 和大型操作系统 Linux 之间的空白,在实时性、成本、安全性、启动速度等方面取得最佳的平衡。
01 RT-Thread Smart和Linux相比:
启动速度最快可在几百毫秒以内
抢占式调度内核,任务响应性能相比 Linux 更加优秀
OS占用内存空间以及Flash空间极小,可最大化节约物料成本;
支持Windows下开发应用程序,开发环境更加友好;
系统和应用分离,方便应用程序和系统单独发布、单独升级;
重大组件和服务运行在用户态,操作系统更加轻量、安全;