7.11.5. 源码说明¶
7.11.5.1. 信息配置¶
SDK 中 UART 的配置信息包括
SOC 配置: Kconfig.chip
开发板配置:Kconfig.board
Pimux配置:pinmux.c
设备配置:Kconfig.dev
7.11.5.1.1. SOC 配置¶
SOC 的 UART 模块的基础信息配置在 bsp/artinchip/sys/soc name/Kconfig.chip 中设置
驱动版本信息
UART 数目信息
config AIC_UART_DRV
bool
default n
config AIC_UART_DRV_V10
bool
default y if AIC_UART_DRV
config AIC_UART_DRV_VER
string
default "10" if AIC_UART_DRV_V10
config AIC_UART_DEV_NUM
int
default 8 if AIC_UART_DRV
7.11.5.1.2. 开发板配置¶
在 target/soc name/board name/Kconfig.board 中完成某一开发板中 UART 的相关信息设置, 一般会配置需要的 UART 端口
config AIC_USING_UART0
bool "Using uart0"
default n
select AIC_UART_DRV
config AIC_USING_UART1
bool "Using uart1"
default n
select AIC_UART_DRV
7.11.5.1.3. Pinmux¶
在 target/soc name/board name/pinmux.c 中配置 UART 端口的 pinmux
struct aic_pinmux aic_pinmux_config[] = {
...
#ifdef AIC_USING_UART0
/* uart0 */
{5, PIN_PULL_DIS, 3, "PA.0"},
{5, PIN_PULL_DIS, 3, "PA.1"},
#endif
7.11.5.1.4. 设备配置¶
在 bsp/artinchip/drv/uart/Kconfig.dev 中设置设备的工作参数
clock
baudrate
data bites
stop bits
parity
function
config AIC_DEV_UART0_BAUDRATE
int "uart0 baudrate"
default 115200
config AIC_DEV_UART0_DATABITS
int "uart0 data bits"
range 0 15
default 8
config AIC_DEV_UART0_STOPBITS
int "uart0 stop bits"
range 0 3
default 1
7.11.5.2. 源码说明¶
UART 的功能通过三层包装实现: - HAL 层: bsp/artinchip/hal/uart/aic_hal_uart.c - 驱动层: bsp/artinchip/drv/uart/aic_drv_uart.c - 应用层: kernel/rt-thread/components/drivers/serial/serial.c
7.11.5.2.1. HAL 层¶
HAL 层主要完成对寄存的操作,对基础功能块的封装
7.11.5.2.1.1. 寄存器¶
代码中通过一个数据结构来完整的保存寄存器的数据,对数据结构变量的操作将直接操作到对寄存器
typedef struct
{
union
{
__IM uint32_t RBR; /* Offset: 0x000 (R/ ) Receive buffer register */
__OM uint32_t THR; /* Offset: 0x000 ( /W) Transmission hold register */
__IOM uint32_t DLL; /* Offset: 0x000 (R/W) Clock frequency division low section register */
};
union
{
__IOM uint32_t DLH; /* Offset: 0x004 (R/W) Clock frequency division high section register */
__IOM uint32_t IER; /* Offset: 0x004 (R/W) Interrupt enable register */
};
union
{
__IM uint32_t IIR; /* Offset: 0x008 (R/ ) Interrupt indicia register */
__IOM uint32_t FCR; /* Offset: 0x008 (W) FIFO control register */
};
__IOM uint32_t LCR; /* Offset: 0x00C (R/W) Transmission control register */
__IOM uint32_t MCR; /* Offset: 0x010 (R/W) Modem Control register */
__IM uint32_t LSR; /* Offset: 0x014 (R/ ) Transmission state register */
__IM uint32_t MSR; /* Offset: 0x018 (R/ ) Modem state register */
uint32_t RESERVED1[24]; /**/
__IM uint32_t USR; /* Offset: 0x07c (R/ ) UART state register */
} aic_usart_reg_t;
7.11.5.2.1.2. 扩展寄存器¶
扩展寄存器是 ArtInChip 的特殊寄存器,从 0XB8 地址开始,采用和寄存一样的使用方式
typedef struct
{
__IOM uint32_t RS485DE; /* Offset: 0x0B8 (R/W ) RS485 DE Time register*/
uint32_t RESERVED0;
__IOM uint32_t RS485CTL; /* Offset: 0x0C0 (R/W ) RS485 Control and Status register*/
__IOM uint32_t RS485AM; /* Offset: 0x0C4 (R/W ) RS485 Address Match register*/
__IOM uint32_t RS485BIC; /* Offset: 0x0C8 (R/W ) RS485 Bus Idle Check register*/
} aic_usart_exreg_t;
7.11.5.2.1.3. 接口设计¶
7.11.5.2.1.3.1. hal_usart_initialize¶
函数原型 |
static int hal_usart_initialize(int32_t idx, usart_event_cb_t cb_event, void *handler) |
---|---|
功能说明 |
初始化 uart 端口 |
参数定义 |
index - uart 端口号
cb_event - event call back
handler - 生成的工作句柄
|
返回值 |
0,成功; < 0,失败 |
注意事项 |
7.11.5.2.1.3.2. hal_usart_uninitialize¶
函数原型 |
int hal_usart_uninitialize(void *handler) |
---|---|
功能说明 |
关闭 uart 端口 |
参数定义 |
handler - uart 句柄
cb_event - event call back
handler - 生产的工作句柄
|
返回值 |
0,成功; < 0,失败 |
注意事项 |
7.11.5.2.1.3.3. hal_usart_config¶
函数原型 |
int hal_usart_config(usart_handle_t handle, ……) |
---|---|
功能说明 |
配置 uart 的工作参数 |
参数定义 |
handle - uart 句柄
baud - 波特率
mode - 工作模式,同步还是异步
parity - 极性
stopbits - 停止位
bits - 数据位
func - 功能,RS232,RF485等
|
返回值 |
0,成功; < 0,失败 |
注意事项 |
7.11.5.2.1.3.4. hal_usart_send¶
函数原型 |
int32_t al_usart_send(usart_handle_t handle, const void *data, uint32_t num) |
---|---|
功能说明 |
发送数据 |
参数定义 |
handle - uart 句柄
data - 待发送数据
num - 数据长度
|
返回值 |
0,成功; < 0,失败 |
注意事项 |
7.11.5.2.1.3.5. hal_usart_receive¶
函数原型 |
int32_t hal_usart_receive(usart_handle_t handle, void *data, uint32_t num) |
---|---|
功能说明 |
接收数据 |
参数定义 |
handle - uart 句柄
data - 接收数据buffer
num - 要接收的数据长度
|
返回值 |
0,成功; < 0,失败 |
注意事项 |
7.11.5.2.1.3.6. hal_usart_receive_query¶
函数原型 |
int32_t hal_usart_receive_query(usart_handle_t handle, void *data, uint32_t num) |
---|---|
功能说明 |
查询要接收的数据的长度 |
参数定义 |
handle - uart 句柄
data - 接收数据buffer
num - buffer的大小
|
返回值 |
长度 |
注意事项 |
7.11.5.2.1.3.7. hal_usart_get_status¶
函数原型 |
usart_status_t hal_usart_get_status(usart_handle_t handle) |
---|---|
功能说明 |
获取 uart 的状态 |
参数定义 |
handle - uart 句柄 |
返回值 |
状态值 |
注意事项 |
7.11.5.2.1.3.8. hal_usart_flush¶
函数原型 |
int32_t hal_usart_flush(usart_handle_t handle, usart_flush_type_e type) |
---|---|
功能说明 |
flush 发送或接收的数据 |
参数定义 |
handle - uart 句柄
type - 发送或者接收
|
返回值 |
0,成功; < 0,失败 |
注意事项 |
- int32_t hal_usart_config_flowctrl(usart_handle_t handle,
usart_flowctrl_type_e flowctrl_type)
7.11.5.2.1.3.9. hal_usart_config_flowctrl¶
函数原型 |
int32_t hal_usart_config_flowctrl(usart_handle_t handle, usart_flowctrl_type_e flowctrl_type) |
---|---|
功能说明 |
配置 uart 的流控 |
参数定义 |
handle - uart 句柄
flowctrl_type - 流控类型
|
返回值 |
0,成功; < 0,失败 |
注意事项 |
7.11.5.2.2. 驱动层¶
驱动层通过调用 HAL 层的接口,完成对 UART 设备的驱动实现, 代码在 bsp/artinchip/drv/uart/aic_drv_uart.c
7.11.5.2.2.1. 驱动参数¶
驱动的参数配置通过在 Kconfig 中的宏来初始化
struct drv_uart_dev_para
{
uint32_t index :4;
uint32_t data_bits :4;
uint32_t stop_bits :2;
uint32_t parity :2;
uint32_t baud_rate;
uint32_t clk_freq;
uint32_t function;
char * name;
};
const struct drv_uart_dev_para uart_dev_paras[] =
{
#ifdef AIC_USING_UART0
{0, AIC_DEV_UART0_DATABITS, AIC_DEV_UART0_STOPBITS, AIC_DEV_UART0_PARITY, AIC_DEV_UART0_BAUDRATE, AIC_CLK_UART0_FREQ, AIC_DEV_UART0_MODE, "uart0"},
#endif
#ifdef AIC_USING_UART1
{1, AIC_DEV_UART1_DATABITS, AIC_DEV_UART1_STOPBITS, AIC_DEV_UART1_PARITY, AIC_DEV_UART1_BAUDRATE, AIC_CLK_UART1_FREQ, AIC_DEV_UART1_MODE, "uart1"},
#endif
#ifdef AIC_USING_UART2
{2, AIC_DEV_UART2_DATABITS, AIC_DEV_UART2_STOPBITS, AIC_DEV_UART2_PARITY, AIC_DEV_UART2_BAUDRATE, AIC_CLK_UART2_FREQ, AIC_DEV_UART2_MODE, "uart2"},
#endif
#ifdef AIC_USING_UART3
{3, AIC_DEV_UART3_DATABITS, AIC_DEV_UART3_STOPBITS, AIC_DEV_UART3_PARITY, AIC_DEV_UART3_BAUDRATE, AIC_CLK_UART3_FREQ, AIC_DEV_UART3_MODE, "uart3"},
#endif
#ifdef AIC_USING_UART4
{4, AIC_DEV_UART4_DATABITS, AIC_DEV_UART4_STOPBITS, AIC_DEV_UART4_PARITY, AIC_DEV_UART4_BAUDRATE, AIC_CLK_UART4_FREQ, AIC_DEV_UART4_MODE, "uart4"},
#endif
#ifdef AIC_USING_UART5
{5, AIC_DEV_UART5_DATABITS, AIC_DEV_UART5_STOPBITS, AIC_DEV_UART5_PARITY, AIC_DEV_UART5_BAUDRATE, AIC_CLK_UART5_FREQ, AIC_DEV_UART5_MODE, "uart5"},
#endif
#ifdef AIC_USING_UART6
{6, AIC_DEV_UART6_DATABITS, AIC_DEV_UART6_STOPBITS, AIC_DEV_UART6_PARITY, AIC_DEV_UART6_BAUDRATE, AIC_CLK_UART6_FREQ, AIC_DEV_UART6_MODE, "uart6"},
#endif
#ifdef AIC_USING_UART7
{7, AIC_DEV_UART7_DATABITS, AIC_DEV_UART7_STOPBITS, AIC_DEV_UART7_PARITY, AIC_DEV_UART7_BAUDRATE, AIC_CLK_UART7_FREQ, AIC_DEV_UART7_MODE, "uart7"},
#endif
};
7.11.5.2.2.2. 初始化¶
初始化工作通过调用 RT-Thread 的标准初始化接口实现
INIT_BOARD_EXPORT(drv_usart_init);
int drv_usart_init(void)
{
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
int u = 0;
int i = 0;
for (i=0; i<sizeof(uart_dev_paras)/sizeof(struct drv_uart_dev_para); i++){
u = uart_dev_paras[i].index;
serial[u].ops = & drv_uart_ops;
serial[u].config = config;
serial[u].config.bufsz = 2048;
serial[u].config.baud_rate = uart_dev_paras[i].baud_rate;
serial[u].config.data_bits = uart_dev_paras[i].data_bits;
serial[u].config.stop_bits = uart_dev_paras[i].stop_bits;
serial[u].config.parity = uart_dev_paras[i].parity;
serial[u].config.function = uart_dev_paras[i].function;
hal_clk_set_freq(CLK_UART0 + u, uart_dev_paras[i].clk_freq);
hal_clk_enable(CLK_UART0 + u);
hal_reset_assert(RESET_UART0 + u);
aic_udelay(10000);
hal_reset_deassert(RESET_UART0 + u);
uart_handle[u] = hal_usart_initialize(u, NULL, drv_usart_irqhandler);
rt_hw_serial_register(&serial[u],
uart_dev_paras[i].name,
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
uart_handle[u]);
}
return 0;
}
7.11.5.2.2.3. 对外接口¶
UART 驱动对外的接口主要是实现了 rt_uart_ops 的四个标准接口, dma_transmit 传输没有实现
const struct rt_uart_ops drv_uart_ops =
{
drv_uart_configure,
drv_uart_control,
drv_uart_putc,
drv_uart_getc,
};
7.11.5.2.3. 应用层¶
UART 在应用层被封装成了一个标准的设备,通过读写进行数据的发送和接收
设备实现代码:kernel/rt-thread/components/drivers/serial/serial.c 使用示例代码:bsp/examples/test-uart/test_uart.c
7.11.5.2.3.1. rt_device_find¶
函数原型 |
rt_device_t rt_device_find(const char *name); |
---|---|
功能说明 |
找到相应的设备 |
参数定义 |
name - 设备名 |
返回值 |
设备变量或者NULL |
注意事项 |
7.11.5.2.3.2. rt_device_open¶
函数原型 |
rt_err_t rt_device_open (rt_device_t dev, rt_uint16_t oflag); |
---|---|
功能说明 |
打开设备 |
参数定义 |
dev - uart device
oflag - 打开参数
|
返回值 |
0,成功; 其他,失败 |
注意事项 |
7.11.5.2.3.3. rt_device_close¶
函数原型 |
rt_err_t rt_device_close(rt_device_t dev); |
---|---|
功能说明 |
关闭设备 |
参数定义 |
dev - 设备名 |
返回值 |
0,成功; 其他,失败 |
注意事项 |
7.11.5.2.3.4. rt_device_read¶
函数原型 |
rt_size_t rt_device_read (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); |
---|---|
功能说明 |
接收信息 |
参数定义 |
dev - uart device
pos - 起始位置
buffer - 数据存储区
size - 大小
|
返回值 |
接收数据的大小 |
注意事项 |
7.11.5.2.3.5. rt_device_write¶
函数原型 |
rt_size_t rt_device_write (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); |
---|---|
功能说明 |
发送信息 |
参数定义 |
dev - uart device
pos - 起始位置
buffer - 数据存储区
size - 大小
|
返回值 |
发送数据的大小 |
注意事项 |
7.11.5.2.4. 使用示例¶
示例可以参考 bsp/examples/test-uart/test_uart.c
static rt_device_t serial = rt_device_find("uart1");
rt_device_open(serial, RT_DEVICE_FLAG_RDONLY);
rt_device_write(serial, 0, str_send, (sizeof(str_send) - 1));
rt_device_read(serial, 0, str_send, 1);