对于不同底层驱动的uart操作实现,统一封装成本文所述uart hal接口。 hal相关头文件位于目录:include/aos/hal。hal相关实现位于具体的mcu目录下,如:platform/mcu/stm32f1xx/hal/ 注意:另系统启动后printf输出对接时,一般都使用了一个uart串口,实际使用时需要注意避免冲突。参见: utility/libc/newlib_stub.c 中_write_r实现

API列表

hal_uart_init 初始化指定UART
hal_uart_send 从指定的UART发送数据
hal_uart_recv 从指定的UART接收数据
hal_uart_recv_II 从指定的UART中断方式接收数据
hal_uart_finalize 关闭指定UART

API详情

请参考include/aos/hal/uart.h

相关结数据结构

uart_dev_t

typedef struct {
    uint8_t        port;   /**< uart port */
    uart_config_t  config; /**< uart config */
    void          *priv;   /**< priv data */
} uart_dev_t;

uart_config_t

typedef struct {
    uint32_t                baud_rate;      /**< Uart baud rate */
    hal_uart_data_width_t   data_width;     /**< Uart data width */
    hal_uart_parity_t       parity;         /**< Uart parity check mode */
    hal_uart_stop_bits_t    stop_bits;      /**< Uart stop bit mode */
    hal_uart_flow_control_t flow_control;   /**< Uart flow control mode */
    hal_uart_mode_t         mode;           /**< Uart send/receive mode */
} uart_config_t;

hal_uart_data_width_t

typedef enum {
    DATA_WIDTH_5BIT,
    DATA_WIDTH_6BIT,
    DATA_WIDTH_7BIT,
    DATA_WIDTH_8BIT,
    DATA_WIDTH_9BIT
} hal_uart_data_width_t;

hal_uart_parity_t

typedef enum {
    NO_PARITY,      /**< No parity check */
    ODD_PARITY,     /**< Odd parity check */
    EVEN_PARITY     /**< Even parity check */
} hal_uart_parity_t;

hal_uart_stop_bits_t

typedef enum {
    STOP_BITS_1,
    STOP_BITS_2
} hal_uart_stop_bits_t;

hal_uart_flow_control_t

typedef enum {
    FLOW_CONTROL_DISABLED,  /**< Flow control disabled */
    FLOW_CONTROL_CTS,       /**< Clear to send, yet to send data */
    FLOW_CONTROL_RTS,       /**< Require to send, yet to receive data */
    FLOW_CONTROL_CTS_RTS    /**< Both CTS and RTS flow control */
} hal_uart_flow_control_t;

hal_uart_mode_t

typedef enum {
    MODE_TX,        /**< Uart in send mode */
    MODE_RX,        /**< Uart in receive mode */
    MODE_TX_RX      /**< Uart in send and receive mode */
} hal_uart_mode_t;

hal_uart_init

初始化指定UART

函数原型

int32_t hal_uart_init(uart_dev_t *uart)

参数

uart_dev_t *uart 入参 UART设备描述,定义需要初始化的UART参数 用户自定义一个uart_dev_t结构体

返回值

返回成功或失败, 返回0表示UART初始化成功,非0表示失败

调用示例

/* define dev */
#define UART1_PORT_NUM  1
uart_dev_t uart1;
/* uart port set */
uart1.port = UART1_PORT_NUM;
/* uart attr config */
uart1.config.baud_rate    = 115200;
uart1.config.data_width   = DATA_WIDTH_8BIT;
uart1.config.parity       = NO_PARITY;
uart1.config.stop_bits    = STOP_BITS_1;
uart1.config.flow_control = FLOW_CONTROL_DISABLED;
uart1.config.mode         = MODE_TX_RX;
ret = hal_uart_init(&uart1);

hal_uart_send

从指定的UART发送数据

函数原型

int32_t hal_uart_send(uart_dev_t *uart, const void *data, uint32_t size, uint32_t timeout)

参数

uart_dev_t *uart 入参 UART设备描述句柄 使用hal_uart_init传入值
const void *data 入参 指向要发送数据的数据指针 char pdata[10]
uint32_t size 入参 要发送的数据字节数 10
uint32_t timeout 入参 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER 50

返回值

返回成功或失败, 返回0表示UART数据发送成功,非0表示失败

调用示例

#define UART_BUF_SIZE   10
#define UART_TX_TIMEOUT 50
char uart_data_buf[UART_BUF_SIZE] = {0};
ret = hal_uart_send(&uart1, uart_data_buf, UART_BUF_SIZE, UART_TX_TIMEOUT);

hal_uart_recv

从指定的UART接收数据,一般是阻塞等待数据接收

函数原型

int32_t hal_uart_recv(uart_dev_t *uart, void *data, uint32_t expect_size,uint32_t timeout)

参数

