![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=1739152872-cWhoSqX2h8KyOvHgYdnJZ9fuvjL6XPX1-0-4cdf7846efb9ff1ce2f3ae3b59bccfd2)
这些操作方法会完成串口的基本操作,例如: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=1739152872-0azrbEytmJ7ieLy3mu6o62BEy0gV3gnL-0-946afdf6c8b25c6b42a6a3f90296885c)
configure方法的参数及返回值如表2-1所示。
表2-1 configure方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_02.jpg?sign=1739152872-2cEgG3hxzLJkCLIFsUxZF1qYjfCijHFo-0-23880d3094894d6422fe7dc525bdde73)
参数cfg是串口设备的配置参数,结构原型为struct serial_configure,如下所示。configure方法根据这些成员的值进行配置。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_03.jpg?sign=1739152872-tTOCnbd9N2oRLxY5FkTBoSa388JiSR8V-0-18df37cf7da1811aecfcaa4afbd7aab4)
成员可取值以及参考的默认取值如下所示,读者可以根据实际用途选择合适的值。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/35_04.jpg?sign=1739152872-Wj3qirjw2h0xDe5CbEqyBF5iFytJF8py-0-0b280051102e9a0f682a63cb89200853)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/36_01.jpg?sign=1739152872-uK0197AnWmY6FGiEJ0IY1vHPQmPNLv8M-0-720358905aab09ca5be80b2d3277c69c)
使用STM32串口驱动configure方法的实现示例如下。其内容主要是初始化STM32 UART的句柄,将cfg配置参数赋值给STM32 UART的句柄的成员,然后对串口进行初始化操作。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/36_02.jpg?sign=1739152872-AL4qtH1nuo1MmHPLd5gky9sjzvL2WJDE-0-eb9bae5950d4a55903888a7304786928)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_01.jpg?sign=1739152872-1RJ0GaSKLkrVKF1RYAuv55B6F2YGEBGw-0-d6ea47a2451983e4d9bca46e62b710bb)
2.3.2 control:控制UART设备
操作方法control用于控制UART设备行为,会根据传入的参数cmd(控制命令)对串口的行为进行相应的控制,例如配置设备、关闭设备、清除中断等操作,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_02.jpg?sign=1739152872-m1KhrkOpkOkjyYaTQUQr5rxE9tWKrOHb-0-5c91aca4780216bfa5ea54a051891e9f)
control方法的参数及返回值如表2-2所示,该方法根据控制命令cmd和控制参数arg控制串口设备,如开关中断及DMA的配置。
表2-2 control方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/37_03.jpg?sign=1739152872-pmrwEoDCWzSeM0753sygJFlJXaPpjDB4-0-1dc28dcaab139267244c6b735d4573eb)
在驱动实现时,需要完成的cmd取值情况如下所示。如果注释中标明“驱动中不用实现”,表示在实现驱动代码时不用考虑cmd的取值,因为这些取值无关底层设备,而系统对这些取值的处理也已经在设备驱动框架中实现了。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/38_01.jpg?sign=1739152872-wzu8RUxo2AOszZff6LFowRqcrlwFh5Pk-0-5c3b3351a16f878cfd38ee56abdaa3e9)
以下是STM32串口驱动的control方法的代码,该方法实现了6种cmd命令对应的操作。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/38_02.jpg?sign=1739152872-orw1HOdIMuBzthw4pdqIdiaOLWNWmhrs-0-3c682558d4f31fe6f3ae2049c9d3cab1)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/39_01.jpg?sign=1739152872-riIdTb9nxyfD34fLUHRBiAFRLyGFYlBS-0-a959f05bbfef7dc19882ed95b02ee10f)
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_01.jpg?sign=1739152872-kUGakj8JRYOWs4HYSZhUU6cUoDht6bRC-0-c104169d41b90552e43f955f0a72c321)
2.3.3 putc:发送一个字符
操作方法putc用于发送一个字符的数据,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_02.jpg?sign=1739152872-mGeskmKN6Ukn556p46uT2xUQlnlucIuo-0-43f4dade97f6f8e85b5f51fd6de5a971)
putc方法的参数及返回值如表2-3所示。
表2-3 putc方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_03.jpg?sign=1739152872-Onypey8yoMWesU1W22A6oHJVDZa1wnnB-0-496a5ee2d4f65666d6f5c99ca7e90b11)
我们看一个具体的putc方法的示例代码,STM32串口驱动中putc方法实现的部分代码如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/40_04.jpg?sign=1739152872-Y1yDqUtSHtHQaB52PMicUCek9OjH1LJe-0-147844bc52868a3f1348519b50078ea8)
在示例代码中,先利用接口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=1739152872-g1Kj9FREkaveheHNDLAZbPEdK3rRQM1j-0-ec0f670763a6c687a5a5c4f2a6142040)
2.3.4 getc:接收一个字符
操作方法getc用于从硬件寄存器中接收一个字符数据,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_01.jpg?sign=1739152872-R7hoeYSCJ3A5kkTdIqfV3cYLZCAXYgpg-0-d7bfe00f8969936830299b912b28fc0e)
getc方法的参数及返回值如表2-4所示。
表2-4 getc方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_02.jpg?sign=1739152872-OtzsNaGWWxlyXDcj7OVJRNMaRhtvmgyo-0-8121a1bc090fe2e40e96c04e590a6eb6)
我们看一个具体的getc方法的示例代码,STM32串口驱动中getc方法实现的部分代码如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/41_03.jpg?sign=1739152872-hFA2MkU1QoyAWRCdIQz6gY4M2gK29JDf-0-d375868a1d1803858b954f2aeb660ced)
在示例代码中,同样先获取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=1739152872-1xn9rsUyRzzpLhuYpXCCIDAs5qhkG9dF-0-b51c279e43bd138f9d28344b8d4842a7)
2.3.5 transmit:数据发送
操作方法transmit一般用于中断和DMA的数据发送,其原型如下所示。
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_02.jpg?sign=1739152872-HjxwsB5U48thkHwtNE8s7ONI5l61GvYS-0-191d94d96adb19f33fd16279ed43df62)
transmit方法的参数及返回值如表2-5所示。
表2-5 transmit方法的参数及返回值
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_03.jpg?sign=1739152872-zNOSrXqjIhifbdnXeEg5SJtXmWqHxJ2t-0-577bbffb6e746284250b061c73e04662)
其中参数tx_flag可取值如下,驱动开发者可以根据以下两种情况完成驱动:
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_04.jpg?sign=1739152872-A5DbjE05Xv1Cu4FX4kA7A4yREZDJplhy-0-db1cbc4547713ef6ff472a4e52a610b9)
我们来看一个在STM32上实现串口transmit方法的示例代码:
![](https://epubservercos.yuewen.com/8B2CE7/25929799901480006/epubprivate/OEBPS/Images/42_05.jpg?sign=1739152872-Ex0j3r5tFa5Fj9wqeKKd0AU5QXqIjBMc-0-4e824f595f810e06130c33c8ef420a9a)
在示例代码中,首先检测是否使用DMA发送数据,然后直接调用了STM32 HAL库提供的DMA传输接口,完成了数据的发送。