README_zh.md
1# Niobe407开发板OpenHarmony基于HDF驱动框架编程开发——UART
2本示例将演示如何在Niobe407开发板上通过HDF驱动框架,使用UART接口对USART4进行读写操作。
3
4
5## 编译调试
6- 进入//kernel/liteos_m目录, 在menuconfig配置中进入如下选项:
7
8 `(Top) → Platform → Board Selection → select board niobe407 → use talkweb niobe407 application → niobe407 application choose`
9
10- 选择 `203_hdf_usart_read_write`
11
12- 在menuconfig的`(Top) → Driver`选项中使能如下配置:
13
14```
15 [*] Enable Driver
16 [*] HDF driver framework support
17 [*] Enable HDF platform driver
18 [*] Enable HDF platform uart driver
19```
20- 回到sdk根目录,执行`hb build -f`脚本进行编译。
21
22### 运行结果
23
24示例代码编译烧录代码后,按下开发板的RESET按键,通过串口助手查看日志
25```
26[HDF:I/uartDev]InitUartDevice: Enter
27[HDF:E/uartDev]uart 2 device init
28[HDF:I/HDF_LOG_TAG]UartSetAttribute: success
29[HDF:I/uartDev]uart write block 0x40004400
30[HDF:I/HDF_LOG_TAG]UartWrite: success, ret 0
31```
32用串口线连接串口4,并打开串口4,输入welcome to openharmony,即可在调试串口看到日志
33```
34[HDF:I/HDF_LOG_TAG]UartRead byte 23 content is welcome to openharmony
35[HDF:I/uartDev]UartHostDevDeinit: Enter
36[HDF:I/uartDev]UartHostDevDeinit: Enter
37
38```
39# OpenHarmony驱动子系统开发—UART收发测试
40
41## 概述
42 1.UART是通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)的缩写,是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输。
43
44 2.UART与其他模块一般用2线或4线相连:
45 当使用2线相连时,它们分别是:
46 TX:发送数据端,和对端的RX相连;
47 RX:接收数据端,和对端的TX相连;
48
49 当使用4线相连时,它们分别是:
50 TX:发送数据端,和对端的RX相连;
51 RX:接收数据端,和对端的TX相连;
52 RTS:发送请求信号,用于指示本设备是否准备好,可接受数据,和对端CTS相连;
53 CTS:允许发送信号,用于判断是否可以向对端发送数据,和对端RTS相连;
54
55 3.UART通信之前,收发双方需要约定好一些参数:波特率、数据格式(起始位、数据位、校验位、停止位)等。通信过程中,UART通过TX发送给对端数据,通过RX接收对端发送的数据。
56
57## 接口说明
58 1. uart open初始化函数:DevHandle UartOpen(uint32_t port);
59 参数说明:
60 port: 对应的uart号,stm32f407芯片有6组uart,分别为uart1-uart6 0-5
61 return: 不为NULL,表示初始化成功
62 2. uart设置波特率函数:int32_t UartSetBaud(DevHandle handle, uint32_t baudRate);
63 参数说明:
64 handle: UART设备句柄,
65 baudRate: 待设置的波特率
66 return: 0:UART设置波特率成功,负数表示设置波特率失败
67 2. uart读数据函数:int32_t UartRead(DevHandle handle, uint8_t *data, uint32_t size);
68 参数说明:
69 handle: 指向uart设备句柄的指针
70 data: uart读取数据后的缓存地址
71 size: uart本次期望读取的数据长度
72 return: 返回负数表示失败
73
74 3. uart写数据函数:int32_t UartWrite(DevHandle handle, uint8_t *data, uint32_t size);
75 参数说明:
76 handle: 指向uart设备句柄的指针
77 data: uart待发送的数据
78 size: uart本次期望发送的数据长度
79 return: 返回0,表示成功,返回负数,表示失败
80
81 4. uart去初始化函数:void UartClose(DevHandle handle);
82 参数说明:
83 handle: 指向uart设备句柄的指针
84
85## UART HDF HCS配置文件解析
86- device_uart_info.hcs文件位于/device/board/talkweb/niobe407/sdk/hdf_config/device_uart_info.hcs,本例子使用的是UART4串口
87```
88
89root {
90 module = "talkweb,stm32f407";
91 device_info {
92 match_attr = "hdf_manager";
93 template host {
94 hostName = "";
95 priority = 100;
96 template device {
97 template deviceNode {
98 policy = 0;
99 priority = 100;
100 preload = 0;
101 permission = 0664;
102 moduleName = "";
103 serviceName = "";
104 deviceMatchAttr = "";
105 }
106 }
107 }
108 platform :: host {
109 hostName = "platform_host";
110 device_uart :: device {
111 uart4 :: deviceNode { // uart4配置信息
112 policy = 2;//驱动服务发布的策略,policy大于等于1(用户态可见为2,仅内核态可见为1);
113 priority = 100;//驱动启动优先级
114 moduleName = "STM_TW_UART_MODULE_HDF";//驱动名称,该字段的值必须和驱动入口结构的moduleName值一致
115 serviceName = "HDF_PLATFORM_UART_4"; //驱动对外发布服务的名称,必须唯一,必须要按照HDF_PLATFORM_UART_X的格式,X为UART控制器编号
116 deviceMatchAttr = "uart_config4";
117 }
118 }
119 device_uart1 :: device {
120 uart5 :: deviceNode { // uart5配置信息,为485接口
121 policy = 2;
122 priority = 100;
123 moduleName = "STM_TW_UART_MODULE_HDF";
124 serviceName = "HDF_PLATFORM_UART_5";
125 deviceMatchAttr = "uart_config5";
126 }
127 }
128 }
129 }
130}
131```
132
133- hdf_uart.hcs文件位于/device/board/talkweb/niobe407/sdk/hdf_config/hdf_uart.hcs,在此文件中配置串口对应的GPIO引脚信息,串口配置信息
134```
135#include "device_uart_info.hcs"
136root {
137 platform {
138 uart_config4 {
139 uart4_gpio {
140 // 要配置的引脚个数,接下来的引脚名必须定义成gpio_num_1, gpio_num_2, gpio_num_3...
141 gpio_num_max = 2; // uart4 做232 示例 2个脚
142 // port, pin, mode, speed, outputType, pull, alternate
143 gpio_num_1 = [2, 10, 2, 3, 0, 1, 8]; // tx pc10
144 gpio_num_2 = [2, 11, 2, 3, 0, 1, 8]; // rx pc11
145 }
146 uart4 : uart4_gpio {
147 match_attr = "uart_config4";
148 num = 4; // 1 :uart1 2: USART2 3:USART3 4:UART4 5:UART5 6:USART6 串口总线号此处为uart4
149 baudRate = 115200; // baudrate
150 dataWidth = 0; // 0:8bit 1:9bit
151 stopBit = 1; // 0:0.5stop bits 1:1 stop bit 2:1.5 stop bits 2:2 stop bits
152 parity = 0; // 0: none 1: event 2:odd
153 transDir = 0; // 0: dir none 1: rx 2: tx 3:tx and rx
154 flowCtrl = 0; // 0: no flowcontrl 1: flowContorl RTS 2: flowControl CTS 3: flowControl RTS AND CTS
155 overSimpling = 0; // 0: overSimpling 16bits 1: overSimpling 8bits
156 idleIrq = 1; // 0: disable idle irq 1: enable idle irq
157 transMode = 0; /// 0:block 1:noblock 2:TX DMA RX NORMAL 3:TX NORMAL RX DMA 4: USART_TRANS_TX_RX_DMA 目前还不支持DMA传输方式,只支持0,1阻塞读写方式和非阻塞读写方式
158 阻塞读写是指,写时等可写并且写完才返回,阻塞读是指读到设定读取个数或者产生闲时中断才返回,非阻塞读写是指不管串口可读或者可写,直接调用读写接口进行读写,不一定能正确读写成功,一般建议阻塞读写
159 maxBufSize = 1024;
160 uartType = 0; // 0 : 232 1: 485
161 uartDePin = 0; // usart 485 pin
162 uartDeGroup = 0; // usart 485 control line
163 }
164 }
165
166 uart_config5 {
167 uart5_gpio {
168 // 要配置的引脚个数,接下来的引脚名必须定义成gpio_num_1, gpio_num_2, gpio_num_3...
169 gpio_num_max = 3; // uart5 做485 示例 3个脚
170 // port, pin, mode, speed, outputType, pull, alternate
171 gpio_num_1 = [2, 12, 2, 3, 0, 1, 8]; // tx pc12
172 gpio_num_2 = [3, 2, 2, 3, 0, 1, 8]; // rx pd2
173 gpio_num_3 = [6, 12, 1, 3, 0, 2, 0]; // de pg12
174 }
175 uart5 : uart5_gpio {
176 match_attr = "uart_config5";
177 num = 5; // 1 :uart1 2: USART2 3:USART3 4:UART4 5:UART5 6:USART6 串口总线号此处为uart5 485
178 baudRate = 115200; // baudrate
179 dataWidth = 0; // 0:8bit 1:9bit
180 stopBit = 1; // 0:0.5stop bits 1:1 stop bit 2:1.5 stop bits 2:2 stop bits
181 parity = 0; // 0: none 1: event 2:odd
182 transDir = 3; // 0: dir none 1: rx 2: tx 3:tx and rx
183 flowCtrl = 0; // 0: no flowcontrl 1: flowContorl RTS 2: flowControl CTS 3: flowControl RTS AND CTS
184 overSimpling = 0; // 0: overSimpling 16bits 1: overSimpling 8bits
185 idleIrq = 1; // 0: disable idle irq 1: enable idle irq
186 transMode = 0; // 0:block 1:noblock 2:TX DMA RX NORMAL 3:TX NORMAL RX DMA 4: USART_TRANS_TX_RX_DMA 目前还不支持DMA传输方式,只支持0,1阻塞读写方式和非阻塞读写方式
187 阻塞读写是指,写时等可写并且写完才返回,阻塞读是指读到设定读取个数或者产生闲时中断才返回,非阻塞读写是指不管串口可读或者可写,直接调用读写接口进行读写,不一定能正确读写成功,一般建议阻塞读写
188 uartType = 1; // 0 : 232 1: 485
189 uartDePin = 12; // uart5 485 pin
190 uartDeGroup = 6; // uart5 485 control line group
191 }
192 }
193 }
194}
195
196```
197
198## 例程原理简介
199 NIOBE407开发板有USART1,USART2,USART3,UART4,UART5,USART6总共6路串口,本例程用的是USART2,和USART3,USART2为RS232, USART3为RS485。如需修改UART的硬件配置,可前往device\board\talkweb\niobe407\sdk\hdf_config\hdf_uart.hcs中根据您的开发板原理图进行修改
200``` c
201static void* HdfUsartTestEntry(void* arg)
202{
203 DevHandle handle = NULL; /* UART设备句柄 */
204 uint32_t port = 2; /* UART设备端口号 */
205 handle = UartOpen(port);
206 if (handle == NULL) {
207 HDF_LOGE("UartOpen: failed!\n");
208 return NULL;
209 }
210
211 int32_t ret;
212 uint32_t baudRate;
213 /* 获取UART波特率 */
214 ret = UartGetBaud(handle, &baudRate);
215 if (ret != 0) {
216 HDF_LOGE("UartGetBaud: failed, ret %d\n", ret);
217 } else {
218 HDF_LOGI("UartGetBaud: success, badurate %d\n", baudRate);
219 }
220
221 baudRate = 115200;
222 ret = UartSetBaud(handle, baudRate); // 设置uart波特率
223 if (ret != 0) {
224 HDF_LOGE("UartGetBaud: failed, ret %d\n", ret);
225 } else {
226 HDF_LOGI("UartSetBaud: success, badurate %d\n", baudRate);
227 }
228
229 struct UartAttribute attribute = {0};
230
231 ret = UartGetAttribute(handle, &attribute); // 获取有hcs文件设置的串口配置信息
232 if (ret != 0) {
233 HDF_LOGE("UartGetAttribute: failed, ret %d\n", ret);
234 } else {
235 HDF_LOGI("UartGetAttribute: success\n");
236 }
237
238 attribute.dataBits = UART_ATTR_DATABIT_8; // 8位停止位
239 attribute.fifoTxEn = 1; // tx使能
240 attribute.fifoRxEn = 1; // rx使能
241 attribute.parity = UART_ATTR_PARITY_NONE; // 无校验
242 attribute.stopBits = UART_ATTR_STOPBIT_1; // 1位停止位
243 attribute.cts = 0; // 无流控
244 attribute.rts = 0; // 无流控
245
246 ret = UartSetAttribute(handle, &attribute); // 设置uart配置
247 if (ret != 0) {
248 HDF_LOGE("UartSetAttribute: failed, ret %d\n", ret);
249 } else {
250 HDF_LOGI("UartSetAttribute: success\n");
251 }
252
253 len = strlen((char *)txbuf);
254 ret = UartWrite(handle, txbuf, len); // 写串口
255 if (ret != 0) {
256 HDF_LOGE("UartWrite: failed, ret %d\n", ret);
257 goto _ERR;
258 } else {
259 HDF_LOGI("UartWrite: success, ret %d\n", ret);
260 }
261
262 ret = UartRead(handle, rxbuf, len); // 读串口输入
263 if (ret < 0) {
264 HDF_LOGE("UartRead: failed, ret %d\n", ret);
265 goto _ERR;
266 } else {
267 HDF_LOGI("UartRead byte %d content is %s\n", ret, rxbuf);
268 }
269
270 UartClose(handle);
271_ERR:
272 /* 销毁UART设备句柄 */
273 UartClose(handle);
274
275}
276 ```