了解和使用no-OS及平台驱动程序

  作者:Mahesh Phalke(亚德诺半导体 高级软件工程师) 时间:2022-04-11来源:电子产品世界

编者按:快速发展的技术需要软件支持(固件驱动程序和代码示例)来简化设计导入过程。本文介绍如何利用no-OS(无操作系统)驱动程序和平台驱动程序来构建ADI(亚德诺半导体)公司精密模数转换器和数模转换器的应用固件,这些器件在速度、功耗、尺寸和分辨率方面提供高水平的性能。

ADI 公司提供基于no-OS 驱动程序的嵌入式固件示例来支持精密转换器。no-OS驱动程序负责器件配置、转换器数据采集、执行校准等,而基于no-OS 驱动程序的固件示例则便于将数据传输到主机进行显示、存储和进一步处理。

1   no-OS和平台驱动程序简介

顾名思义,no-OS 驱动程序设计用于通用(或无特定)操作系统。该名称还意味着这些驱动程序可以用在没有任何OS 支持的裸机(BareMetal,亦称裸金属主机) 系统上。no-OS 驱动程序旨在为给定精密转换器的数字接口访问提供高API(Application Programming Interface,应用程序接口),如图1 所示。no-OS 驱动程序使用器件的这些API 接口访问、配置、读取、写入数据,而无需知道寄存器地址(存储器映射)及其内容。

no-OS 驱动程序利用平台驱动程序层来支持跨多个硬件/ 软件平台复用相同的no-OS 驱动程序, 使固件高度可移植。平台驱动程序层的使用将no-OS 驱动程序隔绝开来,后者无需知道平台特定接口(如SPI(Serial Peripheral Interface,串行外设接口)、I2C(Inter-Integrated Circuit,集成电路总线)、GPIO(通用输入输出)等)的低级细节,因此no-OS 驱动程序不需要修改就能跨多个平台复用。

371622-fig-01.jpg

图1 精密转换器固件协议栈

2   使用no-OS驱动程序

图2 显示了no-OS 驱动程序的典型代码结构。

1649658487100661.jpg

图2 no-OS驱动程序代码结构

1649658519284245.jpg

图3 器件配置枚举、结构和API

精密转换器的no-OS 驱动程序代码通常包含在两个以C 编程语言编写的源文件中:adxxxx.c 和adxxxx.h,其中xxxx 代表器件名称(例如AD7606、AD7124等)。器件头文件(adxxxx.h) 包含器件特定结构、枚举、寄存器地址和位掩码的公共编程接口,将此文件包含到所需的源文件中便可使用这些公开访问接口。器件源文件(adxxxx.c) 包含接口的实现,用于初始化和移除器件、读/ 写器件寄存器、从器件读取数据、获取/ 设置器件特定参数等。

典型的no-OS驱动程序围绕一组常见功能来构建。

1)器件特定寄存器地址、位掩码宏、器件配置枚举、读/ 写器件特定参数(如过采样、增益、基准电压等)的结构的声明。

2)通过no-OS 驱动程序的器件初始化/ 移除函数以及器件特定的初始化和驱动程序结构与描述符初始化物理器件/ 解除器件初始化。

3)使用器件寄存器读/ 写函数访问器件存储器映射或寄存器详细信息,例如adxxxx_read_register() 或adxxxx_write_register()。

3   no-OS驱动程序代码使用

1)使用器件特定地址、位掩码、参数配置枚举和结构

如前所述,adxxxx.h 头文件包含所有器件特定枚举和结构的声明,这些枚举和结构被传递到器件特定的函数或API 以配置或访问器件参数。具体情况如图3 所示。

图3 中显示的adxxxx_config 结构允许用户选择多路复用器通道并为其设置过采样率。此结构的成员(afe_mux_channel 和oversampling) 是存在于同一头文件中的枚举,其包含这两个字段的所有可能值的数字常量,用户可以选择。

adxxxx.c 文件中定义的adxxxx_set_adc_config() 函数通过配置结构获取用户传递的配置/ 参数,并进一步调用adxxxx_spi_reg_write() 函数,通过数字接口(在上例中是SPI)将数据写入ADXXXX_REG_CONFIG器件寄存器。

2)使用no-OS 驱动程序结构和初始化函数初始化器件

1649658548943854.jpg

图4 器件初始化和驱动程序结构的声明

除了器件配置枚举和结构之外,no-OS 驱动程序还提供以下两个结构:器件初始化结构和设备驱动程序结构。器件初始化结构允许用户在用户应用程序代码中定义器件特定的参数和配置。初始化结构包含其他器件特定的参数结构和枚举的成员。图5 显示了器件初始化结构的定义。

器件驱动程序结构通过器件初始化函数adxxxx_init() 加载器件初始化参数。器件驱动程序结构是在运行时(动态)从堆空间中分配内存。器件驱动程序结构和器件初始化结构中声明的参数几乎完全相同。器件驱动程序结构是器件初始化结构的运行时版本。

以下步骤说明典型的器件初始化函数和初始化流程。

第1 步:在应用程序中创建器件初始化结构的定义(或实例)(例如struct adxxxx_init_params),以初始化用户特定的器件参数和平台相关的驱动程序参数。参数在编译期间定义。

注意:初始化结构中定义的参数因器件而异。

1649658595156754.jpg

第2 步:在应用程序代码中创建器件驱动程序结构的指针实例(变量)。

