移植通用 I/O 库 - FreeRTOS
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

移植通用 I/O 库

通常,设备驱动程序独立于基础操作系统,并且特定于给定的硬件配置。硬件抽象层 (HAL) 是一个包装程序,它提供驱动程序和更高级别的应用程序代码之间的通用接口。HAL 提取出特定驱动程序如何工作的详细信息,并提供一个统一的 API 来控制相似设备。这样一来,您可以使用相同的 API 跨多个基于微控制器 (MCU) 的参考板来控制各种设备。

FreeRTOS 通用 I/O 将充当硬件抽象层。它提供了一组标准 API,用于跨受支持的参考板访问常用串行设备。这些 API 与一些常见的外围设备进行通信和交互,可让您的应用程序代码跨平台运行。如果没有通用 I/O,则使用低级设备所需的代码是特定于芯片供应商的。

支持的外围设备

  • UART

  • SPI

  • I2C

支持的功能

  • 同步读/写 – 此函数直到传输了请求的数据量后才返回。

  • 异步读/写 – 此函数立即返回,并且数据以异步方式传输。在函数执行完成后,将调用已注册用户回调。

外围设备特定的

  • I2C – 将多个操作合并到一个事务中,通常会在一个事务中依次执行写入操作和读取操作。

  • SPI – 在主设备和辅助设备之间传输数据,这意味着写入操作和读取操作将同时进行。

移植

请参阅 FreeRTOS 移植指南

先决条件

要移植常用 I/O 库,您需要:

  • 一个包括供应商提供的 I/O 驱动程序的 IDE 项目或 CMakeLists.txt 列表文件。

  • 一个 FreeRTOS 内核的经验证配置。

测试

首先,请设置 IDE 项目或配置 CMake。

设置本地测试环境

无需对测试文件 /libraries/abstractions/common_io/test/test_iot_peripheral.c 进行更改。

特定于设备的代码位于以下文件中

  • /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h

  • /vendors/vendor/boards/board/ports/common_io/test_iot_internal.c

设置本地测试环境

  1. 创建一个名为 /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h 的测试配置标头文件。有关该文件的内容,请参阅每个外围设备的“Test Setup”部分。

  2. 创建一个名为 /vendors/vendor/boards/board/ports/common_io/test_iot_internal.c 的测试设置文件。有关该文件的内容,请参阅每个外围设备的“测试设置”部分。

  3. 要启用通用 I/O 测试,请打开文件 /vendors/vendor/boards/board/aws_tests/config_files/aws_test_runner_config.h

  4. testrunnerFULL_COMMON_IO_ENABLED 设置为 1

设置 IDE 测试项目

如果使用 IDE 进行移植和测试,您必须先将源文件添加到 IDE 测试项目中,然后才能测试移植的代码。

重要

在以下步骤中,请确保您将源文件从当前的磁盘上位置添加到 IDE 项目中。请勿创建源文件的重复副本。

在 IDE 项目中设置通用 I/O 库

  1. 将所有实施源文件 /vendors/vendor/boards/board/ports/common_io/iot_peripheral.c 添加到 aws_tests IDE 项目中(每个外围设备一个文件)。

  2. 将所有测试源文件 /libraries/abstractions/common_io/test/test_iot_peripheral.c 添加到 aws_tests IDE 项目中(每个外围设备一个文件)。

  3. 将测试配置文件 /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h 添加到 aws_tests IDE 项目中(对于所有外围设备,仅添加这一个文件)。

  4. 将测试设置文件 /vendors/vendor/boards/board/ports/common_io/test_iot_internal.c 添加到 aws_tests IDE 项目中(对于所有外围设备,仅添加这一个文件)。

配置 CMakeLists.txt 文件

如果使用 CMake 构建测试项目,您必须在 CMake 列表文件中为库定义一个可移植层目标。

/vendors/vendor/boards/board/CMakeLists.txt 中的 CMakeLists.txt 模板列表文件包括可移植层目标定义示例。取消注释每个要移植的库的定义,并对其进行修改以适合您的平台。

以下是通用 I/O 库的可移植层目标定义。

# Common I/O afr_mcu_port(common_io) target_sources( AFR::common_io::mcu_port INTERFACE # peripheral implementations /vendors/vendor/boards/board/ports/common_io/iot_peripheral_1.c /vendors/vendor/boards/board/ports/common_io/iot_peripheral_2.c /vendors/vendor/boards/board/ports/common_io/iot_peripheral_3.c ... # test configuration and pre-steps /vendors/vendor/boards/board/ports/common_io/test_iot_internal.c ) # ------------------------------------------------------------------------------------------------- # FreeRTOS demos and tests # ------------------------------------------------------------------------------------------------- ... if(AFR_IS_TESTING) set(exe_target aws_tests) else() set(exe_target aws_demos) endif() ... # link common io library along with others target_link_libraries( ${exe_target} PRIVATE AFR::wifi AFR::utils AFR::common_io )

