【RTT-Studio】详细使用教程八:驱动框架编写

一、简介

RT-Thread Studio是一个基于Eclipse的集成开发环境,用于开发和调试RT-Thread实时操作系统。RT-Thread是一个开源的实时操作系统,其设备驱动模型包括IO设备管理层、设备驱动框架层和设备驱动层。

1.IO设备管理层
IO设备管理层是RT-Thread中最高层次的设备管理模块,主要职责是:

  • 提供设备的注册、注销接口。
  • 提供设备的打开、关闭、读取、写入等标准操作接口。
  • 管理系统中所有的设备,维护设备列表。

2.设备驱动框架层
设备驱动框架层为具体的设备驱动提供了统一的接口和抽象,实现了设备驱动的通用部分。它定义了设备的标准结构体和操作方法。

  • 结构体:struct rt_device
  • 设备信息:rt_device_ops
  • 设备操作函数:init(), open(), close(), read(), write(), control()

二、RTT-Thread-Studio具体实现

在创建一个设备的时候,可以按照以下方式进行设备创建:

  • 初始化设备驱动结构体
  • 填充相关信息和操作函数
  • 实现具体设备的操作函数
  • 注册设备到RT-Thread设备管理层
    以上创建方法针对所有设备的驱动层,都可以按照以上方式进行设备的创建,常见成一个设备之后,可以对设备进行一系列的操作,比如实现设备的初始化,设备的读和写,设备的打开和关闭,以及对设备进行控制,控制设备的操作,从而更加方便的操作设备。

三、注册设备

1.初始化设备驱动结构体
主要是通过定义设备用到的引脚、设备名称,和结构体变量,便于对设备进行整体控制和使用。

#define LOG_TAG "drv.led"

#define GPIO_LED_PIN GET_PIN(F, 12)

typedef struct
{
    struct rt_device base_device; 	// 继承 rt_device 结构体
    
} led_device_t;

static led_device_t led_dev;		// 创建一个LED设备

2.填充相关信息和操作函数以及具体实现
主要是进行设备操作的一些函数的实现,常见的包括init(), open(), close(), read(), write(), control(),这些函数数主要是对设备进行简单的控制,和常用的一些操作,比如:设备的初始化,设备打开和关闭,以及读写设备,对设备进行其他操作。

/* 设备初始化函数 */
static rt_err_t led_init(rt_device_t dev)
{
    rt_pin_mode(GPIO_LED_PIN, PIN_MODE_OUTPUT);	// 设置设备的模式
    rt_pin_write(GPIO_LED_PIN, PIN_HIGH); 		// 默认关闭LED
    return RT_EOK;
}

/* 设备打开函数 */
static rt_err_t led_open(rt_device_t dev, rt_uint16_t oflag)
{
    return RT_EOK;	// 该设备无需打开,其他设备可以进行相应的打开操作
}

/* 设备关闭函数 */
static rt_err_t led_close(rt_device_t dev)
{
    return RT_EOK;	// 该设备无需关闭,其他设备可以进行相应的关闭操作
}

/* 设备读函数 */
static rt_size_t led_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
    return 0;		// 该设备无需读取,其他设备可以进行相应的读取操作
}

/* 设备写函数 */
static rt_size_t led_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
    if (size != 1)
    {
        return 0;
    }
    
    char state = *(char *)buffer;
    if (state == 1)
    {
        rt_pin_write(GPIO_LED_PIN, PIN_LOW); // 打开LED
    }
    else
    {
        rt_pin_write(GPIO_LED_PIN, PIN_HIGH); // 关闭LED
    }
    return size;
}

/* 设备控制函数 */
static rt_err_t led_control(rt_device_t dev, int cmd, void *args)
{
    switch (cmd)
    {
	    case 0:
	        rt_pin_write(GPIO_LED_PIN, PIN_HIGH); 	// 关闭LED
	        break;
	        
	    case 1:
	        rt_pin_write(GPIO_LED_PIN, PIN_LOW); 	// 打开LED
	        break;
	        
	    default:
	        return -RT_ERROR;
    }
    
    return RT_EOK;
}

