Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
Devices
小白初探RT-Thread驱动注册机制套路......
发布于 2019-11-15 14:43:15 浏览:1915
订阅该版
* 本帖最后由 pl4636 于 2019-11-15 14:47 编辑 * RTT设备驱动的注册需要了解2个结构体和1个注册函数。 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); //配置设备 }; 注册函数 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硬件 */ 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");
查看更多
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
这家伙很懒,什么也没写!
[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=469149&ptid=422614][color=#999999]左耳朵的耗子 发表于 2019-11-16 10:07[/color][/url][/size] 熟悉驱动构架后可以自己做相应的驱动了[/quote] 我想问问你们在做单片机开发时是否没每个设备都会注册到系统,还是直接调用?
左耳朵的耗子
2019-11-16
这家伙很懒,什么也没写!
[quote][size=2][url=forum.php?mod=redirect&goto=findpost&pid=469154&ptid=422614][color=#999999]pl4636 发表于 2019-11-16 10:40[/color][/url][/size] 我想问问你们在做单片机开发时是否没每个设备都会注册到系统,还是直接调用? ...[/quote] 看设备的复杂度,如果简单的,可以注册,如果复杂,驱动比较难搞,调通能用不不错了,灵活应变吧。
jerry2cool
2020-07-01
这家伙很懒,什么也没写!
感谢分享。。。
撰写答案
登录
注册新账号
关注者
0
被浏览
1.9k
关于作者
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
五分钟玩转RT-Thread新社区
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
6
国产MCU移植系列教程汇总,欢迎查看!
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
RS485驱动包的使用
2
当做一件事,坚持到第二十年 ——Open-SkyEye强势回归!
3
stm32f407zgt6新建工程
4
【github】rt-thread BSP 目录所有支持开发板整理展示
5
使用 D1s (RDC2022 纪念版) 连接 thingspeak
热门标签
RT-Thread Studio
串口
LWIP
SPI
Env
AT
FinSH
ART-Pi
Bootloader
CAN总线
Hardfault
文件系统
USB
DMA
RT-Thread
线程
stm32
RT-Thread Nano
SCons
MQTT
ESP8266
ota
packages_软件包
UART
rtthread
I2C
RTC
freemodbus
flash
cubemx
rt-smart
W5500
定时器
FAL
PWM
ADC
BSP
SDIO
msh
AB32VG1
Debug
C++_cpp
socket
SFUD
中断
编译报错
MicroPython
keil
LVGL
dfs
本月问答贡献
RTT_逍遥
3
个答案
2
次被采纳
crystal266
4
个答案
1
次被采纳
用户名由3_15位
4
个答案
1
次被采纳
xiaorui
3
个答案
1
次被采纳
小小李sunny
1
个答案
1
次被采纳
本月文章贡献
出出啊
4
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
crystal266
1
篇文章
1
次点赞
whj467467222
2
篇文章
2
次点赞
张世争
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部