![RT-Thread设备驱动开发指南](https://wfqqreader-1252317822.image.myqcloud.com/cover/260/46670260/b_46670260.jpg)
2.3 实现UART设备的操作方法
UART设备驱动框架层为UART设备驱动层提供的操作方法原型如下所示。在开发驱动时,需要为设备定义并实现这些操作方法。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/34_02.jpg?sign=1739279437-ImqO9Xiqom0eYmsMSPoaOssCqN6yKmgJ-0-f587f7ce55772f7fc1400da56cdbf606)
这些操作方法会完成串口的基本操作,例如:configure方法用于配置串口(波特率等);control方法用于控制串口;putc方法用于串口向外发送字符数据;getc方法用于串口获取字符数据;transmit方法用于数据发送,主要是进行多字节数据的发送。下面继续讲解如何实现这些操作方法。
2.3.1 configure:配置UART设备
操作方法configure的作用是根据配置参数对UART设备进行配置,配置参数如波特率、接收缓冲区大小、数据位、停止位、奇偶校验等,UART设备在初始化时会调用此方法,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_01.jpg?sign=1739279437-jq6RVWWK7qlK6wTItuPjW1bwoZ2YLsPF-0-a505ec30f3db053f177e8a39b8c12f83)
configure方法的参数及返回值如表2-1所示。
表2-1 configure方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_02.jpg?sign=1739279437-XhFIrp1loRqeI9HnUBmxacZKmBuoZGSX-0-c373797f0a2ea12d83825ed77b685807)
参数cfg是串口设备的配置参数,结构原型为struct serial_configure,如下所示。configure方法根据这些成员的值进行配置。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_03.jpg?sign=1739279437-5FI6CNXw8V2y0PqQiYexFnTrGoDkjo1R-0-0123c49de8ad1ea36d0ffae13bd06384)
成员可取值以及参考的默认取值如下所示,读者可以根据实际用途选择合适的值。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_04.jpg?sign=1739279437-EtfgP55OQtd9U0yJxlhAqfejAxTcoBLY-0-92eb1556adbff052fee33715d7e1c504)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/36_01.jpg?sign=1739279437-J0GzDVf7i2OY5jkl4UhLNlTW7l1PxAJB-0-fd6631c446dfae3304e3c74aaf34a818)
使用STM32串口驱动configure方法的实现示例如下。其内容主要是初始化STM32 UART的句柄,将cfg配置参数赋值给STM32 UART的句柄的成员,然后对串口进行初始化操作。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/36_02.jpg?sign=1739279437-tV0Gg9vJze5Z0VTWdwMMTdCIztm0dKMa-0-6ae026ccfc15cdb8f50b16cc97edfed0)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_01.jpg?sign=1739279437-rcC9nCelLJbNqYypZPnn5FIZalXeT4zc-0-0273c230b4850abdc2bbad551400d7db)
2.3.2 control:控制UART设备
操作方法control用于控制UART设备行为,会根据传入的参数cmd(控制命令)对串口的行为进行相应的控制,例如配置设备、关闭设备、清除中断等操作,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_02.jpg?sign=1739279437-LTZeWKQtPviQX3fhXqWmdQS0U3qnZFgj-0-60e44460e9a7a6524adc60c5ecacda87)
control方法的参数及返回值如表2-2所示,该方法根据控制命令cmd和控制参数arg控制串口设备,如开关中断及DMA的配置。
表2-2 control方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_03.jpg?sign=1739279437-yv8cIVUFYfY4MN1Tf9v8FWXlnHsPjOUJ-0-a4c28fab76400fff21eeb4763f99deaa)
在驱动实现时,需要完成的cmd取值情况如下所示。如果注释中标明“驱动中不用实现”,表示在实现驱动代码时不用考虑cmd的取值,因为这些取值无关底层设备,而系统对这些取值的处理也已经在设备驱动框架中实现了。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/38_01.jpg?sign=1739279437-4lt0Kjd2e2vHZT3LOm3I3kdDRg6vkKa1-0-78195d0773accb803a884c497cecdfd2)
以下是STM32串口驱动的control方法的代码,该方法实现了6种cmd命令对应的操作。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/38_02.jpg?sign=1739279437-dfyvEvLkJvZNdthhu6lZKsHkL5ioHmiZ-0-c6edbfb8a8e6ce1fc1a3479a353a1b5b)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/39_01.jpg?sign=1739279437-uZU9NIJ1RSAvg4XGNN9Oa0rZZfpuZmXG-0-9e3c782d680b3dcd419658de64293a16)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_01.jpg?sign=1739279437-qGUtKm8HLqC61YEWFVkzLYU2TfamZ70q-0-75f124e4efaaeba42d9632627325f2fd)
2.3.3 putc:发送一个字符
操作方法putc用于发送一个字符的数据,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_02.jpg?sign=1739279437-c6BYhIJv3InSvEgOxt9LTmI2VcCso0tQ-0-368d934c31c9380efcced7a1aaa32ac9)
putc方法的参数及返回值如表2-3所示。
表2-3 putc方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_03.jpg?sign=1739279437-45qAmJ7jlV1K1SMLgyMX6O28QwTP9i6f-0-e8a2d83b5e0d1c15a3d7891a108707f0)
我们看一个具体的putc方法的示例代码,STM32串口驱动中putc方法实现的部分代码如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_04.jpg?sign=1739279437-awUNtxKdbQXacpTabrwvadaGxEiLEJcD-0-5f65416e5efdb4f06a84b512551ad147)
在示例代码中,先利用接口rt_container_of获取到STM32的UART设备模型,然后等待上一次数据发送完成后再向硬件寄存器发送一个字符数据。这里需要注意,在UART设备驱动drv_usart_v2.h中,已经定义了向寄存器写入数据的宏UART_SET_TDR,供驱动开发者使用:
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_05.jpg?sign=1739279437-YgWfuj3Px0pVXfTtfP22RcKsA9NzvzXT-0-33ba5e7a55a33a7ed9b8a9cbaa363a4a)
2.3.4 getc:接收一个字符
操作方法getc用于从硬件寄存器中接收一个字符数据,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_01.jpg?sign=1739279437-vl17YTwCw4jFHQGdu5sKaZRe71HDcFMJ-0-1a1be88f53f475b0c9157860eaf83ffb)
getc方法的参数及返回值如表2-4所示。
表2-4 getc方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_02.jpg?sign=1739279437-2avHYX4beku5F00HyyTk1fPcZ0PshP7B-0-c5b54be8bbaf6114525cf7602ad2a84b)
我们看一个具体的getc方法的示例代码,STM32串口驱动中getc方法实现的部分代码如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_03.jpg?sign=1739279437-fOB8tZULyYhHfn4Dn9pVnbEFkXDPZjzN-0-2b44c1bdbeed9ec05afdddcdf2b11aae)
在示例代码中,同样先获取STM32的UART设备模型uart,然后利用UART_GET_RDR宏从硬件寄存器中读取一个字符的数据。其中,UART设备驱动drv_usart_v2.h定义了获取寄存器数据的宏UART_GET_RDR,供驱动开发者使用:
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_01.jpg?sign=1739279437-vb37YLGKCBeOzZ7ku7YcA1PnDcWGl8CY-0-12f137c6d7059ecd46785fc13ed52c55)
2.3.5 transmit:数据发送
操作方法transmit一般用于中断和DMA的数据发送,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_02.jpg?sign=1739279437-D5V5xMA3SCyuf69d5fdRij1Vqq49RokB-0-29386fc098babf7dcbc90f65a47d72d4)
transmit方法的参数及返回值如表2-5所示。
表2-5 transmit方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_03.jpg?sign=1739279437-FEMPzM0vSDSIAgau7gWGfThMSsh0HOCF-0-a00473680d532d04232f42880fe98670)
其中参数tx_flag可取值如下,驱动开发者可以根据以下两种情况完成驱动:
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_04.jpg?sign=1739279437-B2wBt8pAidEFHmk85eGmLRy791nAOjWY-0-be47dc110cb394f11dd3672d2edecfb7)
我们来看一个在STM32上实现串口transmit方法的示例代码:
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_05.jpg?sign=1739279437-MH0tmFkd1A86Zu06cyUq9Gk86uiGn9WE-0-437faceac4e19c52a83f332b6051c854)
在示例代码中,首先检测是否使用DMA发送数据,然后直接调用了STM32 HAL库提供的DMA传输接口,完成了数据的发送。