• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

【Rt-thread学习记】:设备篇之uart设备。。。

猿小A  : 小B快开门,我发现了你上一篇讲的一个大bug,哈哈哈。。。

猿小B  :你发现什么了。。。

猿小A  : 上次你讲的应该是pin设备吧,我仔细研究了一下,并不是所有的驱动都是注册到IO设备管理器中,也有的之注册到了设备驱动层中,像你昨天讲的pin设备。。。

猿小B : 你讲的是对的,可那又怎样呢,构架都是我写的,难免表达会有错误。。。

猿小A : ....

猿小B : 这一篇开始讲一下用的比较多的uart设备吧。。。

全部回复(15)
正序查看
倒序查看
2019-08-23 10:01

猿小B:要讲解uart的设备使用之前,就需要先选择相应的uart端口,这里因为finsh组件占用了uart1端口,所以不能选uart1,这里就需要动手做跟线接入uart2端口,另一端我们选择接电脑,这样可以借助串口助手直接进行uart测试和验证。

猿小A : 开始你的表演。。。

0
回复
2019-08-23 10:21
@程序小白
猿小B:要讲解uart的设备使用之前,就需要先选择相应的uart端口,这里因为finsh组件占用了uart1端口,所以不能选uart1,这里就需要动手做跟线接入uart2端口,另一端我们选择接电脑,这样可以借助串口助手直接进行uart测试和验证。猿小A:开始你的表演。。。[图片][图片][图片]

猿小B:接下来就是做线,接到板子上,对接串口转接小板,接入电脑,就完成串口通信的硬件部分工作了。

0
回复
zhifubao
LV.1
4
2019-08-23 11:23
可以打印“HELLO WORLD”了。
0
回复
2019-08-23 14:19
@程序小白
猿小B:接下来就是做线,接到板子上,对接串口转接小板,接入电脑,就完成串口通信的硬件部分工作了。[图片][图片][图片]

猿小A : 接下来是不是该讲讲我发现的问题了,是不?

猿小B :接下来来讨论下,你提出的问题,首先那的确是个问题,对比一下两个sample的代码就会发现,其接口API的提供者并不来源于同一层,先讲一下层的概念,这里的可以理解为4层,每一层其实只是虚化的概念,这里用实体来代替,更好理解一些:

项目工程:                           PIN应用                                                                      Uart应用

应用程序:                          pin_beep_sample                                                      uart_sample.c

I/O设备管理层:                  无                                                                           device.c

设备驱动框架层:                 pin.c                                                                        serial.c

设备驱动层:                       drv_gpio.c                                                                drv_usart.c


也就是真的是有的驱动没有注册到device.c 也就是IO设备管理层,而是通过设备驱动框架层直接应用,like Pin设备。


0
回复
2019-08-23 15:24
@zhifubao
可以打印“HELLOWORLD”了。
那必须的的  
0
回复
2019-08-23 17:27
@程序小白
猿小A:接下来是不是该讲讲我发现的问题了,是不?猿小B:接下来来讨论下,你提出的问题,首先那的确是个问题,对比一下两个sample的代码就会发现,其接口API的提供者并不来源于同一层,先讲一下层的概念,这里的可以理解为4层,每一层其实只是虚化的概念,这里用实体来代替,更好理解一些:项目工程:                          PIN应用                                                                     Uart应用应用程序:                         pin_beep_sample                                                     uart_sample.cI/O设备管理层:               无                                                                         device.c设备驱动框架层:                pin.c                                                                       serial.c设备驱动层:                      drv_gpio.c                                                               drv_usart.c[图片]也就是真的是有的驱动没有注册到device.c也就是IO设备管理层,而是通过设备驱动框架层直接应用,likePin设备。

猿小B:接下来介绍一下uart设备,IO设备管理层对外提供的API接口:

1.查找串口设备

rt_device_t rt_device_find(const char* name);

参数:                                描述:

name                                  设备名称

返回                                   ————————————

设备句柄                             查找到对象设备将返回相应的设备句柄。

2.打开串口设备:rt_err_t rt_device_open(rt_device_t dev,rt_uint16_t oflags);

参数:                                 描述:

dev                                      设备句柄

oflags                                   设备模式标志

返回                                     ————————————

RT_EOK                                 设备打开成功

-RT_EBUSY                            如果设备注册时指定的参数中包括RT_DEVICE_FLAG_STANDALONE参数,此                                              设备将不允许重复打开

其它错误码                            设备打开失败

oflags参数支持下列取值(可以采用或的方式支持多种取值):

#define RT_DEVICE_FLAG_STREAM                           0X040/*流模式*/

#define RT_DEVICE_FLAG_INT_RX                            0X100/*中断接收模式*/