uart_dev_t *uart 入参 UART设备描述句柄 使用hal_uart_init传入值
void *data 入参 指向接收缓冲区的数据指针 char pdata[10]
uint32_t expect_size 入参 期望接收的数据字节数 10
uint32_t timeout 入参 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER 50

返回值

返回成功或失败, 返回0表示成功接收expect_size个数据,非0表示失败

调用示例

#define UART_BUF_SIZE   10
char uart_data_buf[UART_BUF_SIZE] = {0};
ret = hal_uart_recv(&uart1, uart_data_buf, UART_BUF_SIZE, HAL_WAIT_FOREVER);

hal_uart_recv_II

从指定的UART中断方式接收数据,与hal_uart_recv不同的是,其不需要阻塞等待消息;中断触发后会自动唤醒其继续处理字符信息。

函数原型

int32_t hal_uart_recv_II(uart_dev_t *uart, void *data, uint32_t expect_size,uint32_t *recv_size, uint32_t timeout)

参数

uart_dev_t *uart 入参 UART设备描述句柄 使用hal_uart_init传入值
void *data 入参 指向接收缓冲区的数据指针 char pdata[10]
uint32_t expect_size 入参 期望接收的数据字节数 10
uint32_t *recv_size 出参 实际接收数据字节数 用户自定义int类型,传入地址
uint32_t timeout 入参 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER 50

返回值

返回成功或失败, 返回0表示成功接收expect_size个数据,非0表示失败

调用示例

#define UART_BUF_SIZE   10
uint32_t plen = 0;
char uart_data_buf[UART_BUF_SIZE] = {0};
ret = hal_uart_recv_II(&uart1, uart_data_buf, UART_BUF_SIZE,&plen, HAL_WAIT_FOREVER);

hal_uart_finalize

关闭指定UART

函数原型

int32_t hal_uart_finalize(uart_dev_t *uart)

参数

uart_dev_t *uart 入参 UART设备描述句柄 使用hal_uart_init传入值

返回值

类型:int 返回成功或失败, 返回0表示UART关闭成功,非0表示失败。

调用示例

ret = hal_uart_finalize(&uart1);

使用

添加该组件

在相应的platform/mcu的mk内,添加对应hal文件的编译包含。

包含头文件

#include "aos/hal/uart.h"

使用示例

#include <aos/hal/uart.h>

#define UART1_PORT_NUM  1
#define UART_BUF_SIZE   10
#define UART_TX_TIMEOUT 10
#define UART_RX_TIMEOUT 10

/* define dev */
uart_dev_t uart1;

/* data buffer */
char uart_data_buf[UART_BUF_SIZE];

int application_start(int argc, char *argv[])
{
    int count   = 0;
    int ret     = -1;
    int i       = 0;
    int rx_size = 0;

    /* uart port set */
    uart1.port = UART1_PORT_NUM;

    /* uart attr config */
    uart1.config.baud_rate    = 115200;
    uart1.config.data_width   = DATA_WIDTH_8BIT;
    uart1.config.parity       = NO_PARITY;
    uart1.config.stop_bits    = STOP_BITS_1;
    uart1.config.flow_control = FLOW_CONTROL_DISABLED;
    uart1.config.mode         = MODE_TX_RX;

    /* init uart1 with the given settings */
    ret = hal_uart_init(&uart1);
    if (ret != 0) {
        printf("uart1 init error !\n");
    }

    /* init the tx buffer */
    for (i = 0; i < UART_BUF_SIZE; i++) {
        uart_data_buf[i] = i + 1;
    }

    /* send 0,1,2,3,4,5,6,7,8,9 by uart1 */
    ret = hal_uart_send(&uart1, uart_data_buf, UART_BUF_SIZE, UART_TX_TIMEOUT);
    if (ret == 0) {
        printf("uart1 data send succeed !\n");
    }

    /* scan uart1 every 100ms, if data received send it back */
    while(1) {
        ret = hal_uart_recv_II(&uart1, uart_data_buf, UART_BUF_SIZE,
                               &rx_size, UART_RX_TIMEOUT);
        if ((ret == 0) && (rx_size == UART_BUF_SIZE)) {
            printf("uart1 data received succeed !\n");

            ret = hal_uart_send(&uart1, uart_data_buf, rx_size, UART_TX_TIMEOUT);
            if (ret == 0) {
                printf("uart1 data send succeed !\n");
            }
        }

        /* sleep 100ms */
        aos_msleep(100);
    };
}

注:port为逻辑端口号,其与物理端口号的对应关系见具体的对接实现

移植说明

新建hal_uart_xxmcu.c和hal_uart_xxmcu.h的文件,并将这两个文件放到platform/mcu/xxmcu/hal目录下。在hal_uart_xxmcu.c中实现所需要的hal函数,hal_uart_xxmcu.h中放置相关宏定义。 参考platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_uart_stm32l4.c