![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=1739293075-Ix7VS23235JjU8DOMcZItt0ZNPzlfg5S-0-527d46d530b65b589fbe21516e0cda30)
这些操作方法会完成串口的基本操作,例如: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=1739293075-jaIhKEkkkBX147GBaUGCcHItLQEgkRnd-0-e050b16d499c0e3410d3ff901bbef04e)
configure方法的参数及返回值如表2-1所示。
表2-1 configure方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_02.jpg?sign=1739293075-qQZQltNk4v1B3y1HAvn4hyW7eKKi5CBH-0-6ba4d9bbf5921ae0290d993656d46011)
参数cfg是串口设备的配置参数,结构原型为struct serial_configure,如下所示。configure方法根据这些成员的值进行配置。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_03.jpg?sign=1739293075-Q3roNHV2anmkBlwlGXCMnfR1BYYij2cv-0-845545576ad33e51038408e36e1747b2)
成员可取值以及参考的默认取值如下所示,读者可以根据实际用途选择合适的值。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_04.jpg?sign=1739293075-4PjbspbZtkeObONzdJ8ZCFlJxjwZc7oh-0-89a8806d6952423e34f027df968c942d)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/36_01.jpg?sign=1739293075-m6969Xy7bjBxwu2WEGt56EuJRPzoEtIV-0-451d83410083bba2c9267efea27c29e2)
使用STM32串口驱动configure方法的实现示例如下。其内容主要是初始化STM32 UART的句柄,将cfg配置参数赋值给STM32 UART的句柄的成员,然后对串口进行初始化操作。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/36_02.jpg?sign=1739293075-VuY8HmvMK9puVrn09q8dL41Lr8yaCDnp-0-59a91c48a8f33163ddb0d22a300cefce)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_01.jpg?sign=1739293075-WVbNq53BX4mKlhv7sxOv00I0a92JqtBa-0-0a4fbd30966f9a351c175313547e3e04)
2.3.2 control:控制UART设备
操作方法control用于控制UART设备行为,会根据传入的参数cmd(控制命令)对串口的行为进行相应的控制,例如配置设备、关闭设备、清除中断等操作,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_02.jpg?sign=1739293075-OjHLFhy6eVVkFY3U0Ae2C3wF7cLeT8RF-0-e02033e9c67fde5452761b0d8562cc49)
control方法的参数及返回值如表2-2所示,该方法根据控制命令cmd和控制参数arg控制串口设备,如开关中断及DMA的配置。
表2-2 control方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_03.jpg?sign=1739293075-thWYinfpsXHtHDrACVkGrSu9109Q96Wo-0-99dac00dcc923ee8089f9b6556ab1aa0)
在驱动实现时,需要完成的cmd取值情况如下所示。如果注释中标明“驱动中不用实现”,表示在实现驱动代码时不用考虑cmd的取值,因为这些取值无关底层设备,而系统对这些取值的处理也已经在设备驱动框架中实现了。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/38_01.jpg?sign=1739293075-ixLAvLqB6nA9H0h5fEfZeiz9JxrWxks6-0-2966568694baa412155ebd599a8255a6)
以下是STM32串口驱动的control方法的代码,该方法实现了6种cmd命令对应的操作。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/38_02.jpg?sign=1739293075-mvQccc4Mqf4FcfU1GOdUZGhYgfAcC3Gp-0-551c32177b0673ecce3e33d7fa10fd12)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/39_01.jpg?sign=1739293075-bPoWgXmLoUC7O5SJkcy8Xv8jRs8L2BRW-0-5b81d799ab58a265dbc158aa4deea9dc)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_01.jpg?sign=1739293075-IWURTFnWBTp6greOZorXo9AkEG4oVf3F-0-680a2aa2395e9f1780abe014192035e6)
2.3.3 putc:发送一个字符
操作方法putc用于发送一个字符的数据,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_02.jpg?sign=1739293075-n2x9HREDmTJPZPuEJqXxemV5LxkxsMmO-0-c1544627ac06736caefb9ea29575aab9)
putc方法的参数及返回值如表2-3所示。
表2-3 putc方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_03.jpg?sign=1739293075-v3DIwOosXjblzdxiSETcrbXdF61Tubha-0-2f136bd240bc77a241e7c9d5b6281eb8)
我们看一个具体的putc方法的示例代码,STM32串口驱动中putc方法实现的部分代码如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_04.jpg?sign=1739293075-QowFXkBMFFEcRKf2zQVTUQUVmHeqecB9-0-d2a4403b92233bedcc9e72e2f2163405)
在示例代码中,先利用接口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=1739293075-3puyqSlxwV39ZmVmVjxnIIyM7H0TIUqW-0-848ac259f2aa2fc16c48554bacad64e6)
2.3.4 getc:接收一个字符
操作方法getc用于从硬件寄存器中接收一个字符数据,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_01.jpg?sign=1739293075-RiTSasC1TX3AZUrTAO0vMlbuu8bJNnQj-0-87f049b12132a7c33ad1dc2e0b0b2e25)
getc方法的参数及返回值如表2-4所示。
表2-4 getc方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_02.jpg?sign=1739293075-vAarJjZIJM1kddIjGTM94hhYRycWHJxf-0-eab1b905dd0d308fe26b4689c19ed846)
我们看一个具体的getc方法的示例代码,STM32串口驱动中getc方法实现的部分代码如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_03.jpg?sign=1739293075-PlHB87izzoM5ofCLgBcZeIzzFZ3ewRYt-0-3d359009f169602731010388bcd844a0)
在示例代码中,同样先获取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=1739293075-AIhCdlAmiuKSP64hLaBNf5Q8gpMdbHXN-0-a6be57cd477c7d439df6a056742ad7b7)
2.3.5 transmit:数据发送
操作方法transmit一般用于中断和DMA的数据发送,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_02.jpg?sign=1739293075-2tYsD8Ri6uFPLB0YaXRMfTdvpc1FRLYK-0-28dec1bd8decc03524441330af472930)
transmit方法的参数及返回值如表2-5所示。
表2-5 transmit方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_03.jpg?sign=1739293075-bCPVzof3FHas9xmlwPDRrS9lB8AIPaoj-0-8fd382742e871846de018b11971c15e9)
其中参数tx_flag可取值如下,驱动开发者可以根据以下两种情况完成驱动:
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_04.jpg?sign=1739293075-TM2PpFXEwJtbb8MlSjvI7nic5Qy7XHVF-0-8905c080a96d52e2facdc9255046378d)
我们来看一个在STM32上实现串口transmit方法的示例代码:
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_05.jpg?sign=1739293075-NDirfnzIsc27Rq0gvUl0EW39Hd2iVOtY-0-6f540310cfb4915c9581ecaa8253d667)
在示例代码中,首先检测是否使用DMA发送数据,然后直接调用了STM32 HAL库提供的DMA传输接口,完成了数据的发送。