嵌入式技术基础与实践-学习札记(三)

嵌入式技术基础与实践-学习札记(三)

嵌入式硬件构件

概念

嵌入式硬件构件是指将一个或多个硬件功能模块,支撑电路及其功能描述封装成一个可重用的硬件实体,并提供一系列规范的输入/输出接口。硬件模块是硬件构件的组成部分,一个硬件构件可能包含多个硬件功能模块

分类

根据接口之间的生产消费关系,接口可分为供给接口和需求接口两类。根据所拥有的接口类型的不同,硬件构件分为核心构件、中间构件和终端构件。

  • 核心构件只有供给结构,没有需求接口。也就是说,只为其他硬件构件提供服务,而不接受服务。例如芯片的硬件最小系统
  • 中间构件既有需求接口又有供给接口。例如电源控制构件,\(232\)电平转换构件。
  • 终端构件只有需求接口,它只接受其他构件提供的服务。例如\(LCD\)构件,\(LED\)构件,键盘构件。

利用硬件构件进行嵌入式系统硬件设计之前,应该进行硬件构件的合理划分,按照一定规则,设计与系统目标无关的构件个体,然后进行“组装”,完成具体系统的硬件设计。

电路图设计简明规则

在绘制原理图时,一个硬件构件使用一个虚线框,把硬件构件的电路及其文字描述括在其中,对外接口引出到虚线框外,填上接口网标。

1. 硬件构件设计的通用规则

(1)、元器件命名格式:对于核心构件,其元器件直接编号命名,同种类型的元件命名时冠以相同字母前缀。如电阻\(R1,R2\)。对于中间构件和终端构件,其元器件命名格式采用“构件名-标志字符?“。例如,\(LCD\)构件的电阻名为\(LCD-C1\)。当构件原理图应用到具体系统时,可借助原理图编辑软件自动编号。

(2)、为硬件构件添加详细的文字描述,包括中文名称、英文名称、功能描述、接口描述、注意事项等,以增强原理图的可读性。

(3)、前两步产生的内容封装在一个虚线框内,组成硬件构件的内部实体。

(4)、为该硬件构件添加与其他构件交互的输入/输出接口标识。接口标识有两种:

  • 接口注释标于虚线框内,是为构件接口所做的解释性文字。
  • 接口网标位于虚线框外,且具有电路连接特性。

2. 核心构件设计规则

设计核心构件时,需要考虑的问题是:“核心构件能为其他构件提供哪些信号?

核心构件其实就是某型号\(MCU\)的硬件最小系统。核心构件设计的目标是:凡是使用该\(MCU\)进行硬件系统设计时,核心构件可以直接“组装”到系统中,无需任何改动。

在进行接口设计时,需要将所有可能使用到的引脚都标注上接口网标。若同一引脚具有不同的功能,则接口网标依据第一功能命名。

3. 中间构件设计规则

设计中间构件时,需要考虑的问题是:”中间构件需要接受哪些信号,以及提供哪些信号?

一个中间构件应具有明确的且相对独立的功能,它既要有接受其他构件提供的服务的接口,即需求接口,又要有为其他构件提供服务的接口,即供给接口。描述需求接口采用接口注释,处于虚线框内,描述供给接口采用接口网标,处于虚线框外。

将构件的需求接口放置在构件实体的左侧,供给接口放置在右侧。接口网标的命名规则是:构件名称-引脚信号/功能名称。

嵌入式技术基础与实践-学习札记(三)_第1张图片

4. 终端构件设计规则

设计终端构件时,需要考虑的问题是:”终端构件需要什么信号才能工作?

它仅有与上一级构件交互的需求接口,因而街廓标识均为斜体标注的接口注释。

嵌入式技术基础与实践-学习札记(三)_第2张图片

使用硬件构件化思想设计嵌入式硬件系统的过程与步骤如下:

  1. 根据系统的功能划分出若干个硬件构件。
  2. 将所有的硬件构件原理图”组装“在一起
  3. 为中间构件和终端构件添加接口网标。

嵌入式底层驱动构件的概念与层次模型

嵌入式系统中,驱动程序是直接工作在各种硬件设备上的软件,是硬件和高层软件之间桥梁。

嵌入式底层驱动构件的概念

  • 构件\((Component)\)是可重用的实体,它包含合乎规范的接口和功能实现,能够被独立部署和被第三方组装。

  • 软件构件是指,在软件系统中具有相对独立功能、可以明确辨识的构件实体。
  • 嵌入式软件构件是实现一定嵌入式系统功能的一组封装的、规范的、可重用的、具有嵌入式特性的软件构件单元。是组织嵌入式系统功能的基本单位。
  • 嵌入式底层驱动构件,简称底层驱动构件或硬件驱动构件,是直接面向硬件操作系统的程序代码及使用说明。规范的底层驱动构件由头文件及源程序文件构成。头文件是底层驱动构件简明且完备的使用说明,也就是说,不需要查看源程序文件,就能够使用该构件进行下一层程序的开发。

嵌入式硬件构件和软件构件的层次模型

在硬件构件层中,相对于核心构件而言,中间构件和终端构件是核心构件的”外设“。由这些”外设“的驱动程序封装而成的软件构件成为底层外设构件。

嵌入式技术基础与实践-学习札记(三)_第3张图片

由上图可以看出,底层外设构件可以调用底层内部构件,如\(LCD\)构件可以调用\(GPIO\)驱动构件。而高层构件可以调用底层外设构件和底层内部构件中的功能构件,而不能直接调用\(GPIO\)驱动构件。另外,几乎所有的底层内部构件都涉及\(MCU\)各种寄存器额使用,因此将\(MCU\)的所有寄存器定义组织在一起,形成\(MCU\)头文件。