运行测试

执行通用 I/O 测试

  1. 构建测试项目,然后将其刷写到您的设备以执行该项目。

  2. 在 UART 控制台中检查测试结果。

移植 I2C 库

I2C 库与供应商提供的 I2C 驱动程序进行交互。如果设备没有 I2C 外围设备,则可以跳过移植 I2C 接口这一步。I2C 库只能将设备上的 I2C 外围设备用作主设备。

先决条件

要移植 I2C 库,您需要 I2C 辅助设备。它可以是下列项之一:

  • 一个板载 I2C 传感器。

  • 一个外部设备,如 Raspberry PI。

移植

使用供应商提供的 I2C 驱动程序库实施 /libraries/abstractions/common_io/include/iot_i2c.h 中的所有函数。标头文件提供了所需的 API 行为信息。应创建一个实施源文件并将其命名为 /vendors/vendor/boards/board/ports/common_io/iot_i2c.c

如果任何 I2C 功能在目标设备上均不受支持,请让相应的函数返回 IOT_I2C_FUNCTION_NOT_SUPPORTED。有关可返回 IOT_I2C_FUNCTION_NOT_SUPPORTED 的函数的列表,请参阅 /libraries/abstractions/common_io/include/iot_i2c.h 中记录的 API。

匿名句柄“struct IotI2CDescriptor”

这通常将封装驱动程序的句柄和各种状态。请参见以下示例。

/* Suppose the data type of driver handle for I2C is Driver_I2C_Handle */ struct IotI2CDescriptor { Driver_I2C_Handle xHandle; /* Driver Handle. */ IotI2CConfig_t xConfig; /* Bus Configuration. */ IotI2CCallback_t xCallback; /* Callback function. */ void * pvUserContext; /* User context passed in callback. */ uint16_t usSlaveAddr; /* Slave Address. */ uint16_t usTransmittedTxBytes; /* Number of Transmitted Bytes */ uint16_t usReceivedRxBytes; /* Number of Received Bytes */ SemaphoreHandle_t xSemphr; /* Optional, useful when there is a synchronization situation. */ /* State: if already opened. */ /* State: if send no stop. */ };

测试设置

硬件设置

如果您使用板载传感器作为从属设备,则可跳过此步骤。

如果您使用外部设备,则需要连接两个设备的 SDA(数据)线和 SCL(时钟)线。

可以在以下目录中找到 I2C 测试文件:/libraries/abstractions/common_io/test/test_iot_i2c.c

测试设置配置

  1. 将 I2C 配置添加到 /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h

    IOT_TEST_COMMON_IO_I2C_SUPPORTED

    如果此设备具有 I2C 外围设备,则设置为 1。否则,将它设置为 0

    IOT_TEST_COMMON_IO_I2C_SUPPORTED_SEND_NO_STOP

    如果 I2C 未明确支持发送停止条件,则设置为 1。否则,设置为 0

    IOT_TEST_COMMON_IO_I2C_SUPPORTED_CANCEL

    如果 I2C 支持通过中断或 DMA 取消异步事务,则设置为 1。否则,设置为 0

    I2C_TEST_SET

    指定要测试的 I2C 实例的数目。

  2. /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h 文件中定义测试数据。

    i2cTestInstanceIdx

    I2C 实例 ID。

    i2cTestInstanceNum

    I2C 实例总数。

    i2cTestSlaveAddr

    设备地址。

    i2cTestDeviceRegister

    在测试设备上注册地址。

    i2cTestWriteVal

    要写入测试设备的字节值。

    gIotI2cHandle

    未使用。将它定义为要编译的 null 数组。

    /* I2C includes */ #include "iot_i2c.h" #define IOT_TEST_COMMON_IO_I2C_SUPPORTED 1 #if ( IOT_TEST_COMMON_IO_I2C_SUPPORTED == 1 ) #define IOT_TEST_COMMON_IO_I2C_SUPPORTED_SEND_NO_STOP 1 #define IOT_TEST_COMMON_IO_I2C_SUPPORTED_CANCEL 1 #endif #define I2C_TEST_SET 1 /* Slave address. */ const uint8_t i2cTestSlaveAddr[ I2C_TEST_SET ] = { 0xD4 }; /* Register address. */ const uint8_t i2cTestDeviceRegister[ I2C_TEST_SET ] = { 0x73 }; /* A value that is written to slave device during test. */ const uint8_t i2cTestWriteVal[ I2C_TEST_SET ] = { 0b01101010 }; /* I2C instance ID. */ const uint8_t i2cTestInstanceIdx[ I2C_TEST_SET ] = { 1 }; /* Total number of I2C instances. */ const uint8_t i2cTestInstanceNum[ I2C_TEST_SET ] = { 3 }; /* Unused, but this needs to be defined. */ IotI2CHandle_t gIotI2cHandle[ 4 ] = { NULL, NULL, NULL, NULL };
  3. 将 I2C 测试设置代码添加到 /vendors/vendor/boards/board/ports/common_io/test_iot_internal.c 文件中。

    #include "test_iot_internal.h" /* These global variables are defined in test_iot_i2c.c. */ extern uint8_t uctestIotI2CSlaveAddr; extern uint8_t xtestIotI2CDeviceRegister; extern uint8_t uctestIotI2CWriteVal; extern uint8_t uctestIotI2CInstanceIdx; extern uint8_t uctestIotI2CInstanceNum; void SET_TEST_IOT_I2C_CONFIG(int testSet) { uctestIotI2CSlaveAddr = i2cTestSlaveAddr[testSet]; xtestIotI2CDeviceRegister = i2cTestDeviceRegister[testSet]; uctestIotI2CWriteVal = i2cTestWriteVal[testSet]; uctestIotI2CInstanceIdx = i2cTestInstanceIdx[testSet]; uctestIotI2CInstanceNum = i2cTestInstanceNum[testSet]; }