#define RT_DEVICE_FLAG_DMA_RX                           0x200/*DMA接收模式*/

#define RT_DEVICE_FLAG_INT_TX                            0X400/*中断发送模式*/

#define RT_DEVICE_FLAG_DMA_TX                           0X800/*DMA发送模式*/

0
回复
2019-08-26 14:34
@程序小白
猿小B:接下来介绍一下uart设备,IO设备管理层对外提供的API接口:1.查找串口设备rt_device_trt_device_find(constchar*name);参数:                               描述:name                                 设备名称返回                                  ————————————设备句柄                            查找到对象设备将返回相应的设备句柄。2.打开串口设备:rt_err_trt_device_open(rt_device_tdev,rt_uint16_toflags);参数:                                描述:dev                                     设备句柄oflags                                  设备模式标志返回                                    ————————————RT_EOK                                设备打开成功-RT_EBUSY                           如果设备注册时指定的参数中包括RT_DEVICE_FLAG_STANDALONE参数,此                                             设备将不允许重复打开其它错误码                           设备打开失败oflags参数支持下列取值(可以采用或的方式支持多种取值):#defineRT_DEVICE_FLAG_STREAM                          0X040/*流模式*/#defineRT_DEVICE_FLAG_INT_RX                           0X100/*中断接收模式*/#defineRT_DEVICE_FLAG_DMA_RX                          0x200/*DMA接收模式*/#defineRT_DEVICE_FLAG_INT_TX                           0X400/*中断发送模式*/#defineRT_DEVICE_FLAG_DMA_TX                          0X800/*DMA发送模式*/

3.控制串口设备:rt_err_t rt_device_control(rt_device_t dev,rt_uint8_t cmd,void* arg);

参数:                                                  描述:

dev                                                       设备句柄

cmd                                                      命令控制字,可取值:RT_DEVICE_CTRL_CONFIG

arg                                                        控制的参数,可取类型:struct serial_configure

返回                                                       ————————

RT_EOK                                                  函数执行成功

-RT_ENOSYS                                           执行失败,dev为空

其它错误码                                             执行失败

cmd 和 arg 参数是被限定的参数,只能是一个值和一种类型。

4.发送数据:rt_size_t rt_device_write(rt_device_t dev,rt_off_t pos,const void* buffer,

                                                        rt_size_t size);

参数:                                               描述:

dev                                                    设备句柄

pos                                                    写入数据偏移量,此参数串口设备未使用,默认为0

buffer                                                 内存缓冲区指针,放置要写入的数据

size                                                    写入数据的大小

返回                                                    ——————————

写入数据的实际大小                              如果是字符设备,返回大小以字节为单位;

0                                                         需要读取当前线程的errno来判断错误状态


0
回复
2019-08-26 15:12
@程序小白
3.控制串口设备:rt_err_trt_device_control(rt_device_tdev,rt_uint8_tcmd,void*arg);参数:                                                 描述:dev                                                      设备句柄cmd                                                     命令控制字,可取值:RT_DEVICE_CTRL_CONFIGarg                                                       控制的参数,可取类型:structserial_configure返回                                                      ————————RT_EOK                                                 函数执行成功-RT_ENOSYS                                          执行失败,dev为空其它错误码                                            执行失败cmd和arg参数是被限定的参数,只能是一个值和一种类型。4.发送数据:rt_size_trt_device_write(rt_device_tdev,rt_off_tpos,constvoid*buffer,                                                       rt_size_tsize);参数:                                              描述:dev                                                   设备句柄pos                                                   写入数据偏移量,此参数串口设备未使用,默认为0buffer                                                内存缓冲区指针,放置要写入的数据size                                                   写入数据的大小返回                                                   ——————————写入数据的实际大小                             如果是字符设备,返回大小以字节为单位;0                                                        需要读取当前线程的errno来判断错误状态

5.设置发送完成回调函数:rt_err_t rt_device_set_tx_complete(rt_device_t dev,rt_err_t (*tx_done)(rt_device_t,void* buffer));

参数:                                                       描述:

dev                                                            设备句柄

tx_done                                                      回调函数指针

返回                                                            ——————————

RT_EOK                                                       设置成功

使用DMA发送模式才会调用这个回调函数

0
回复
2019-08-26 17:31
@程序小白
5.设置发送完成回调函数:rt_err_trt_device_set_tx_complete(rt_device_tdev,rt_err_t(*tx_done)(rt_device_t,void*buffer));参数:                                                      描述:dev                                                           设备句柄tx_done                                                     回调函数指针返回                                                           ——————————RT_EOK                                                      设置成功使用DMA发送模式才会调用这个回调函数[图片]

