Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
2024-RSOC
【2024-RSOC】D4学习分享(IO设备驱动框架,GPIO设备开发,I2C外设开发,SPI外设)
发布于 2024-07-30 00:06:15 浏览:95
订阅该版
[tocm] # 一,概要 ![重头戏部分](https://oss-club.rt-thread.org/uploads/20240729/d04c3d759ff919650b66bf062201e42b.png) # 二,基础概念 *SPI* SPI是一种串行通信方式,不同于UART,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB的布局上节省空间,提供方便,主要应用在 EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间. *API* API是Application Programming Interface的缩写,翻译为应用程序编程接口,是一种用于软件系统之间相互通信和交互的接口。API可以让不同的应用程序之间进行数据交换、功能扩展和服务调用等操作,从而实现更加复杂和强大的应用程序。API是现代软件开发中不可或缺的一部分,可以极大地提高软件的可扩展性、灵活性和互操作性。 *字符设备和块设备* **字符设备**提供连续的数据流,通常不支持随机存取。但此类设备支持按字节/字符来读写数据。目前常见的键盘、串口、调制解调器都是典型的字符设备。**块设备**可以随机访问设备数据,程序可自行确定读取数据的位置。硬盘和软盘等块设备可以寻址磁盘上的任何位置,并由此读取数据。此外,数据的读写只能以块(通常是512B)的倍数进行。~~与字符设备不同,块设备并不支持基于字符的寻址~~ # 三,相关代码 IO设备相关的官方文档: [♂官方文档♂](https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/device "♂官方文档♂") ## 1.IO设备驱动框架 示例代码: ```c struct rt_device{ struct rt_object parent; 内核对象基类*/ enum rt_device_class_type type; /* 设备类型*/ rt_uint16_t flag; /* 设备参数*/ rt_uint16_t open_flag; 设备打开标志/ rt_uint8_t ref_count; 设备被引用次数*/ rt_uint8_t device_id; /* 设备 ID,0-255*/ /*数据收发回调函数 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; /*设备操作方法*//*设备的私有数据/ void *user_data;}; typedef structrt_device *rt_device_t; ``` *支持的IO设备类型:* ```c RT_Device_Class_Char /* 字符设备 */ RT_Device_Class_Block /* 块设备 */ RT_Device_Class_NetIf /*网络接口设备 */ RT Device Class MTD /* 内存设备 */ RT_Device_Class_RTC /* RTC 设备 */ RT_Device_Class_Sound /*声音设备 */ RT_Device_Class_Graphic /*图形设备 */ RT_Device_Class_I2CBUS /* I2C 总线设备 */ RT Device Class USBDevice /* USB device 设备 */ RT_Device_Class_USBHost /* USB host 设备 */ RT_Device_Class_SPIBUS /* SPI 总线设备 */ RT_Device_Class_SPIDevice /*SPI设备 */ RT_Device_Class_SDIO /* SDIO 设备 */ RT_Device_Class_Miscellaneous /* 杂类设备 */ ``` *创建和销毁系统* ```c rt_device_t rt_device_create(int type, int attach_size); void rt_device_destroy(rt_device_t device); ``` *注册,注销设备* ```c rt_err_t rt_device_register(rt_device_t dev, const char* name, rt_uint8_t flags); rt_err_t rt_device_unregister(rt_device_t dev); ``` *注册设备flags* ```c #define RT_DEVICE_FLAG_RDONLY 0x001 /* 只读 */ #define RT_DEVICE_FLAG_WRONLY 0x002 /* 只写 */ #define RT DEVICE FLAG RDWR 0x003 /* 读写 */ #define RT_DEVICE_FLAG_REMOVABLE 0x004 /* 可移除 */ #define RT_DEVICE_FLAG_STANDALONE 0x008 /* 独立 */ #define RT DEVICE FLAG SUSPENDED 0x020 /*挂起*/ #define RT DEVICE FLAG STREAM 0x040 /* 流模式*/ #define RT DEVICE_FLAG INT RX 0x100 /* 中断接收 */ #define RT DEVICE FLAG DMA RX 0x200 /* DMA 接收*/ #define RT_DEVICE_FLAG_INT_TX 0x400 /*中断发送*/ #define RT_DEVICE_FLAG_DMA_TX 0x800 /* DMA 发送 */ ``` *注册字符设备test* ```c rt_device_t rt_device_create(int type, int attach_size); void rt_device_destroy(rt_device_t device); rt_err_t rt_device_register(rt_device_t dev, const char* name,rt_uint8_t flags); rt_err_t rt_device_unregister(rt_device_t dev); ``` *访问 I/O 设备* ```c struct rt_device_ops { /.* common device interface */ rt_err_t(rt_device_t dev);(*init) rt_err_t(rt_device_t dev, rt_uint16_t oflag);(*open) rt_err_t((rt_device_t dev);(*close) rt_size_t(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); (*read) rt_size_t(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size);(*write) rt_err_t(rt_device_t dev, int cmd, void *args);(*control) } ``` *查找设备/初始化设备* ```c rt_device_t rt_device_find(const char* name); •rt_err_t rt_device_init(rt_device_t dev); ``` *打开和关闭设备* ```c rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags); rt_err_t rt_device_close(rt_device_t dev); ``` *控制设备* ```c rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg); ``` *读写设备* ```c rt_size_t rt_device_read(rt_device_t dev, rt_off_t pos,void* buffer, rt_size_t size); rt_size_t rt_device_write(rt_device_t dev, rt_off_t pos,const void* buffer, rt_size_t size); ``` *数据接收回调* ```c rt_err_t rt_device_set_rx_indicate(rt_device_t dev,rt_err_t (*rx_ind)(rt_device_t dev,rt_size_t size)); rt_err_t rt_device_set_tx_complete(rt_device_t dev, rt_err_t (*tx_done)(rt_device_t dev,void *buffer)) ``` ## 2.GPIO外设开发 常用接口: ```c rt_pin_mode()//设置引脚模式 rt_pin_write()//设置引脚电平 rt_pin_read()//读取引脚电平 rt_pin_attach_irq()//绑定引脚中断回调函数 rt_pin_irq_enable()//使能引脚中断 rt_pin_detach_irq()//脱离引脚中断回调函数 ``` ## 3.I2C总线 开启 I2C 驱动后,使用 list_device 命令查看总线设备注册情况 ![总线设备](https://oss-club.rt-thread.org/uploads/20240729/59cbcc8acf140e0cbfce02fa3463c289.jpg.webp) 勾选使用 i2c-tools 软件包,方便对 i2c 设备进行调试 ![配置界面](https://oss-club.rt-thread.org/uploads/20240729/51c492b92783358e907006fcea3d07be.jpg.webp) 探测总线上的设备:i2c scan i2c3 ![总线设备](https://oss-club.rt-thread.org/uploads/20240729/e881bc98ff3c71447c7b248766efedae.jpg.webp) ## 4.SPI设备开发 SPI设备数据传输(一次通信) ```c #include
#include
#include "dry_spi.h" #include "drv_gpio.h static int spi_attach(void) { return rt_hw_spi_device_attach("spi2","spi20",GET_PIN(B,12)); } MSH_CMD_EXPORT(spi_attach,spi_attach); static int spi_example(void) { rt_err_t ret =RT EOK; struct rt spi_ device * spi20 = (struct rt_spi device *)rt device find("spi20"); struct rt_spi_configuration cfg; cfg.data width - 8; cfg.mode =RT_SPI_MASTER|RT_SPI_MODE_e|RT_SPI_MSB; cfg.max hz = 1* 1000* 1000;/*1m*/ rt_spi_configure(spi20,&cfg); rt uints t sendBuff =BxDA; rt_uint8 t recvBuff-exF1; ret - rt_spi_transfer(spi20,&sendBuff,&recvBuff,1); rt_kprintf("ret = %d\n", ret); return ret; } MSH_CMD_EXPORT(spi_example,spi_example); static int spi_send_one_data(void) { rt_err_t ret =RT_EOK; struct rt_spi_device *spi20 - (struct rt_spi_device*)rt_device_find("spi20"); struct rt_spi_configuration cfg; cfg.data width =8; cfg.mode =RT_SPI_MASTER|RT_SPI_MODE_0| RT_SPI_MSB; cfg.max_hz=1*1000*1000; /*1M */ rt_spi_configure(spi20,&cfg); rt_uint8 _t sendBuff =0x1A; ret = rt_spi_send(spi20,&sendBuff,1); rt_kprintf("ret = %d\n", ret); //return actual num return ret; MSH_CMD_EXPORT(spi_send_one_data, spi_send_one_data); ``` ## 四,小结 今天的课程启发了我对硬件知识的深入思考,但更多扩展还需自行学习。
0
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
LE_hor
这家伙很懒,什么也没写!
文章
6
回答
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
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
ota在线升级
UART
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
keil_MDK
rt_mq_消息队列_msg_queue
at_device
ulog
C++_cpp
本月问答贡献
踩姑娘的小蘑菇
7
个答案
3
次被采纳
张世争
8
个答案
2
次被采纳
rv666
5
个答案
2
次被采纳
用户名由3_15位
11
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
本月文章贡献
程序员阿伟
6
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
大龄码农
1
篇文章
2
次点赞
ThinkCode
1
篇文章
1
次点赞
Betrayer
1
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部