1@page page_device_uart UART Device 2 3# UART Introduction 4 5UART (Universal Asynchronous Receiver/Transmitter), as a kind of asynchronous serial communication protocol, the working principle is to transmit each character of the transmitted data one by one. It is the most frequently used data bus during application development. 6 7The UART serial port is characterized by sequentially transmitting data one bit at a time. As long as two transmission lines can realize two-way communication, one line transmits data while the other receives data . There are several important functions for UART serial communication, namely baud rate, start bit, data bit, stop bit and parity bit. For two ports that use UART serial port communication, these functions must be matched, otherwise the communication can't be carried out normally. The data format of the UART serial port transmission is as shown below: 8 9 10 11* Start bit: Indicates the start of data transfer and the level logic is "0". 12- Data bits: Possible values are 5, 6, 7, 8, and 9, indicating that these bits are transmitted. The value is generally 8, because an ASCII character value is 8 bits. 13- Parity check bit: It it used by the receiver to verify the received data. The number of bits is used in the check of "1" is even (even parity) or odd (odd parity) ,in order to verify the data transmission. It is also fine by not using this bit . 14- Stop Bit: Indicates the end of one frame of data. The level logic is "1". 15- Baudrate: It is the rate at which a serial port communicates, which expressed in bits per second (bps) of the binary code transmitted in unit time. The common baud rate values are 4800, 9600, 14400, 38400, 115200, etc. The higher the value is, the faster the data transmission will be. 16 17# Access UART Device 18 19The application accesses the serial port hardware through the I/O device management interface provided by RT-Thread. The related interfaces are as follows: 20 21| **Funtion** | **Description** | 22| --------------------------- | -------------------------- | 23| rt_device_find() | find device | 24| rt_device_open() | open device | 25| rt_device_read() | read device | 26| rt_device_write() |write device| 27| rt_device_control() | control device | 28| rt_device_set_rx_indicate() | set receive callback function | 29| rt_device_set_tx_complete() | set send complete callback function | 30| rt_device_close() | close device | 31 32## Find UART Device 33 34The application obtains the device handle according to the uart device name, and then can operate the uart device.The device find function is shown below 35 36```c 37rt_device_t rt_device_find(const char* name); 38``` 39 40| **Parameter** | **Description** | 41| ------------- | ------------------------------------------------------------ | 42| name | device's name | 43| **back** | —— | 44| device handle | finding the corresponding device will return to the corresponding device handle | 45| RT_NULL | corresponding device object was not found | 46 47Generally, the name of the uart device registered to the system is uart0, uart1, etc. samples are as follows: 48 49```c 50#define SAMPLE_UART_NAME "uart2" /* uart device name */ 51static rt_device_t serial; /* uart device handle */ 52/* Find uart device*/ 53serial = rt_device_find(SAMPLE_UART_NAME); 54``` 55 56## Open UART Device 57 58Through the device handle, the application can open and close the device. When the device is opened, it will detect whether the device has been initialized. If it is not initialized, it will call the initialization interface to initialize the device by default. Open the device through the following functions: 59 60```c 61rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags); 62``` 63 64| **Parameter** | **Description** | 65| ---------- | ------------------------------- | 66| dev | device handle | 67| oflags | device mode flags | 68| **back** | —— | 69| RT_EOK | device opened successfully | 70| -RT_EBUSY | If the standalone parameter RT_DEVICE_FLAG_STANDALONE is included in the functions specified when the device is registered, the device will not be allowed to be opened repeatedly | 71| Other error codes | device failed to open | 72 73oflags parameters support the following values (Use OR logic to support multiple values): 74 75```c 76#define RT_DEVICE_FLAG_STREAM 0x040 /* Stream mode */ 77/* Receive mode function */ 78#define RT_DEVICE_FLAG_INT_RX 0x100 /* Interrupt receive mode */ 79#define RT_DEVICE_FLAG_DMA_RX 0x200 /* DMA receiving mode */ 80/* Receive mode function */ 81#define RT_DEVICE_FLAG_INT_TX 0x400 /* Interrupt receive mode*/ 82#define RT_DEVICE_FLAG_DMA_TX 0x800 /* DMA receive mode */ 83``` 84 85There are three modes of uart data receiving and sending: interrupt mode, polling mode and DMA mode. When used, only one of the three modes can be selected. If the open parameter oflag of the serial port does not specify the use of interrupt mode or DMA mode, the polling mode is used by default. 86 87The DMA (Direct Memory Access) transfer mode does not require the CPU to directly control the transfer, and does not have the process of reserving the scene and restoring the scene as they have in the interrupt processing mode. The DMA controller opens a path for directly transferring data to the RAM and the I/O device, which saves CPU resources to do other things. Using DMA transfer can continuously acquire or send a piece of information without taking up interrupts or delays, which is useful when communication is frequent or when large pieces of information are to be transmitted. 88 89>RT_DEVICE_FLAG_STREAM: Stream mode is used to output a string to the serial terminal: when the output character is `"\n"` (corresponding to the hexadecimal value 0x0A), a ``\r"` is automatically output in front (corresponding to hexadecimal value is 0x0D). 90 91The stream mode `RT_DEVICE_FLAG_STREAM` can be used with the receive and send mode parameter with the "|" logic. 92 93An example of using a uart device in **interrupt receive mode and polling mode** as follows: 94 95```c 96#define SAMPLE_UART_NAME "uart2" /* uart device name */ 97static rt_device_t serial; /* uart device handle */ 98/* find uart device */ 99serial = rt_device_find(SAMPLE_UART_NAME); 100 101/* Open the uart device in interrupt receive mode and polling mode*/ 102rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); 103``` 104 105If the uart is to use the DMA receive mode, the oflags takes the value RT_DEVICE_FLAG_DMA_RX. An example of using a uart device in the **DMA receive and polling send mode** is as follows: 106 107```c 108#define SAMPLE_UART_NAME "uart2" /* uart device's name */ 109static rt_device_t serial; /* uart device handle */ 110/* find uart device */ 111serial = rt_device_find(SAMPLE_UART_NAME); 112 113/* Open the uart device in DMA receive and polling send mode*/ 114rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX); 115``` 116 117## Control UART Device 118 119Through command control word, the application can configure the uart device by the following function: 120 121```c 122rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg); 123``` 124 125| **Parameter** | **Description** | 126| ----------------- | ------------------------------------------------------------ | 127| dev | device handle | 128| cmd | command control word can be valued as:RT_DEVICE_CTRL_CONFIG | 129| arg | controlled parameter: struct serial_configure | 130| **Back** | —— | 131| RT_EOK | function executed successfully | 132| -RT_ENOSYS | execution failed, dev is empty | 133| Other error codes | execution failed | 134 135* The prototype of control parameter structure: struct serial_configure is as follows: 136 137```c 138struct serial_configure 139{ 140 rt_uint32_t baud_rate; /* Baudrate */ 141 rt_uint32_t data_bits :4; /* Data bit */ 142 rt_uint32_t stop_bits :2; /* Stop bit */ 143 rt_uint32_t parity :2; /* Parity bit */ 144 rt_uint32_t bit_order :1; /* Prioritized by order */ 145 rt_uint32_t invert :1; /* Mode */ 146 rt_uint32_t bufsz :16; /* Receive data buffer size */ 147 rt_uint32_t reserved :4; /* Reserved bit */ 148}; 149``` 150 151* The default macro configuration provided by RT-Thread is as follows: 152 153```c 154#define RT_SERIAL_CONFIG_DEFAULT \ 155{ \ 156 BAUD_RATE_115200, /* 115200 bps */ \ 157 DATA_BITS_8, /* 8 databits */ \ 158 STOP_BITS_1, /* 1 stopbit */ \ 159 PARITY_NONE, /* No parity */ \ 160 BIT_ORDER_LSB, /* LSB first sent */ \ 161 NRZ_NORMAL, /* Normal mode */ \ 162 RT_SERIAL_RB_BUFSZ, /* Buffer size */ \ 163 0 \ 164} 165``` 166 167The configuration parameters provided by RT-Thread can be defined as the following macro definitions:: 168 169```c 170/* The baudrate can be defined as*/ 171#define BAUD_RATE_2400 2400 172#define BAUD_RATE_4800 4800 173#define BAUD_RATE_9600 9600 174#define BAUD_RATE_19200 19200 175#define BAUD_RATE_38400 38400 176#define BAUD_RATE_57600 57600 177#define BAUD_RATE_115200 115200 178#define BAUD_RATE_230400 230400 179#define BAUD_RATE_460800 460800 180#define BAUD_RATE_921600 921600 181#define BAUD_RATE_2000000 2000000 182#define BAUD_RATE_3000000 3000000 183/* Data bits can be defined as*/ 184#define DATA_BITS_5 5 185#define DATA_BITS_6 6 186#define DATA_BITS_7 7 187#define DATA_BITS_8 8 188#define DATA_BITS_9 9 189/* Stop bits can be defined as */ 190#define STOP_BITS_1 0 191#define STOP_BITS_2 1 192#define STOP_BITS_3 2 193#define STOP_BITS_4 3 194/* Parity bits can be defined as */ 195#define PARITY_NONE 0 196#define PARITY_ODD 1 197#define PARITY_EVEN 2 198/* Bit order can be defined as */ 199#define BIT_ORDER_LSB 0 200#define BIT_ORDER_MSB 1 201/* Mode canbe defined as */ 202#define NRZ_NORMAL 0 /* normal mode */ 203#define NRZ_INVERTED 1 /* inverted mode */ 204/* Default size of the receive data buffer */ 205#define RT_SERIAL_RB_BUFSZ 64 206``` 207 208**Receive Buffer** 209 210When the uart device is opened using interrupt receive mode, the uart driver framework will open a buffer according to the size of RT_SERIAL_RB_BUFSZ to save the received data. When the underlying driver receives a data, it will put the data into the buffer in the interrupt service program. 211 212>The default size of the receive data buffer is 64 bytes. If the number of received data in one-time is too large and the data is not read in time, the data of the buffer will be overwritten by the newly received data, resulting in data loss. It is recommended to increase the buffer. 213 214A sample for configuring uart hardware parameters such as data bits, check bits, stop bits, and so on are shown below: 215 216```c 217#define SAMPLE_UART_NAME "uart2" /* uart device's name */ 218static rt_device_t serial; /* uart device handle */ 219struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* Configuration parameters */ 220/* Find uart devices */ 221serial = rt_device_find(SAMPLE_UART_NAME); 222 223/* Open the uart device in interrupt receive and polling send mode */ 224rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); 225 226config.baud_rate = BAUD_RATE_115200; 227config.data_bits = DATA_BITS_8; 228config.stop_bits = STOP_BITS_2; 229config.parity = PARITY_NONE; 230/* The serial port configuration parameters can only be modified after opening the device */ 231rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config); 232``` 233 234## Send Data 235 236To write data to the serial port, the following functions can be used: 237 238```c 239rt_size_t rt_device_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size); 240``` 241 242| **Parameter** | **Description** | 243| ---------- | ------------------------------------------ | 244| dev | device handle | 245| pos | Write data offset, this parameter is not used in uart device | 246| buffer | Memory buffer pointer, place the data to be written | 247| size | The size of the written data | 248| **back** | —— | 249| The actual size of the written data | If it is a character device, the return size is in bytes; | 250| 0 | It needs to read the current thread's errno to determine the error status | 251 252Calling this function will write the data in the `buffer` to the `dev` device, the size of the write data is: size. 253 254The sample program for writing data to the serial port is as follows: 255 256```c 257#define SAMPLE_UART_NAME "uart2" /* uart device's name */ 258static rt_device_t serial; /* uart device handle */ 259char str[] = "hello RT-Thread!\r\n"; 260struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; /* Configuration parameter */ 261/*find uart device */ 262serial = rt_device_find(SAMPLE_UART_NAME); 263 264/* Open the uart device in interrupt reception and polling mode */ 265rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); 266/* Send string */ 267rt_device_write(serial, 0, str, (sizeof(str) - 1)); 268``` 269 270## Set The Send completion Callback Function 271 272When the application calls `rt_device_write()` to write data, if the underlying hardware can support automatic transmission, the upper application can set a callback function. This callback function is called after the underlying hardware data has been sent (for example, when the DMA transfer is complete or the FIFO has been written to complete the completion interrupt). You can set the device to send completion instructions by the following function: 273 274```c 275rt_err_t rt_device_set_tx_complete(rt_device_t dev, rt_err_t (*tx_done)(rt_device_t dev,void *buffer)); 276``` 277 278| **Parameter** | **Description** | 279| ------------- | ------------------------- | 280| dev | device handle | 281| tx_done | callback function pointer | 282| **back** | —— | 283| RT_EOK | set up successfully | 284 285When this function is called, the callback function is provided by the user. When the hardware device sends the data, the device driver calls back this function and passes the sent data block address buffer as a parameter to the upper application. When the application (thread) receives the indication, it will release the buffer memory block or use it as the buffer for the next write data according to the condition of sending the buffer. 286 287## Set The Receive Callback Function 288 289The data receiving instruction can be set by the following function. When the serial port receives the data, it will inform the upper application thread that the data has arrived: 290 291```c 292rt_err_t rt_device_set_rx_indicate(rt_device_t dev, rt_err_t (*rx_ind)(rt_device_t dev,rt_size_t size)); 293``` 294 295| **Parameter** | **Description** | 296| -------- | ------------ | 297| dev | device handle | 298| rx_ind | callback function pointer | 299| dev | device handle (callback function parameter) | 300| size | buffer data size (callback function parameter) | 301| **back** | —— | 302| RT_EOK | set up successfully | 303 304The callback function for this function is provided by the user. If the uart device is opened in interrupt receive mode, the callback function will be called when the serial port receives a data, and the data size of the buffer will be placed in the `size` parameter, and the uart device handle will be placed in the `dev` parameter. 305 306If the uart is opened in DMA receive mode, the callback function is called when the DMA completes receiving a batch of data. 307 308Normally the receiving callback function can send a semaphore or event to notify the serial port data processing thread that data has arrived. The example is as follows: 309 310```c 311#define SAMPLE_UART_NAME "uart2" /* uart device name */ 312static rt_device_t serial; /* uart device handle */ 313static struct rt_semaphore rx_sem; /* The semaphore used to receive the message */ 314 315/* Receive data callback function */ 316static rt_err_t uart_input(rt_device_t dev, rt_size_t size) 317{ 318 /* When the serial port receives the data, it triggers interrupts, calls this callback function, and sends the received semaphore */ 319 rt_sem_release(&rx_sem); 320 321 return RT_EOK; 322} 323 324static int uart_sample(int argc, char *argv[]) 325{ 326 serial = rt_device_find(SAMPLE_UART_NAME); 327 328 /* Open the uart device in interrupting receive mode */ 329 rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); 330 331 /* Initialization semaphore */ 332 rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); 333 334 /* Set the receive callback function */ 335 rt_device_set_rx_indicate(serial, uart_input); 336} 337 338``` 339 340## Receive Data 341 342You can call the following function to read the data received by the uart: 343 344```c 345rt_size_t rt_device_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size); 346``` 347 348| **Parameter** | **Description** | 349| -------------------------------- | ------------------------------------------------------------ | 350| dev | device handle | 351| pos | Read data offset, uart device dose not use this parameter | 352| buffer | Buffer pointer, the data read will be saved in the buffer | 353| size | Read the size of the data | 354| **back** | —— | 355| Read the actual size of the data | If it is a character device, the return size is in bytes. | 356| 0 | It needs to read the current thread's errno to determine the error status | 357 358Read data offset: pos is not valid for character devices. This parameter is mainly used for block devices. 359 360An example of using the interrupt receive mode with the receive callback function is as follows: 361 362```c 363static rt_device_t serial; /* uart device handle */ 364static struct rt_semaphore rx_sem; /* Semaphore used to receive messages */ 365 366/* Thread receiving data */ 367static void serial_thread_entry(void *parameter) 368{ 369 char ch; 370 371 while (1) 372 { 373 /* Reads a byte of data from the serial port and waits for the receiving semaphore if it is not read */ 374 while (rt_device_read(serial, -1, &ch, 1) != 1) 375 { 376 /* Blocking waiting to receive semaphore, waiting for the semaphore to read the data again*/ 377 rt_sem_take(&rx_sem, RT_WAITING_FOREVER); 378 } 379 /* Read the data through the serial port dislocation output*/ 380 ch = ch + 1; 381 rt_device_write(serial, 0, &ch, 1); 382 } 383} 384``` 385 386## Close The UART Device 387 388After the application completes the serial port operation, the uart device can be closed by the following functions: 389 390```c 391rt_err_t rt_device_close(rt_device_t dev); 392``` 393 394| **Parameter** | **Description** | 395| ----------------- | ------------------------------------------------------------ | 396| dev | device handle | 397| **back** | —— | 398| RT_EOK | device closed successfully | 399| -RT_ERROR | The device has been completely shut down and cannot be shut down repeatedly | 400| other error codes | fail to close the device | 401 402Use the `rt_device_close()` interface and `rt_device_open()` interface in pair. When you open the device, you need to close the device once, so that the device will be completely shut down, otherwise the device will remain open. 403 404# Examples Of Using UART Device 405 406## Interrupt Receiving And Polling Send 407 408The main steps of the sample code are as follows: 409 4101. First find the uart device to get the device handle. 4112. Initialize the semaphore that the callback function sends, and then open the uart device in read/write and interrupt receive mode. 4123. Set the receive callback function of the uart device, then send the string and create a read data thread. 4134. The read data thread will try to read a character data. If there is no data, it will hang and wait for the semaphore. When the uart device receives a data, it will trigger an interrupt and call the receive callback function. This function will send a semaphore to wake up the thread. At this point, the thread will immediately read the received data. 4145. This sample code is not limited to a specific BSP. According to the uart device registered by BSP, modify the uart device's name corresponding to the sample code's macro definition SAMPLE_UART_NAME to run. 415 416The running sequence diagram is shown as follows: 417 418 419 420 421```c 422/* 423 * Program list: This is a uart device usage routine 424 * The routine exports the uart_sample command to the control terminal 425 * Format of command: uart_sample uart2 426 * Command explanation: the second parameter of the command is the name of the uart device. If it is null, the default uart device wil be used 427 * Program function: output the string "hello RT-Thread!" through the serial port, and then malposition the input character 428*/ 429 430#include <rtthread.h> 431 432#define SAMPLE_UART_NAME "uart2" 433 434/* Semaphore used to receive messages */ 435static struct rt_semaphore rx_sem; 436static rt_device_t serial; 437 438/* Receive data callback function */ 439static rt_err_t uart_input(rt_device_t dev, rt_size_t size) 440{ 441 /* After the uart device receives the data, it generates an interrupt, calls this callback function, and then sends the received semaphore. */ 442 rt_sem_release(&rx_sem); 443 444 return RT_EOK; 445} 446 447static void serial_thread_entry(void *parameter) 448{ 449 char ch; 450 451 while (1) 452 { 453 /* Read a byte of data from the serial port and wait for the receiving semaphore if it is not read */ 454 while (rt_device_read(serial, -1, &ch, 1) != 1) 455 { 456 /* Being Suspended and waiting for the semaphore */ 457 rt_sem_take(&rx_sem, RT_WAITING_FOREVER); 458 } 459 /* Read the data from the serial port and output through dislocation */ 460 ch = ch + 1; 461 rt_device_write(serial, 0, &ch, 1); 462 } 463} 464 465static int uart_sample(int argc, char *argv[]) 466{ 467 rt_err_t ret = RT_EOK; 468 char uart_name[RT_NAME_MAX]; 469 char str[] = "hello RT-Thread!\r\n"; 470 471 if (argc == 2) 472 { 473 rt_strncpy(uart_name, argv[1], RT_NAME_MAX); 474 } 475 else 476 { 477 rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); 478 } 479 480 /* Find uart devices in the system */ 481 serial = rt_device_find(uart_name); 482 if (!serial) 483 { 484 rt_kprintf("find %s failed!\n", uart_name); 485 return -RT_ERROR; 486 } 487 488 /* Initialize the semaphore */ 489 rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); 490 /* Open the uart device in interrupt receive and polling send mode */ 491 rt_device_open(serial, RT_DEVICE_FLAG_INT_RX); 492 /* Set the receive callback function */ 493 rt_device_set_rx_indicate(serial, uart_input); 494 /* Send string */ 495 rt_device_write(serial, 0, str, (sizeof(str) - 1)); 496 497 /* Create a serial thread */ 498 rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); 499 /* Start the thread successfully */ 500 if (thread != RT_NULL) 501 { 502 rt_thread_startup(thread); 503 } 504 else 505 { 506 ret = -RT_ERROR; 507 } 508 509 return ret; 510} 511/* Export to the msh command list */ 512MSH_CMD_EXPORT(uart_sample, uart device sample); 513``` 514 515## DMA Reception And Polling Transmission 516 517When the serial port receives a batch of data, it will call the receive callback function. The receive callback function will send the data size of the buffer at this time to the waiting data processing thread through the message queue. After the thread gets the message, it is activated and reads the data. In general, the DMA receive mode completes data reception in conjunction with the DMA receive completion interrupt and the serial port idle interrupt. 518 519* This sample code is not limited to a specific BSP. According to the uart device registered by BSP, modify the sample code macro to define the uart device name corresponding to SAMPLE_UART_NAME to run. 520 521The running sequence diagram is shown below: 522 523 524 525```c 526/* 527 * Program list: This is a uart device DMA receive usage routine 528 * The routine exports the uart_dma_sample command to the control terminal 529 * Command format: uart_dma_sample uart3 530 * Command explanation: The second parameter of the command is the name of the uart device to be used. If it is empty, the default uart device will be used. 531 * Program function: output the string "hello RT-Thread!" through the serial port, and output the received data through the serial port, and then print the received data. 532*/ 533 534#include <rtthread.h> 535 536#define SAMPLE_UART_NAME "uart3" /* uart device name */ 537 538/* Serial port receiving message structure*/ 539struct rx_msg 540{ 541 rt_device_t dev; 542 rt_size_t size; 543}; 544/* uart device handle */ 545static rt_device_t serial; 546/* Message queue control block*/ 547static struct rt_messagequeue rx_mq; 548 549/* Receive data callback function */ 550static rt_err_t uart_input(rt_device_t dev, rt_size_t size) 551{ 552 struct rx_msg msg; 553 rt_err_t result; 554 msg.dev = dev; 555 msg.size = size; 556 557 result = rt_mq_send(&rx_mq, &msg, sizeof(msg)); 558 if ( result == -RT_EFULL) 559 { 560 /* message queue full */ 561 rt_kprintf("message queue full!\n"); 562 } 563 return result; 564} 565 566static void serial_thread_entry(void *parameter) 567{ 568 struct rx_msg msg; 569 rt_err_t result; 570 rt_uint32_t rx_length; 571 static char rx_buffer[RT_SERIAL_RB_BUFSZ + 1]; 572 573 while (1) 574 { 575 rt_memset(&msg, 0, sizeof(msg)); 576 /* Read messages from the message queue*/ 577 result = rt_mq_recv(&rx_mq, &msg, sizeof(msg), RT_WAITING_FOREVER); 578 if (result >= 0) 579 { 580 /*Read data from the serial port*/ 581 rx_length = rt_device_read(msg.dev, 0, rx_buffer, msg.size); 582 rx_buffer[rx_length] = '\0'; 583 /* Output the read message through the uart device: serial */ 584 rt_device_write(serial, 0, rx_buffer, rx_length); 585 /* Print data */ 586 rt_kprintf("%s\n",rx_buffer); 587 } 588 } 589} 590 591static int uart_dma_sample(int argc, char *argv[]) 592{ 593 rt_err_t ret = RT_EOK; 594 char uart_name[RT_NAME_MAX]; 595 static char msg_pool[256]; 596 char str[] = "hello RT-Thread!\r\n"; 597 598 if (argc == 2) 599 { 600 rt_strncpy(uart_name, argv[1], RT_NAME_MAX); 601 } 602 else 603 { 604 rt_strncpy(uart_name, SAMPLE_UART_NAME, RT_NAME_MAX); 605 } 606 607 /* find uart device */ 608 serial = rt_device_find(uart_name); 609 if (!serial) 610 { 611 rt_kprintf("find %s failed!\n", uart_name); 612 return -RT_ERROR; 613 } 614 615 /* Initialize message queue */ 616 rt_mq_init(&rx_mq, "rx_mq", 617 msg_pool, /* a pool for storing messages */ 618 sizeof(struct rx_msg), /* The maximum length of a message*/ 619 sizeof(msg_pool), /* The size of the message pool */ 620 RT_IPC_FLAG_FIFO); /* If there are multiple threads waiting, assign messages according to the order. */ 621 622 /* Open the uart device in DMA receive and polling send mode */ 623 rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX); 624 /* Set the receive callback function */ 625 rt_device_set_rx_indicate(serial, uart_input); 626 /* Send string */ 627 rt_device_write(serial, 0, str, (sizeof(str) - 1)); 628 629 /* Create a thread */ 630 rt_thread_t thread = rt_thread_create("serial", serial_thread_entry, RT_NULL, 1024, 25, 10); 631 /* Start the thread if it is created successfully*/ 632 if (thread != RT_NULL) 633 { 634 rt_thread_startup(thread); 635 } 636 else 637 { 638 ret = -RT_ERROR; 639 } 640 641 return ret; 642} 643/* Export to the msh command list */ 644MSH_CMD_EXPORT(uart_dma_sample, uart device dma sample); 645``` 646 647