3.注册设备到RT-Thread设备管理层
主要是将实现的函数注册到设备管理层,可以直接调用该设备的函数,就可以实现设备的操作。

/* 设备注册 */
int rt_hw_led_device_init(void)
{
    rt_device_t device = &(led_dev.base_device);
    
    // 设置设备类型和设备标志
    device->type = RT_Device_Class_Char;
    device->rx_indicate = RT_NULL;
    device->tx_complete = RT_NULL;
    
    // 设置设备操作接口
    device->init = led_init;
    device->open = led_open;
    device->close = led_close;
    device->read = led_read;
    device->write = led_write;
    device->control = led_control;
    
    // 注册设备
    rt_err_t result = rt_device_register(device, "led", RT_DEVICE_FLAG_RDWR);
    if (result != RT_EOK)
    {
        LOG_E("Failed to register LED device");
        return -RT_ERROR;
    }
    return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_led_device_init);	// 导出到自动初始化

四、完整代码

1.led.h

#include <rtthread.h>
#include <rtdevice.h>
#include <drv_common.h>

#define LOG_TAG "drv.led"

#define GPIO_LED_PIN GET_PIN(F, 12)

typedef struct
{
    struct rt_device base_device; 	// 继承 rt_device 结构体
    
} led_device_t;

static led_device_t led_dev;		// 创建一个LED设备

2.led.c

/* 设备初始化函数 */
static rt_err_t led_init(rt_device_t dev)
{
    rt_pin_mode(GPIO_LED_PIN, PIN_MODE_OUTPUT);	// 设置设备的模式
    rt_pin_write(GPIO_LED_PIN, PIN_HIGH); 		// 默认关闭LED
    return RT_EOK;
}

/* 设备打开函数 */
static rt_err_t led_open(rt_device_t dev, rt_uint16_t oflag)
{
    return RT_EOK;	// 该设备无需打开,其他设备可以进行相应的打开操作
}

/* 设备关闭函数 */
static rt_err_t led_close(rt_device_t dev)
{
    return RT_EOK;	// 该设备无需关闭,其他设备可以进行相应的关闭操作
}

/* 设备读函数 */
static rt_size_t led_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
    return 0;		// 该设备无需读取,其他设备可以进行相应的读取操作
}

/* 设备写函数 */
static rt_size_t led_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
    if (size != 1)
    {
        return 0;
    }
    
    char state = *(char *)buffer;
    if (state == 1)
    {
        rt_pin_write(GPIO_LED_PIN, PIN_LOW); // 打开LED
    }
    else
    {
        rt_pin_write(GPIO_LED_PIN, PIN_HIGH); // 关闭LED
    }
    return size;
}

/* 设备控制函数 */
static rt_err_t led_control(rt_device_t dev, int cmd, void *args)
{
    switch (cmd)
    {
	    case 0:
	        rt_pin_write(GPIO_LED_PIN, PIN_HIGH); 	// 关闭LED
	        break;
	        
	    case 1:
	        rt_pin_write(GPIO_LED_PIN, PIN_LOW); 	// 打开LED
	        break;
	        
	    default:
	        return -RT_ERROR;
    }
    
    return RT_EOK;
}

/* 设备注册 */
int rt_hw_led_device_init(void)
{
    rt_device_t device = &(led_dev.base_device);
    
    // 设置设备类型和设备标志
    device->type = RT_Device_Class_Char;
    device->rx_indicate = RT_NULL;
    device->tx_complete = RT_NULL;
    
    // 设置设备操作接口
    device->init = led_init;
    device->open = led_open;
    device->close = led_close;
    device->read = led_read;
    device->write = led_write;
    device->control = led_control;
    
    // 注册设备
    rt_err_t result = rt_device_register(device, "led", RT_DEVICE_FLAG_RDWR);
    if (result != RT_EOK)
    {
        LOG_E("Failed to register LED device");
        return -RT_ERROR;
    }
    return RT_EOK;
}
INIT_DEVICE_EXPORT(rt_hw_led_device_init);	// 导出到自动初始化
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值