嵌入式软件分层架构

文章目录

  • 起因
  • 设计思路
  • 驱动框架接口介绍
  • 目前开发进度

起因

开发基于stm32的样板嵌入式项目工程(使用keril环境的,最小的一个工程,不涉及业务功能,只有驱动和必要的外设初始化),嵌入式定义好与硬件驱动交互的接口,这样以后不同的stm32芯片,只需要换驱动就行,不需要上层业务。

开发这样的系统架构,主要就是为了:

1、应用的代码逻辑清晰,且避免重复的造轮子。

2、如果没有好的架构,移植将会是一件很痛苦的事情,因此一个好的架构设计,方便软件的移植。

3、最大限度的复用。

4、高耦合低内聚。

设计思路

移植参考RT-thread 内核,采用一套统一的设备驱动管理接口进行数据访问,I/O 设备模型框架
如下图所示,它位于硬件和应用程序之间,共分成三层,从上到下分别是 I/O 设备管理层、设备驱动框架层、设备驱动层。
嵌入式软件分层架构_第1张图片
应用程序通过 I/O 设备管理接口获得正确的设备驱动,然后通过这个设备驱动与底层 I/O 硬件设备进行数据(或控制)交互。

I/O 设备管理层实现了对设备驱动程序的封装。应用程序通过 I/O 设备层提供的标准接口访问底层设备,设备驱动程序的升级、更替不会对上层应用产生影响。这种方式使得设备的硬件操作相关的代码能够独立于应用程序而存在,双方只需关注各自的功能实现,从而降低了代码的耦合性、复杂性,提高了系统的可靠性。

设备驱动框架层是对同类硬件设备驱动的抽象,将不同厂家的同类硬件设备驱动中相同的部分抽取出来,将不同部分留出接口,由驱动程序实现。

设备驱动层是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。它负责创建和注册 I/O 设备,对于操作逻辑简单的设备,可以不经过设备驱动框架层,直接将设备注册到 I/O 设备管理器中,使用序列图如下图所示,主要有以下 2 点:

设备驱动根据设备模型定义,创建出具备硬件访问能力的设备实例,将该设备通过 rt_device_register() 接口注册到 I/O 设备管理器中。

应用程序通过 rt_device_find() 接口查找到设备,然后使用 I/O 设备管理接口来访问硬件。

驱动框架接口介绍

struct rz_device
{
		char name[RZ_NAME_MAX];		        /* device name  */
        enum rz_device_class_type type;         /**< device type */
        rz_uint16_t flag;                               /**< device flag */
        rz_uint16_t open_flag;                          /**< device open flag */
        rz_uint8_t ref_count;                      /**< reference count */
        
        bool (*init)(rz_device_t dev);
		bool (*open)(rz_device_t dev);
		bool (*close)(rz_device_t dev);
		rz_size_t (*read)(rz_device_t dev, rz_off_t pos, void *buffer, rz_size_t size);
		rz_size_t (*write)(rz_device_t dev, rz_off_t pos, const void *buffer, rz_size_t size);
		bool (*control)(rz_device_t dev,int cmd, void *args);

        /* device call back */
        bool (*rx_indicate)(rz_device_t dev, rz_size_t size);
        bool (*tx_complete)(rz_device_t dev, void *buffer);

        void  *user_data;                /**< device private data */
             
		struct list_head device_list;
};
/************************Interface calls provided to applications************************/
int rz_device_register(rz_device_t dev,const char *name,rz_uint16_t flags);
int rz_device_unregister(rz_device_t dev);
rz_device_t rz_device_find(const char *name);
bool rz_device_init(rz_device_t dev);
bool rz_device_open(rz_device_t dev);
bool rz_device_close(rz_device_t dev);
rz_size_t rz_device_read(rz_device_t dev,rz_off_t pos,void *buffer, rz_size_t size);
rz_size_t rz_device_write(rz_device_t dev,rz_off_t pos,const void *buffer,rz_size_t size);
bool rz_device_control(rz_device_t dev, int cmd, void *arg);
bool rz_device_set_rx_indicate(rz_device_t dev, bool (*rx_ind)(rz_device_t dev, rz_size_t size));
bool rz_device_set_tx_complete(rz_device_t dev,bool (*tx_done)(rz_device_t dev, void *buffer));

目前开发进度

  • 移植设备驱动框架开发
  • 移植ADC驱动
  • 移植RTC驱动
  • 移植HWTIMER驱动
  • 移植 easylogger
  • 移植 multi_timer
  • 待更新【2020年6月27日23:46:11】

你可能感兴趣的:(工作)