System结构体封装了整个系统层,让App很容易基于System跨平台,那么System内部该如何组织?
ARM公司推荐嵌入式开发遵循CMSIS架构,用户应用程序可以调用实时内核(OS)、中间件等,也可以直接调用底层硬件基于CMSIS标准的函数接口,比如ST公司发布的STM32的硬件驱动LIB库,甚至直接访问最底层的寄存器。这种架构编程比较灵活,对于规模不大的嵌入式系统比较适合,但这样的一个架构分层还比较模糊,应用层几乎可以访问所有的系统层资源,比较任意。各种底层接口没有封装,规模一大很容易引起重名、相互调用,若更换处理器芯片,整个系统层都要重新设计,不便于移植。为了解决这些问题,需要引入新的概念:设备,基于设备把底层的硬件驱动函数按功能封装起来,这样可以把系统层内部理清、分层次、模块化、可移植。
设备这个词,我们是经常接触的,我们知道PC机的组成,就是由中央处理器、内存、硬盘、主板、电源、显示器等几样组成,这是物理上讲的,若从Windows操作系统角度看,我们可以看Windows的设备管理器。一台PC机在Windows XP的眼中由DVD驱动器、IDE控制器、处理器、磁盘驱动器、电池等等组成,每一个设备里面又细分为很多小设备。所以设备是Windows XP管理的基本对象。
在VS.Net架构的C#编程角度看,系统层System由各种功能子类组成,子类下面又分子类。应用层开发程序,就是面向System各种类开发即可,所以类是C#编程的基础单元。
无论设备还是类,它们都是表征一组具有相对完整功能的集合。比如一个人,由头、四肢、五脏六腑组成,这些部件都是相对完整的功能集,而头呢,又由大脑、眼睛、鼻子、耳朵等组成,它们的功能也是相对完整的。相对于类这个概念来说,嵌入式人员更容易接受设备这个名词,因为有很多实际的对应物存在,比如LCD、按键、存储器、串口、ADC、定时器、IO等等,都是具体的一个设备,它们有非常明确的功能定义,基本上各个项目都需要这些设备组合起来完成,只是不同的项目可能涉及的设备种类不同罢了,但基本上脱离不了这么几种。所以我们可以认为一个系统层System就是由不同的设备组成的,系统层内的中间件也是由设备来支持的,而设备则需要编写设备驱动代码,需要调用各种硬件驱动接口函数来实现,比如ST公司发布的STM32硬件驱动库来完成。
中低端嵌入式编程,因为资源比较紧张,为了节省资源,代码编写比较紧凑,所以长期以来应用层与系统底层是分不清的,这就导致经常一个人既要懂上层应用,又要懂底层驱动,对开发者的要求较高,这也增加了项目的开发难度。而现在高性能嵌入式芯片的出现,可以不再被资源约束,所以引入设备概念,让嵌入式编程真正意义上解决了一人打天下的尴尬局面,对于应用层开发人员来说,他们虽然不懂底层硬件驱动,但可以很容易理解设备这个功能接口,轻松完成项目需求,而对于底层驱动人员来说,一个个明确独立的设备,更有助于自己清晰的编写底层驱动,适合多人协助开发。所以msOS,可以认为是面向设备开发的架构。
每一个设备,都有一个对应的结构体封装,因为中低端嵌入式系统规模不大,为了方便应用查看,所以直接封装在System的Device里面。
只有在System的Device中的基础设备才可以被应用层访问、调用,而设备内的其它函数,都需要定义为Static类型,防止被外部调用。
一个设备驱动的代码编写一般的讲要分为五部分,以LCD设备为例:
1、 建立一个按键设备文件device_lcd.c。
2、 在device_lcd.c中编写lcd设备驱动代码,除了外部接口函数之外,其它的都需要定义为Static类型的静态函数,防止被外部函数调用。
3、 在SystemStruct的Device中添加Lcd设备结构体,内部包含接口函数指针。
4、 在Lcd设备初始化函数InitializeLcd中把Lcd设备的接口函数指针与Lcd设备的接口函数关联起来:System.Device.Lcd.DisplayString = LcdDisplayString;
5、 有些需要基于系统节拍运行的设备,比如按键、定时器设备,需要由系统节拍提供系统节拍服务程序:KeySystick100Service();TimerSystick1000Service();
引入设备概念,把系统层分为一个个相对独立的模块,内部的函数都通过Static封装了,只是保留了设备接口与外界联系,这样大大简化了系统的复杂度,调理更加清晰,可以支撑项目做的更大更强。封装之后的设备功能相对完整,独立性强,那么它是如何运转的呢?必须要有一套支撑设备运行的规范。
1、 设备一般分为两类,一类不需要系统节拍支撑它运行的,比如Lcd、IO等设备,它们由上层函数直接调用接口即可。还有一类需要由系统节拍设备支撑其运行的,比如按键和定时器设备,按键是基于每秒100次的按键扫描获取按键值,定时器是基于每秒1000次的系统节拍实现多路虚拟定时器。所以这一类设备,需要由系统节拍设备提供支持,它们的工作基于系统节拍之上运行,系统节拍设备是它们运行的基础。device_systick.c是系统节拍设备,它是相对比较特殊的基础设备。
2、 调用方式分为三种:上层与下层可以直接调用,下层对上层提供了两种方式,一是利用OS的消息机制实现信息上传,二是采用注册机制,实现类似处理器中断的方式,给上层提供信息。