移植 UART 库

UART 库与供应商提供的 UART 驱动程序进行交互。如果设备没有任何 UART 外围设备,则可以跳过移植 UART 接口这一步。

先决条件

  • 使用跳线连接 UART 的 RX 和 TX 以进行环回测试。

移植

使用供应商提供的 UART 驱动程序库实施 /libraries/abstractions/common_io/include/iot_uart.h 中的所有函数。标头文件提供了有关所需的 API 行为的信息。应创建一个实施源文件并将其命名为 /vendors/vendor/boards/board/ports/common_io/iot_uart.c

如果目标设备不支持任何 UART 功能,请让相应的函数放回 IOT_UART_FUNCTION_NOT_SUPPORTED。有关可返回 IOT_UART_FUNCTION_NOT_SUPPORTED 的函数的列表,请参阅 /libraries/abstractions/common_io/include/iot_uart.h 中记录的 API。

匿名句柄“struct IotUARTDescriptor”

这通常将封装驱动程序的句柄和各种状态。请参见以下示例。

/* Suppose the data type of the driver handle for UART is UART_Handle */ struct IotUARTDescriptor { IotUARTCallback_t xUartCallback; /* Application Specified callback. */ UART_Handle * pxUartContext; /* UART handle to be passed to driver functions. */ void * pvUserCallbackContext; / uint8_t sOpened; };

测试设置

硬件设置

在要测试的 UART 端口上,使用跳线连接 TX 和 RX 来进行环回测试。

可以在以下目录中找到 UART 测试文件:/libraries/abstractions/common_io/test/test_iot_uart.c

测试设置配置

  1. 将 UART 配置添加到 /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h 文件中。

    IOT_TEST_COMMON_IO_UART_SUPPORTED

    如果此设备具有 UART 外围设备,则设置为 1。否则,设置为 0

    UART_TEST_SET

    要测试的 UART 实例的数目。

  2. /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h 文件中定义测试数据。

    uartTestPort

    UART 实例 ID。

    uartIotUartFlowControl

    UART 流控制配置。

    uartIotUartParity

    UART 奇偶校验位配置。

    uartIotUartWordLength

    UART 字长配置。

    uartIotUartStopBits

    UART 停止位配置。

    /* UART */ #define UART_TEST_SET 1 const uint8_t uartTestPort[ UART_TEST_SET ] = { 1 }; const uint32_t uartIotUartFlowControl[ UART_TEST_SET ] = { UART_FLOW_CONTROL }; const uint32_t uartIotUartParity[ UART_TEST_SET ] = { UART_PARITY }; const uint32_t uartIotUartWordLength[ UART_TEST_SET ] = { UART_WORD_LENGTH }; const uint32_t uartIotUartStopBits[ UART_TEST_SET ] = { UART_STOP_BITS };
  3. 将 UART 测试设置代码添加到 /vendors/vendor/boards/board/ports/common_io/test_iot_internal.c 文件中。

    #include "test_iot_internal.h" /* UART */ extern uint8_t ustestIotUartPort; extern uint32_t ultestIotUartFlowControl; extern uint32_t ultestIotUartParity; extern uint32_t ultestIotUartWordLength; extern uint32_t ultestIotUartStopBits; void SET_TEST_IOT_UART_CONFIG( int testSet ) { ustestIotUartPort = uartTestPort[ testSet ]; ultestIotUartFlowControl = uartIotUartFlowControl[ testSet ]; ultestIotUartParity = uartIotUartParity[ testSet ]; ultestIotUartWordLength = uartIotUartWordLength[ testSet ]; ultestIotUartStopBits = uartIotUartStopBits[ testSet ]; }

