I/O设备模型
I/O设备模型
绝大部分的嵌入式系统都包括一些I/O(Input/Output,输入/输出)设备。
例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的 Flash 或 SD 卡,以及网络设备的以太网接口等,都是嵌入式系统中容易找到的 I/O 设备例子。
I/O设备模型框架
提供了一套简单的I/O设备模型框架,它位于硬件和应用程序之间,共分成三层,从上到下分别是I/O设备管理层、设备驱动框架层、设备驱动层。
应用程序通过I/O设备管理接口获得正确的设备驱动,然后通过这个设备驱动与底层I/O硬件设备进行数据交互。
I/O设备管理层实现了对设备驱动程序的封装。应用程序通过图中的“I/O设备管理层”提供的标准接口访问底层设备,设备驱动程序的升级、更替不会对上层应用产生影响。
这种方式使得设备的硬件操作相关的代码能够独立于应用程序而存在,双方只需关注各自的功能实现,从而降低了代码的耦合型、复杂性,提高了系统的可靠性。
设备驱动程序框架层是对同类硬件设备驱动的抽象,将不同厂家的同类硬件设备驱动中相同的部分抽取出来,将不同部分留出接口,由驱动程序实现。
设备驱动层是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。
它负责创建和注册I/O设备,对于操作逻辑简单的设备,可以不经过设备驱动框架层,直接将设备注册到I/O设备管理器中。
- 设备驱动根据设备模型定义,创建出具备硬件访问能力的设备实例,将该设备通过rt_device_regster()接口注册到I/O设备管理器中。
- 应用程序通过 rt_device_find() 接口查找到设备,然后使用 I/O 设备管理接口来访问硬件。
对于另一些设备,如看门狗等,则会将创建的设备实例先注册到对应的设备驱动框架中,再由设备驱动框架向 I/O 设备管理器进行注册,主要有以下几点:
看门狗设备驱动程序根据看门狗设备模型定义,创建出具备硬件访问能力的看门狗设备实例,并将该看门狗设备通过 rt_hw_watchdog_register() 接口注册到看门狗设备驱动框架中。
看门狗设备驱动框架通过 rt_device_register() 接口将看门狗设备注册到 I/O 设备管理器中。
应用程序通过 I/O 设备管理接口来访问看门狗设备硬件。
I/O设备模型
RT-Thread 的设备模型是建立在内核对象模型基础之上的,设备被认为是一类对象,被纳入对象管理器的范畴。每个设备对象都是由基对象派生而来,每个具体设备都可以继承其父类对象的属性,并派生出其私有属性,下图是设备对象的继承和派生关系示意图。
该图横向看是分层思想,纵向看是各类派生继承关系。
从下到上不断抽象,屏蔽下层差异,体现了面向对象的抽象的思想。
子类受到父类的接口约束,子类各自实现父类提供的统一接口,又体现了面向接口编程的思想。
比如从驱动层到驱动框架层,由不同厂商的相同硬件模块创建了很多子类对象,然后对接到同一个父类接口上,多对一,体现面向对象的抽象的威力。
时钟管理
操作系统中最小的时间单位是时钟节拍(OS Tick)。
时钟节拍
任何操作系统都需要提供一个时钟节拍,以供系统处理所有和时间有关的事件,如线程的延时、线程的时间片轮转调度以及定时器超时等。
时钟节拍是特定的周期性中断,这个中断可以看做是系统心跳,中断之间的时间间隔取决于不同的应用,一般是1ms~100ms,时钟节拍率越快,系统的实时响应越快,但是系统额外开销越大。
从系统启动开始计数的时钟节拍数称为系统时间。
RT-Thread 中,时钟节拍的长度可以根据 RT_TICK_PER_SECOND 的定义来调整,等于 1/RT_TICK_PER_SECOND 秒。
内核移植
内核移植就是指将RT-Thread内核在不同的芯片架构、不同的板卡上运行起来,能够具备线程管理和调度,内存管理,线程间同步和通信,定时器管理等功能。
移植可分为CPU架构移植和BSP(Board support package,板级支持包)移植两部分。
CPU架构移植
在嵌入式领域有多种不同CPU架构,例如Cortex-M、ARM920T、MIPS32、RISC-V等等。
为了使RT-Thread能够在不同CPU架构的芯片上运行,RT-Thread提供了一个libcpu抽象层来适配不同的CPU架构。
RT-Thread 提供了一个 libcpu 抽象层来适配不同的 CPU 架构。libcpu 层向上对内核提供统一的接口,包括全局中断的开关,线程栈的初始化,上下文切换等。
RT-Thread 的 libcpu 抽象层向下提供了一套统一的 CPU 架构移植接口,这部分接口包含了全局中断开关函数、线程上下文切换函数、时钟节拍的配置和中断函数、Cache 等等内容。下表是 CPU 架构移植需要实现的接口和变量。
实现全局中断开关
无论内核代码还是用户代码,都可能存在一些变量,需要在多个线程或者中断里面使用,如果没有相应的保护机制,那就可能导致临界区问题。
RT-Thread里为了解决这个问题,提供了一系列的线程间同步和通信机制来解决。但是这些机制都需要用到libcpu里提供的全局中断开关函数。
它们分别是:
/* 关闭全局中断 */
rt_base_t rt_hw_interrupt_disable(void);
/* 打开全局中断 */
void rt_hw_interrupt_enable(rt_base_t level);
rt_hw_interrupt_disable PROC
EXPORT rt_hw_interrupt_disable
MRS r0,PRIMASK
CPSID I
BX LR
ENDP
上面的代码首先使用MRS指令将PRIMASK寄存器的值保存到r0寄存器里,然后使用CPSID I指令关闭全局中断,最后使用BX指令返回。
打开全局中断
在rt_hw_interrupt_enbale(rt_base_t level)里,将变量level作为需要恢复的状态,覆盖芯片的全局中断状态。
基于MDK,在Cortex-M内核上实现打开全局中断。
;/*
; * void rt_hw_interrupt_enable(rt_base_t level);
; */
rt_hw_interrupt_enable PROC ; PROC 伪指令定义函数
EXPORT rt_hw_interrupt_enable ; EXPORT 输出定义的函数,类似于 C 语言 extern
MSR PRIMASK, r0 ; 将 r0 寄存器的值写入到 PRIMASK 寄存器
BX LR ; 函数返回
ENDP ; ENDP 函数结束
RT-Thread构建与配置系统
- KConfig:kernel config配置文件(提供系统的配置裁剪功能)
- SCons:构建工具
- env工具:主要提供构建系统所需的各种环境变量以及软件包的管理
Env是RT-Thread推出的开发辅助工具,针对基于RT-Thread操作系统的项目工程,提供编译构建环境、图形化系统配置及软件包管理功能。
其内置的menuconfig提供了简单易用的配置剪裁工具,可对内核、组件和软件包进行自由裁剪,使系统以搭积木的方式进行构建。
主要特性
- menuconfig图形化配置界面,交互性好,操作逻辑强。
- 丰富的文字帮助说明,配置无需查阅文档。
- 使用灵活,自动处理依赖,功能开关彻底。
- 使用 scons 工具生成工程,提供编译环境,操作简单;
- 提供多种软件包,模块化软件包耦合关联少,可维护性好。
- 软件包可在线下载,软件包持续集成,包可靠性高
KConfig在RT-Thread中的工作机制
C语言项目的裁剪配置本质上是通过条件编译和宏的展开来实现的。
借助KConfig这套机制更方便的实现了这一功能。
Kconfig机制包括了Kconfig文件和配置UI界面(如menuconfig,pyconfig等)。Kconfig机制有如下特点:
- Kconfig文件中的配置项会映射至rtconfig.h中
- KConfig文件可以随源码分散至各级子目录,便于灵活修改。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!