底层驱动构件的封装规范

构件设计的基本思想与基本原则

  1. 构件设计的基本思想

    底层构件被组织成具有一定独立性的功能模块,由头文件和源程序文件两部分组成。构件的头文件名和源程序名一致,且为构件名。

    构件的头文件中,主要包含必要的引用文件、描述构件功能特性的宏定义语句以及声明对外接口函数。

    构件的源程序文件中包含构件的头文件,内部函数声明、对外接口函数的实现。

    尽量做到:当一个底层构件应用到不同系统中时,仅需修改构件的头文件,对于构件的源程序文件则不必要修改或改动很小。

  2. 构件设计的基本原则

    良好的底层驱动具有以下特性:

    • 封装性。即内部实现的调整不会影响构件调用者的使用。

    • 描述性。构件必须提供规范的函数名称、接口信息,参数含义与范围、必要的注意事项等。

    • 可移植性。同样功能的构件,做到不改动或少改动,而方便的移植到同系列及不同系列芯片内。

    • 可复用性。高层调用者对构件的使用不会因底层实现的变化而有所改变。

    1、层次化原则

    • 针对应用场景和服务对象,分层组织构件。设计底层驱动构件的过程中,有一些与处理器相关的、描述了芯片寄存器映射的内容,这些是所有底层驱动构件都需要使用的,将这些内容组织成底层驱动的公共内容,作为底层驱动构件的基础。

    • 在构件的层次模型中,上层构件可以调用下层构件提供的服务,同一层次的构件不存在相互依赖关系,不能相互调用。

    2、易用性原则

    • 函数名简洁且达意;接口参数清晰,范围明确,使用说明语言精炼规范,避免二义性。

    3、鲁棒性原则

    • 再明确函数输入输出的取值范围,提供清晰接口描述的同时,在函数实现内部要有对输入输出参数的检测,对超出合法范围的输入参数进行必要的处理。

    4、内存可靠使用原则

    • 优先使用静态分配内存。
    • 谨慎使用变量。
    • 检测空指针。
    • 检测缓冲区溢出,并为内存中的缓冲区预留不小于\(20\%\)的冗余。

编码风格基本规范

命名基本原则:

  • 命名清晰明了,有明确含义,使用完整单词或约定俗称的缩写。

  • 命名风格要自始至终保持一致。

  • 为了代码的复用,命名中应避免使用与具体项目相关的前缀。

  • 为了便于管理,对程序实体的命名要体现出所属构件的名称。

  • 使用英文命名。

  • 除宏命名外,名称字符全部小写,以”_”作为单词的分隔符。

    1、文件的命名

    • 底层驱动构件在具体设计时分为两个文件,头文件,源文件,命名格式为 .后缀。

    2、函数的命名

    • 底层驱动构件的函数从属于驱动构件,驱动函数的命名除了要体现函数功能外,还需要使用命名前缀和后缀标识其所属的构件及不同的实现方式。
    • 函数名前缀:底层驱动构件中定义的所用函数均使用” _“前缀标识其所属的驱动构件模块。
    • 函数名后缀:对同一服务的不同方式的实现,使用后缀加以区分。

    3、函数形参变量与函数内局部变量的命名

    • 函数形参变量:函数形参变量名应直观表明参数意义,若传入的参数是指针类型应使用\(“\_prt”\)后缀加以标识。
    • 局部变量:局部变量的命名与函数形参变量类型。注意一般不取单个字符\((i,j,k)\)进行命名。

    4、宏常量及宏函数的命名

    • 宏常量和宏函数的命名全部使用大写字符,使用下划线为分隔符。

    5、结构体类型的命名、类型定义与变量声明

    • 结构体类型名称使用小写字母命名,定义结构体类型变量时,全部使用大写字母命名。
    • 对结构体内部字段全部使用大写字母命名。
    • 定义类型时,同时声明一个结构体变量和结构体指针变量。

注释

​ 在程序代码中使用注释,说明程序在“做什么”,解释代码的目的,功能和采用的方法。

​ 1、 文件头注释

嵌入式技术基础与实践-学习札记(三)_第4张图片

2、函数头注释

嵌入式技术基础与实践-学习札记(三)_第5张图片

公共要素文件

为某一款芯片编写驱动构件时,不同的构件存在公共使用的内容,将这些内容以构件的形式组织起来,称为构件公共要素。所有底层驱动都包含对构件公共要素的引用。

  1. 芯片寄存器映射文件

    每个底层驱动构件都是以硬件模块的特殊功能寄存器为操作对象,因此,在\(common.h\)文件中包含描述芯片寄存器映射的头文件。

    还需要将内核及芯片相关文件引用到公共要素中。

  2. 移位操作的宏函数

  3. 重定义基本数据类型

    在编写嵌入式时要明确使用变量的字长,因此,需根据具体编译器重新定义嵌入式基本数据类型。有利于软件的移植。

头文件的设计规范

  1. 编码框架

    编写每个构件的头文件时,应使用#ifndef……#define……#endif编码结构,防止对头文件的重复包含。

  2. 使用宏定义

    使用宏定义标识构件中的常量,为常量提供有意义的别名。

    使用宏函数实现构件对外部请求服务的接口映射。

  3. 声明对外接口函数,包含对外接口函数的使用说明

源程序文件设计规范

  1. 只允许一处使用#include包含自身头文件。
  2. 合理设计与实现对外接口函数与内部函数。
  3. 不使用全局变量

你可能感兴趣的:(嵌入式技术基础与实践-学习札记(三))