移植 SPI 库

SPI 库与供应商提供的 SPI 驱动程序进行交互。如果设备没有 SPI 外围设备,则可以跳过移植 SPI 接口这一步。SPI 库只能将设备上的 SPI 外围设备用作主设备。

移植

使用供应商提供的 SPI 驱动程序库实施 /libraries/abstractions/common_io/include/iot_spi.h 中的所有函数。标头文件提供了所需的 API 行为信息。应将实施源文件创建为 /vendors/vendor/boards/board/ports/common_io/iot_spi.c

目标设备可能不支持一些 SPI 功能。在此情况下,让相应的函数返回 IOT_SPI_FUNCTION_NOT_SUPPORTED。有关可返回 IOT_SPI_FUNCTION_NOT_SUPPORTED 的函数的列表,请参阅 /libraries/abstractions/common_io/include/iot_spi.h 中记录的 API。

匿名句柄“struct IotSPIDescriptor”

这通常将封装驱动程序的句柄和各种状态。请参见以下示例。

/* Suppose the data type of driver handle for SPI is Driver_SPI_Handle */ struct IotSPIDescriptor { Driver_SPI_Handle xHandle; /* Driver Handle. */ IotSPIConfig_t xConfig; /* Bus Configuration. */ IotSPICallback_t xCallback; /* Callback function. */ void * pvUserContext; /* User context passed in callback. */ /* State: if already opened. */ };

测试设置

可以在以下目录中找到 SPI 测试文件:/libraries/abstractions/common_io/test/test_iot_spi.c

测试设置配置

  1. 将 SPI 配置添加到 /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h 文件中。

    IOT_TEST_COMMON_IO_SPI_SUPPORTED

    如果设备具有 SPI 外围设备,则将它设置为 1。否则,设置为 0

    SPI_TEST_SET

    要测试的 SPI 实例的数目。

  2. /vendors/vendor/boards/board/aws_tests/config_files/test_iot_config.h 文件中定义测试数据。

    spiTestPort

    SPI 实例 ID。

    spiIotMode

    SPI 模式。

    spiIotSpitBitOrder

    SPI 位顺序。

    spiIotFrequency

    SPI 频率。

    spiIotDummyValue

    虚拟值。

    /* SPI includes */ #include "iot_spi.h" #define IOT_TEST_COMMON_IO_SPI_SUPPORTED 1 #define I2C_TEST_SET 1 const uint8_t spiTestPort[ SPI_TEST_SET ] = { 1 }; const uint32_t spiIotMode[ SPI_TEST_SET ] = { eSPIMode0 }; const uint32_t spiIotSpitBitOrder[ SPI_TEST_SET ] = { eSPIMSBFirst }; const uint32_t spiIotFrequency[ SPI_TEST_SET ] = { 500000U }; const uint32_t spiIotDummyValue[ SPI_TEST_SET ] = { 0 };
  3. /vendors/vendor/boards/board/ports/common_io/test_iot_internal.c 文件中添加 SPI 测试设置代码。

    #include "test_iot_internal.h" /* SPI */ extern uint8_t ultestIotSpiInstance; extern IotSPIMode_t xtestIotSPIDefaultConfigMode; extern IotSPIBitOrder_t xtestIotSPIDefaultconfigBitOrder; extern uint32_t ultestIotSPIFrequency; extern uint32_t ultestIotSPIDummyValue; void SET_TEST_IOT_SPI_CONFIG(int testSet) { ultestIotSpiInstance = spiTestPort[ testSet ] ; xtestIotSPIDefaultConfigMode = spiIotMode[ testSet ]; xtestIotSPIDefaultconfigBitOrder = spiIotSpitBitOrder[ testSet ]; ultestIotSPIFrequency = spiIotFrequency[ testSet ]; ultestIotSPIDummyValue = spiIotDummyValue[ testSet ]; }