参考了几个drv_xxx.c的设备驱动模型,查找共同点,来了解设备的创建、注册、调用功能;并梳理一个创建、注册、初始化、调用的过程
①、首先是创建设备,使用rt_device_create函数:
②、设备创建成功后,对设备编写相应的接口函数,如init、open、close、control等,并和device对应的接口相对接;
③、进行设备注册,在使用前根据设备名进行设备查找,如果查找成功,返回ok,如果查找失败,返回err;
上面三步后,就完成设备就对接了,可以将以上封装在一个函数中进行初始化;
④、接着就可以通过rt_device_init/open/close等应用层接口函数进行控制了。
写一个简单的创建、注册、初始化、调用的过程
将设备创建、接口对接、设备注册放在同一个函数device_reg_test中进行,通过导出到MSH_CMD命令调用
①、使用rt_device_create函数创建设备:rt_device_t dev = rt_device_create(RT_Device_Class_Char, 32);
第一个参数是设备类型,这里用字符设备;第二个参数是数据大小,根据数据的大小来传参。返回值为指针类型rt_device_t;
②、将rtdef.h的通用接口复制过来,再其基础之上进行更改
对函数指针修改,把指针处改为函数名:
将自己编写的函数与I/O设备的接口进行对接
③、设备注册,注册设备的设备名为"dev_test",模式为读写模式;
rt_err_t ret= rt_device_register(dev, "dev_test", RT_DEVICE_FLAG_RDWR);
if(ret!=RT_EOK)
{
rt_kprintf("rt_device_register failed!\n");
return RT_ERROR;
}
④、通过上层接口函数,初始化并打开设备,进行调用
test code:
#include "device_test.h"
static rt_err_t my_device_init_test(rt_device_t dev)
{
rt_kprintf("my_device_init_test run~\r\n");
return 0;
}
static rt_err_t my_device_open_test(rt_device_t dev,rt_uint16_t flag)
{
rt_kprintf("my_device_open_test run~\r\n");
return 0;
}
static rt_err_t my_device_close_test(rt_device_t dev)
{
rt_kprintf("my_device_close_test run~\r\n");
return 0;
}
static rt_err_t my_device_control_test(rt_device_t dev, int cmd, void *args)
{
rt_kprintf("my_device_control_test run~\r\n");
switch (cmd) {
case 0x01:
rt_kprintf("my_device_control_test cmd:01\r\n");
break;
case 0x02:
rt_kprintf("my_device_control_test cmd:02\r\n");
break;
default:
rt_kprintf("my_device_control_test default\r\n");
break;
}
return 0;
}
static int device_reg_test(int argc, char *argv[])
{
rt_device_t dev = rt_device_create(RT_Device_Class_Char, 32);
if(dev == RT_NULL)
{
rt_kprintf("rt_device_create failed!\n");
return RT_ERROR;
}
// I/O设备接口对接
dev->init = my_device_init_test;
dev->open = my_device_open_test;
dev->close = my_device_close_test;
dev->control = my_device_control_test;
rt_err_t ret= rt_device_register(dev, "dev_test", RT_DEVICE_FLAG_RDWR);
if(ret!=RT_EOK)
{
rt_kprintf("rt_device_register failed!\n");
return RT_ERROR;
}
rt_kprintf("rt_device_register success!\n");
return RT_EOK;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(device_reg_test, a test example for my I/O device register);
static int device_use_test(int argc, char *argv[])
{
rt_device_t dev= rt_device_find("dev_test");
if(dev==RT_NULL)
{
rt_kprintf("rt_device_find failed!\n");
return RT_ERROR;
}
rt_device_init(dev);
rt_device_open(dev, RT_DEVICE_FLAG_RDWR);
rt_device_control(dev, 0x02, RT_NULL);
rt_device_close(dev);
return RT_EOK;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(device_use_test, a test example for my I/O device use);
static int device_ureg_test(int argc, char *argv[])
{
rt_device_t dev = rt_device_find("dev_test");
if(dev==RT_NULL)
{
rt_kprintf("rt_device_find failed!\n");
return RT_ERROR;
}
rt_err_t ret = rt_device_unregister(dev);
if(ret!=RT_EOK)
{
rt_kprintf("rt_device_unregister failed!\n");
return RT_ERROR;
}
rt_kprintf("rt_device_unregister OK!\n");
return RT_EOK;
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(device_ureg_test, a test example for my I/O device unregister);
在串口助手中,通过MSH_CMD命令调用,观察状态:
help
RT-Thread shell commands:
list_device - list device in system
list_timer - list timer in system
list_mempool - list memory pool in system
list_msgqueue - list message queue in system
list_mailbox - list mail box in system
list_mutex - list mutex in system
list_event - list event in system
list_sem - list semaphore in system
list_thread - list thread
version - show RT-Thread version information
clear - clear the terminal screen
free - Show the memory usage in the system.
ps - List threads in the system.
help - RT-Thread shell help.
list_alarm - list alarm info
date - get date and time or set (local timezone) [year month day hour min sec]
device_ureg_test - a test example for my I/O device unregister
device_use_test - a test example for my I/O device use
device_reg_test - a test example for my I/O device register
msh >
msh >device_use_test
rt_device_find failed!
msh >
msh >device_reg_test
rt_device_register success!
msh >
msh >device_use_test
my_device_init_test run~
my_device_open_test run~
my_device_control_test run~
my_device_control_test cmd:02
my_device_close_test run~
msh >
msh >device_reg_test
rt_device_register failed!
msh >
msh >list_device
device type ref count
-------- -------------------- ----------
dev_test Character Device 0
rtc RTC 0
uart2 Character Device 0
uart1 Character Device 2
pin Pin Device 0
msh >
msh >device_ureg_test
rt_device_unregister OK!
msh >
msh >list_device
device type ref count
-------- -------------------- ----------
rtc RTC 0
uart2 Character Device 0
uart1 Character Device 2
pin Pin Device 0
msh >
msh >device_reg_test
rt_device_register success!
msh >
msh >device_use_test
my_device_init_test run~
my_device_open_test run~
my_device_control_test run~
my_device_control_test cmd:02
my_device_close_test run~
msh >
msh >
通过以上,对设备的框架有了自己的认识,继续学习~