6.设置接收回调函数:rt_err_t rt_device_set_rx_indicate(rt_device_t dev,rt_err_t(*rx_ind)(rt_device_t dev,rt_size_t size));

参数:                                                        描述:

dev                                                            设备句柄

rx_ind                                                         回调函数指针

dev                                                            设备句柄(回调函数参数)

size                                                             缓冲区数据大小(回调函数参数)

返回                                                            ——————————

RT_EOK                                                      设置成功


该回调函数在DMA接收完成和中断接收一个字节的数据时都会被调用,这个很重要,有时候官方文档说的也不是特别清楚。


0
回复
2019-08-27 09:10
@程序小白
6.设置接收回调函数:rt_err_trt_device_set_rx_indicate(rt_device_tdev,rt_err_t(*rx_ind)(rt_device_tdev,rt_size_tsize));参数:                                                       描述:dev                                                           设备句柄rx_ind                                                        回调函数指针dev                                                           设备句柄(回调函数参数)size                                                            缓冲区数据大小(回调函数参数)返回                                                           ——————————RT_EOK                                                     设置成功该回调函数在DMA接收完成和中断接收一个字节的数据时都会被调用,这个很重要,有时候官方文档说的也不是特别清楚。[图片]

7.接收数据:rt_size_t rt_device_read(rt_device_t dev,rt_off_t pos,void* buffer,rt_size_t size);

参数:                                                          描述:

dev                                                                设备句柄

pos                                                                数据读取偏移量,块设备中使用,串口设备未使用

buffer                                                            缓冲区指针,读取的数据会被保存在缓冲区中

size                                                                读取数据的大小

返回                                                              ————————————————

读到数据的实际大小                                         如果是字符设备,返回大小以字节为单位

0                                                                  需要读取当前线程的errno来判断错误状态。

一般读取操作配合回调函数来使用为佳,因为在读取之前确保串口缓冲区的确收到了数据,这样可以降低读数据的时间开销及不需要处理无效数据等操作。

8. 关闭串口设备:rt_err_t rt_device_close(rt_device_t dev);

参数:                                                    描述:

dev                                                         设备句柄

返回                                                        ————————

RT_EOK                                                   关闭设备成功

-RT_ERROR                                               设备已经完全关闭,不能重复关闭设备

其它错误码                                                关闭设备失败

有打开设备,就会有关闭设备操作,为了降低误操作,退出设备驱动对于资源的占用,等工作,虽然在这里其实没什么太大的意义,她远不如xp一样的灵活,但是该有的理念还是得有的。


0
回复
2019-08-27 09:14
@程序小白
7.接收数据:rt_size_trt_device_read(rt_device_tdev,rt_off_tpos,void*buffer,rt_size_tsize);参数:                                                         描述:dev                                                               设备句柄pos                                                               数据读取偏移量,块设备中使用,串口设备未使用buffer                                                           缓冲区指针,读取的数据会被保存在缓冲区中size                                                               读取数据的大小返回                                                             ————————————————读到数据的实际大小                                        如果是字符设备,返回大小以字节为单位0                                                                 需要读取当前线程的errno来判断错误状态。一般读取操作配合回调函数来使用为佳,因为在读取之前确保串口缓冲区的确收到了数据,这样可以降低读数据的时间开销及不需要处理无效数据等操作。8.关闭串口设备:rt_err_trt_device_close(rt_device_tdev);参数:                                                   描述:dev                                                        设备句柄返回                                                       ————————RT_EOK                                                  关闭设备成功-RT_ERROR                                              设备已经完全关闭,不能重复关闭设备其它错误码                                               关闭设备失败有打开设备,就会有关闭设备操作,为了降低误操作,退出设备驱动对于资源的占用,等工作,虽然在这里其实没什么太大的意义,她远不如xp一样的灵活,但是该有的理念还是得有的。

本篇学习笔记的结束,用接收数据,错位输出的例子来结束吧 ~!

0
回复
yujunice
LV.5
13
2019-08-28 11:32

finsh组件占用了uart1端口,不能选uart1,

除了你说的手动方式,还有别的方式吗?

0
回复
其乐518
LV.2
14
2019-08-28 19:21
@程序小白
本篇学习笔记的结束,用接收数据,错位输出的例子来结束吧~![图片]
等到了合适的应用场合就会有意义的,一个真实的产品都是由很多小小的知识累积起来的
0
回复
RainG
LV.1
15
2019-08-30 09:51
打印“HELLO WORLD”了。
0
回复
2019-08-30 12:17
@yujunice
finsh组件占用了uart1端口,不能选uart1,除了你说的手动方式,还有别的方式吗?
用ENV工具可以将配置所有功能组件的uart口,不用手动调整的 
0
回复