Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
2024-RSOC
[2024-RSOC] 设备驱动学习分享
发布于 2024-07-26 01:34:11 浏览:323
订阅该版
[tocm] # RT-Thread 暑期夏令营第四天:设备驱动 ## 任务1:梳理IO设备管理层、设备驱动框架层和设备驱动层的关系和调用流程(以I2C、SPI为例) ### 关系和调用流程 **1. IO设备管理层:** - 管理所有设备的生命周期,包括注册、初始化和反初始化。 - 提供统一的接口供应用程序与硬件设备交互,屏蔽硬件的具体细节,框架如下图。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240726/11af0e6b2875ea960e9a942642978223.png) **2. 设备驱动框架层:** - 提供编写设备驱动的标准结构,使得不同类型的设备驱动可以按照统一的方式编写。 - 主要职责是管理设备驱动的注册、注销以及提供设备操作的接口。 **3. 设备驱动层:** - 具体实现硬件设备的驱动逻辑,包括设备初始化、数据读写等操作。 - 根据设备的不同,驱动层会有不同的实现细节。例如I2C和SPI设备驱动需要实现I2C、SPI协议的具体操作。 #### 调用流程(以I2C为例) 1. **设备注册**: - 设备驱动层编写具体的I2C设备驱动代码,并通过`rt_device_register`函数将设备注册到系统中。 - 设备管理层记录该设备,并将其加入到设备列表中。 2. **设备初始化**: - 设备驱动层实现`init`函数,负责I2C设备的初始化工作,如配置I2C总线参数等。 - 设备管理层在系统启动时调用设备的`init`函数,完成设备初始化。 3. **设备操作**: - 应用层通过设备管理层提供的统一接口(如`rt_device_open`、`rt_device_read`、`rt_device_write`)操作设备。 - 设备管理层根据设备类型,调用相应的设备驱动层实现的具体操作函数。 ## 任务2:编写一个设备驱动并注册到系统,实现简单的读写操作 ### 代码实现 任务2中,我实现了一个字符设备的读写操作。具体代码如下: ```c #include
#include
#define LOG_TAG "drv.test" #define LOG_LVL LOG_LVL_DBG #include
#define BUFFER_SIZE 256 static int dev_test_app(void) { rt_device_t test_dev = rt_device_find("test_dev"); if (test_dev == RT_NULL) { LOG_E("can't find test dev."); return -RT_ERROR; } rt_device_open(test_dev, RT_DEVICE_OFLAG_RDWR); rt_device_control(test_dev, RT_DEVICE_CTRL_CONFIG, RT_NULL); // 写设备 const char write_buffer[] = "Hello, RT-Thread!"; LOG_I("Write data: %s", write_buffer); if (rt_device_write(test_dev, 0, write_buffer, sizeof(write_buffer)) <= 0) { LOG_E("write to device failed."); rt_device_close(test_dev); return -RT_ERROR; } // 读设备 char read_buffer[BUFFER_SIZE]; rt_memset(read_buffer, 0, BUFFER_SIZE); if (rt_device_read(test_dev, 0, read_buffer, sizeof(read_buffer)) <= 0) { LOG_E("read from example device failed."); rt_device_close(test_dev); return -RT_ERROR; } LOG_I("Read data: %s", read_buffer); rt_device_close(test_dev); return RT_EOK; } MSH_CMD_EXPORT(dev_test_app, dev_test_app); ``` 在这段代码中,我通过`rt_device_find`函数找到名为`test_dev`的设备,并打开该设备。然后,通过`rt_device_write`函数写入数据“Hello, RT-Thread!”,并通过`rt_device_read`函数读取设备中的数据,最后将读取到的数据打印出来。 ### 实验现象 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240726/26cf4f71f89c726bec39efff3f480bf3.png.webp) ## 任务3:利用bsp中已实现的板载外设驱动组合成一个Demo ### 代码实现 任务3中,我使用MultiButton控件,通过一个按键控制两个LED灯。具体代码如下: ```c #include
#include
#include "multi_button.h" #include
#define DBG_TAG "button" #define DBG_LVL DBG_INFO #include
static struct button btn; #define BUTTON_PIN (32) #define GPIO_LED_R GET_PIN(F, 12) #define GPIO_LED_B GET_PIN(F, 11) static uint8_t button_read_pin(void) { return rt_pin_read(BUTTON_PIN); } void btn_test_thread_entry(void *p) { uint32_t btn_event_val = 0; while(1) { if(btn_event_val != get_button_event(&btn)) { btn_event_val = get_button_event(&btn); switch(btn_event_val) { case PRESS_DOWN: rt_kprintf("button press down\n"); break; case PRESS_UP: rt_kprintf("button press up\n"); break; case PRESS_REPEAT: break; case SINGLE_CLICK: rt_kprintf("LED_R ON/OFF\n"); rt_pin_write(GPIO_LED_R, PIN_LOW); rt_thread_mdelay(50); rt_pin_write(GPIO_LED_R, PIN_HIGH); rt_thread_mdelay(50); break; case DOUBLE_CLICK: rt_kprintf("button double click\n"); break; case LONG_PRESS_START: rt_kprintf("LED_B ON/OFF\n"); rt_pin_write(GPIO_LED_B, PIN_LOW); rt_thread_mdelay(50); break; case LONG_PRESS_HOLD: rt_pin_write(GPIO_LED_B, PIN_HIGH); rt_thread_mdelay(50); break; default: break; } } button_ticks(); rt_thread_delay(RT_TICK_PER_SECOND / 200); } } int multi_button_test(void) { rt_thread_t thread = RT_NULL; thread = rt_thread_create("btn_test", btn_test_thread_entry, RT_NULL, 1024, 15, 10); if(thread == RT_NULL) { return RT_ERROR; } rt_thread_startup(thread); rt_pin_mode(BUTTON_PIN, PIN_MODE_INPUT); rt_pin_mode(GPIO_LED_R, PIN_MODE_OUTPUT); rt_pin_mode(GPIO_LED_B, PIN_MODE_OUTPUT); rt_pin_write(GPIO_LED_R, PIN_HIGH); rt_pin_write(GPIO_LED_B, PIN_HIGH); button_init(&btn, button_read_pin, PIN_LOW); button_start(&btn); return RT_EOK; } INIT_APP_EXPORT(multi_button_test); ``` 在这段代码中,通过MultiButton控件,设置了一个按键控制两个LED灯。按键的不同操作(如按下、松开、单击、双击、长按等)对应不同的LED灯操作。 ### 实验现象 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240726/b688d0a21eda419cf1c9d1352d0e65e8.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240726/b4860c555d25c7546b98d85aed821f34.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20240726/13229027514d2c2f26673ededbb31a5e.png.webp) ## 总结 通过这次培训,我对RT-Thread的设备驱动框架有了更深入的了解,并掌握了编写和注册设备驱动的方法。同时,通过任务的实践,我也加深了对设备驱动层、设备驱动框架层和设备管理层之间关系的理解。
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
猪的行独
这家伙很懒,什么也没写!
文章
7
回答
0
被采纳
0
关注TA
发私信
相关文章
推荐文章
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组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
SFUD
msh
ulog
C++_cpp
MicroPython
本月问答贡献
出出啊
1518
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
549
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
3
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部