用户应用程序需要创建器件驱动程序结构的单个指针实例。将此实例传递给所有no-OS 驱动程序API / 函数以访问器件特定参数。应用程序代码中定义的此指针实例指向堆中动态分配的内存,这是通过no-OS 驱动程序中定义的器件初始化函数(如adxxxx_init())完成的。

1649658623376956.jpg

第3 步:调用器件初始化函数以初始化器件和其他平台特定的外设。

1649658655656897.jpg

no-OS 驱动程序中定义的adxxxx_init() 函数用adxxx_init_param结构传递的用户特定参数初始化器件。器件驱动程序结构的指针实例和器件初始化结构的实例作为两个参数传递给此初始化函数。用户应用程序代码可以多次调用adxxxx_init() 函数,只要调用初始化函数之后再调用器件移除函数来平衡。

3)通过器件寄存器读/ 写函数访问存储器映射(寄存器内容)

用户可以通过no-OS 驱动程序器件特定的adxxx_read/write() 函数访问器件寄存器内容(例如产品ID、暂存区值、OSR 等),如图6 所示。

大多数情况下,用户不会直接使用寄存器访问函数。器件特定的函数通过这些寄存器访问函数(如adxxxx_spi_reg_read/write())来调用。如果可能,建议使用器件配置和状态API 来访问器件存储器映射,而不要使用直接寄存器访问函数,因为这样能确保器件驱动程序结构与器件中的配置保持同步。

4   平台驱动程序

平台驱动程序是包装平台特定API 的硬件抽象层(HAL) 之一。它们由no-OS 器件驱动程序或用户应用程序代码调用,使后者可以独立于底层硬件和软件平台。平台驱动程序包装了平台特定的低级硬件功能,例如SPI / I2C 初始化和读/ 写、GPIO 初始化和读/ 写、UART(Universal Asynchronous Receiver/Transmitter,通用异步收发传输器) 初始化和接收/ 发送、用户特定的延迟、中断等。

1649658691300016.jpg

图5 用户应用程序中的器件初始化结构定义

image.png

图6 访问寄存器内容

SPI平台驱动程序模块的典型文件结构如图7所示。

1649654850142408.png

图7 SPI平台驱动程序代码结构

5   使用平台驱动程序

平台驱动程序代码通常包含在以C/C++ 编程语言编写的三个源文件中。

1)spi.h:这是一个与平台无关的文件,包含SPI 功能所需的器件结构和枚举。此头文件中定义的C 编程接口没有平台依赖性。

初始化和器件结构中声明的所有参数对任何平台上的SPI接口都是通用的。器件初始化结构中使用的void *extra 参数允许用户传递额外的参数,这些参数可以是所用平台特定的。SPI 驱动程序结构和SPI 初始化结构中声明的参数几乎完全相同。SPI 驱动程序结构是SPI 初始化结构的运行时版本。

2)spi.cpp/.c:此文件包含spi.h 文件中声明的函数的实现,这些函数用于初始化特定平台的SPI 外设以及读/ 写数据。广义的“平台”是指硬件微控制器(目标器件)和软件(如RTOS 或Mbed-OS)的组合。此文件依赖于平台,移植到其他平台时需要修改。

图9 详细说明了Mbed 平台的SPI 接口,并显示了如何使用这些接口和器件初始化/驱动程序结构来初始化SPI 和读/ 写数据。

1649658794759216.jpg

图8 SPI初始化和驱动程序结构

1649654924669952.png

图9 SPI API或函数注意:增加的spi_init()和spi_write_and_read()代码是节略代码,为清楚起见而省略了细节

1649658754531768.jpg

图10 SPI额外的初始化和驱动程序结构

3)spi_extra.h:此文件包含其他器件结构或枚举,其特定于给定平台。它允许用户应用程序代码提供通用spi.h 文件中未涉及的配置。例如,SPI 引脚可能随平台而异,因此可以作为这些平台特定的额外结构的一部分添加。

6   移植平台驱动程序

平台驱动程序可以从一个平台(微控制器)移植到另一个平台;若要移植,通常需要创建平台特定的.cpp/.c 和_extra.h 文件。平台驱动程序驻留在微控制器单元供应商提供的器件特定硬件抽象层(HAL) 之上的一层。

因此,为将平台驱动程序从一个平台移植到另一个平台,与调用供应商提供的HAL 中存在的函数或API 相关的平台驱动程序代码需要做一些细微改动。

图12 区分了基于Mbed 的SPI 平台驱动程序和ADuCM410 SPI平台驱动程序。ADIno-OS 存储库和平台驱动程序的GitHub 源代码链接可在ADI 公司Wiki 和GitHub 页面上找到。

image.png

图11 Mbed平台特定的SPI初始化实现

image.png

图12 平台驱动程序差异

7   为no-OS驱动程序做贡献

ADI no-OS 驱动程序已开源并托管在GitHub 上。驱动程序不仅支持精密转换器,也支持许多其他ADI 产品,如加速度计、收发器、光电器件等。任何熟悉源代码的人都可以为这些驱动程序做贡献,方式是提交变更和创建拉取请求来审核这些变更。

有许多示例项目可以在Linux 和/ 或Windows 环境中运行。许多示例项目是用硬件描述性语言(HDL) 开发的,以便在Xilinx、Intel 等公司开发的FPGA(FieldProgrammable Gate Array,现场可编程门阵列)以及由不同供应商开发的目标处理器上运行。

(本文来源于必威娱乐平台 杂志2022年3月期)

关键词: ADI 模数转换器 数模转换器 no-OS 202203

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版