Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Devices
设备驱动组件
小白初探RT-Thread驱动注册机制套路......
发布于 2019-11-15 14:43:15 浏览:3183
订阅该版
RTT设备驱动的注册需要了解2个结构体和1个注册函数。 ```c struct rt_device { struct rt_object parent; //继承rt_object对象,不用管 enum rt_device_class_type type; //设备类型 rt_uint16_t flag; //设备标志,设备允许访问权限 rt_uint16_t open_flag; //当前设备的打开方式,当关闭时会根据这个标志去关闭设备 rt_uint8_t ref_count; //打开次数 打开+1 关闭-1,到0时才会调用close函数 rt_uint8_t device_id; //设备的ID号,感觉没用到,应该是系统自动分配ID号吧 rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size); //接收回调函数 rt_err_t (*tx_complete)(rt_device_t dev, void *buffer); //发送回调函数 const struct rt_device_ops *ops; //设备操作方法 } struct rt_device_ops { rt_err_t (*init) (rt_device_t dev); //初始化 rt_err_t (*open) (rt_device_t dev, rt_uint16_t oflag); //打开 rt_err_t (*close) (rt_device_t dev); //关闭 rt_size_t (*read) (rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); //读 rt_size_t (*write) (rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);//写 rt_err_t (*control)(rt_device_t dev, int cmd, void *args); //配置设备 }; ``` 注册函数 ```c rt_err_t rt_device_register( rt_device_t dev, //设备结构体指针 const char *name, //设备名称 rt_uint16_t flags) // 设备可以以哪种方式打开设备 /************************实现OPS结构里边的函数************************************************************/ ops结构体里边的函数都是自行编写 实现对硬件的操作,当应用层调用 rt_device_xxx时会根据参数dev自行找到这些函数。 /* 初始化函数 */ rt_err_t test_init(rt_device_t dev) { rt_kprintf("Init_func...
"); /* *初始化硬件设备 ........... */ return 0; } /* 打开函数 oflag:打开方式 <在找到这个函数前 设备驱动框架会查看这个设备是否已经打开过,没有打开过就自动先调用init才进入这个函数> */ rt_err_t test_open(rt_device_t dev,rt_uint16_t oflag) { rt_kprintf("open_func...
"); rt_kprintf("Type:0x%x
",oflag); /* **判断oflag是否正确,错误则返回错误码 <比如 设备flag 没有读方式,用读方式打开就是错误> 其他操作。。。。。 */ return 0; } ``` 关闭函数 这个对应裸机的编写时初始化硬件的函数,当应用层调用`rt_device_close(dev)`,系统会根据`dev`找到这个函数,在函数里边清除掉已经打开的标志并DISABLE硬件 ```c rt_err_t test_close(rt_device_t dev) { rt_kprintf(" close_func...
"); return 0; /* *清打开标志 *根据已打开标志去disable硬件 */ } /* 读函数 pos: 偏移量,字符设备用不到 buffer:用来装从寄存器读出来的数据 size:读取字节大小,字符设备是1,如果是块设备就是整块读那就非1 返回读取数据大小。 */ rt_size_t test_read(rt_device_t dev,rt_off_t pos,void *buffer, rt_size_t size) { char data=0xff; rt_memcpy(buffer,(void*)&data,size); return size; } /* 写数据 和读一样,只不过buffer是装有要往寄存器写的数据 */ rt_size_t test_write(rt_device_t dev,rt_off_t pos, const void *buffer, rt_size_t size) { char *buf = (char*)buffer; for(int i = 0;i
"); return size; } /* 控制/配置函数 cmd:控制命令,这个是自定义命令 *args: 用来配置设备的数据,这个数据可以自定义封装成结构体,应用层需要配置则向这个结构体赋 值,通过void指针方式传进来,强制转成配置结构体类型,这样驱动层就能得到应用层要配置的参数,根据参数去配置驱动。 */ rt_err_t test_control(rt_device_t dev, int cmd, void *args) { rt_kprintf("CMD:%x
",cmd); rt_kprintf("private:%x
",*(uint16_t*)args); return 0; } /*定义rt_device_ops类型变量 并拿上边的函数去初始化ops结构体变量*/ static const struct rt_device_ops ops = \{test_init,test_open,test_close,test_read,test_write,test_control}; /*定义一个rt_device 变量*/ static struct rt_device dev ; /* 注册函数。 这个函数将设备注册到设备驱动框架 */ void test_register(void) { /*****模拟设备的注册*********/ uint16_t Private_data=0xFF;//私有数据可以是任何类型的变量,这个可以用来存储设备私有的数据 rt_device_t device = &dev;// 定义一个rt_device_t类型变量,让它指向dev全局变量 device->rx_indicate = RT_NULL; //回调函数没有,这2个函数在应用层通过一条API设置 device->tx_complete = RT_NULL; device ->type=RT_Device_Class_Char; // 字符设备 device->ops = &ops; //指向操作方法结构体,这样才能找到读、写、打开 等等函数 device->user_data = &Private_data; //设备私有数据,随便保存个值 /*调用注册函数*/ rt_device_register(device, //设备结构体指针 "test_dev",//设备名字 RT_DEVICE_FLAG_RDW //设备所拥有的打开方式,多种方式用“|”。 ); } /******************写一个函数,导出到控制台方便测试*********************/ static void test_cmd(int argc,char **argv) { rt_device_t dev = rt_device_find("test_dev"); //查找设备,设备名称是注册的设备名称 uint16_t buf=0x1234; //备用 if( *argv[1]== 'i') //输入 “tset_cmd i ” 初始化设备 { rt_device_init(dev); // 调用rt_dev_init初始化设备,它将调用底层驱动的 test_init } if( *argv[1]== 'o') { rt_device_open(dev,RT_DEVICE_FLAG_INT_TX); //打开 } if( *argv[1]== 'c') { rt_device_close(dev); //关闭 } if( *argv[1]== 'r') //读 { rt_device_read(dev,0,&buf,1); rt_kprintf("0x%x
",buf); } if( *argv[1]== 'w') { rt_device_write(dev,0,&buf,2); //写 } if( *argv[1]== 't') { rt_device_control(dev,0x11FF,&buf); //配置 } } MSH_CMD_EXPORT(test_cmd,"deviceTest"); ```
![1.jpg](https://oss-club.rt-thread.org/uploads/201911/15/144412tbtwiizoicmo5ucn.jpg)
![2.jpg](https://oss-club.rt-thread.org/uploads/201911/15/144412yt3lu1xj09899i39.jpg)
![3.jpg](https://oss-club.rt-thread.org/uploads/201911/15/144412d5d678za527f28n2.jpg)
![4.jpg](https://oss-club.rt-thread.org/uploads/201911/15/144412ijnr7m637gdgi8je.jpg)
查看更多
4
个回答
默认排序
按发布时间排序
pl4636
2019-11-15
这家伙很懒,什么也没写!
/*********************烧写到 开发板***********************************************************/ 开始测试 1.输入 list_device 查看设备。 看到test_dev,说明已经注册到系统 [attach]12270[/attach] 2. 输入 tset_cmd i 初始化设备。 [attach]12271[/attach] init驱动函数打印出了 `"Init_func...."`,说明应用层调用API已经找到了底层对应的函数。 3.输入 tset_cmd o 初始化设备。 [attach]12272[/attach] 打开类型是0x03 ,0x03是读写方式打开 4.尝试设备未初始化就打开。 [attach]12273[/attach] 没有打开的情况下,会自动初始化,后打开 。。。 。。。。。。读写就不试了
左耳朵的耗子
2019-11-16
这家伙很懒,什么也没写!
熟悉驱动构架后可以自己做相应的驱动了
pl4636
2019-11-16
这家伙很懒,什么也没写!
>熟悉驱动构架后可以自己做相应的驱动了 我想问问你们在做单片机开发时是否没每个设备都会注册到系统,还是直接调用?
左耳朵的耗子
2019-11-16
这家伙很懒,什么也没写!
>我想问问你们在做单片机开发时是否没每个设备都会注册到系统,还是直接调用? ... 看设备的复杂度,如果简单的,可以注册,如果复杂,驱动比较难搞,调通能用不不错了,灵活应变吧。
jerry2cool
2020-07-01
这家伙很懒,什么也没写!
感谢分享。。。
撰写答案
登录
注册新账号
关注者
0
被浏览
3.2k
关于作者
pl4636
这家伙很懒,什么也没写!
提问
2
回答
2
被采纳
0
关注TA
发私信
相关问题
1
问个问题,ili9320驱动里面rt_hw_lcd_draw_blit_line 这个函数是干什么用的
2
LCD双缓冲有什么好的办法实现
3
LCD NT35510 驱动代码
4
io设备驱动的疑惑与建议
5
液晶屏驱动 U8g2 移植
6
求助:在模板上添加LCD模块出现L6406E错误
7
hwtimer硬件定时器驱动和使用经验
8
硬件定时器超时时间计算问题
9
请教spi驱动lcd显示屏问题
10
rtt-master(3.1.1)bsp—armfly中drv_lcd.c中是不是错了啊?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
TinyUSB Demo运行教程
2
RT-Thread学习大礼包一键带走!
3
freemodbus从机调试说明
4
【1024】瑞萨 RA 系列 BSP 制作与适配最新版本的 Keil 、 RSC、固件,较新的 FSP
5
基于 RT-Thread 星火一号开发板的俄罗斯方块
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
ART-Pi
FinSH
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
cubemx
PWM
flash
packages_软件包
freemodbus
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
ulog
C++_cpp
at_device
本月问答贡献
出出啊
1516
个答案
342
次被采纳
小小李sunny
1440
个答案
289
次被采纳
张世争
799
个答案
171
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
1
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
4
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部