驱动层负责创建设备实例,并注册到I/O设备管理器中,可以通过静态声明的方式创建设备实例,也可以用以下接口动态创建。
rt_device_t rt_device_create(int type,int attach_size);
调用该接口时,系统会从动态堆内存中分配一个设备控制块,大小为struct re_device和attach_size的和。
设备被创建后,需要实现它访问硬件的操作方法。
/**
* operations set for device object
*/
struct rt_device_ops
{
/* common device interface */
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);
};
当一个动态创建的设备不再需要使用时可以通过如下函数来销毁:
void rt_device_destroy(rt_device_t device);
设备被创建后,需要注册到I/O设备管理器中,应用程序才能够访问,注册设备的函数如下所示:
rt_err_t rt_device_register(rt_device_t dev, const char*name, rt_uint8_t flags);
返回
应当避免重复注册已经注册的设备,以及注册相同名字的设备。
flags参数支持(可以采用或的方式支持多种参数)
/**
* device flags defitions
*/
#define RT_DEVICE_FLAG_DEACTIVATE 0x000 /**< device is not not initialized */
#define RT_DEVICE_FLAG_RDONLY 0x001 /**< read only */
#define RT_DEVICE_FLAG_WRONLY 0x002 /**< write only */
#define RT_DEVICE_FLAG_RDWR 0x003 /**< read and write */
#define RT_DEVICE_FLAG_REMOVABLE 0x004 /**< removable device */
#define RT_DEVICE_FLAG_STANDALONE 0x008 /**< standalone device */
#define RT_DEVICE_FLAG_ACTIVATED 0x010 /**< device is activated */
#define RT_DEVICE_FLAG_SUSPENDED 0x020 /**< device is suspended */
#define RT_DEVICE_FLAG_STREAM 0x040 /**< stream mode */
#define RT_DEVICE_FLAG_INT_RX 0x100 /**< INT mode on Rx */
#define RT_DEVICE_FLAG_DMA_RX 0x200 /**< DMA mode on Rx */
#define RT_DEVICE_FLAG_INT_TX 0x400 /**< INT mode on Tx */
#define RT_DEVICE_FLAG_DMA_TX 0x800 /**< DMA mode on Tx */
#define RT_DEVICE_OFLAG_CLOSE 0x000 /**< device is closed */
#define RT_DEVICE_OFLAG_RDONLY 0x001 /**< read only access */
#define RT_DEVICE_OFLAG_WRONLY 0x002 /**< write only access */
#define RT_DEVICE_OFLAG_RDWR 0x003 /**< read and write */
#define RT_DEVICE_OFLAG_OPEN 0x008 /**< device is opened */
#define RT_DEVICE_OFLAG_MASK 0xf0f /**< mask of open flag */
设备流模式RT_DEVICE_FLAG_STREAM参数用于向串口终端输出字符串,当输出的字符串是“\n”时,自动在前面补一个“\r”做分行。
注册成功的设备可以在FinSH命令行使用list_device命令查看系统中所有的设备信息,包括设备名称,设备类型和设备被打开次数。
msh />list_device
device type ref count
-------- -------------------- ----------
e0 Network Interface 0
sd0 Block Device 1
rtc RTC 0
uart1 Character Device 0
uart0 Character Device 2
msh />
当设备注销后,设备将从设备管理器中移除,也就不能再通过设备名查找搜索到该设备。注销设备后不会释放设备控制块占用的内存。
rt_err_t rt_device_unregister(rt_device_t dev);
在C语言中,在struct前面使用const static修饰代表以下含义:
const static struct rt_device_ops wdt_ops =
{
rt_watchdog_init,
rt_watchdog_open,
rt_watchdog_close,
RT_NULL,
RT_NULL,
rt_watchdog_control,
};
rt_err_t rt_hw_watchdog_register(struct rt_watchdog_device *wtd,
const char *name,
rt_uint32_t flag,
void *data)
{
struct rt_device *device;
RT_ASSERT(wtd != RT_NULL);
device = &(wtd->parent);
device->type = RT_Device_Class_Miscellaneous;
device->rx_indicate = RT_NULL;
device->tx_complete = RT_NULL;
device->ops = &wdt_ops;
device->user_data = data;
/* register a character device */
return rt_device_register(device, name, flag);
}