IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> I/O 设备模型-2 -> 正文阅读

[嵌入式]I/O 设备模型-2

目录

1、UART

1.1、访问串口设备接口

1.2、打开flag

1.2.1、接收发送模式

1.2.2、流模式

1.3、配置参数

1.3.1、波特率

1.3.2、数据位

1.3.3、停止位

1.3.4、校验位

1.3.5、高低位顺序

1.3.6、模式

1.3.7、接收数据缓冲区默认大小

1.3.8、默认配置参数

1.4、UART设备对外接口

1.4.1、rt_hw_serial_register()函数

1.4.2、rt_serial_init()函数

1.4.3、rt_serial_open()函数

1.4.4、rt_serial_close()函数

1.4.5、rt_serial_read()函数

1.4.6、rt_serial_write()函数

1.4.7、rt_serial_control()函数

1.5、内部接口

1.5.1、rt_hw_serial_isr()函数

1.5.2、_serial_poll_rx()函数

1.5.3、_serial_poll_tx()函数

1.5.4、_serial_int_rx()函数

1.5.5、_serial_int_tx()函数

1.5.6、_serial_dma_rx()函数

1.5.7、_serial_dma_tx()函数

1.6、底层接口

1.6.1、dma_transmit()函数

1.6.2、control()函数

1.7、使用示例

1.7.1、中断接收轮询发送

1.8.2、DMA接收及轮询发送

2、UART V2

2.1、新旧版本串口使用区别

2.1.1、操作模式

2.1.2、缓冲区宏定义

2.2、硬件工作模式选择

2.2.1、配置发送

2.2.2、接收配置

2.3、内部接口

2.3.1、rt_hw_serial_isr()函数

2.3.2、_serial_fifo_tx_nonblocking()函数?

2.3.3、_serial_fifo_tx_blocking_buf()函数?

2.3.4、_serial_fifo_tx_blocking_nbuf()函数?

3、PIN 设备

3.1、PIN设备结构体

3.1.1、PIN模式

3.1.2、引脚中断模式

3.1.3、中断使能

3.1.4、高低电平

3.2、PIN接口函数

3.2.1、rt_device_pin_register()函数

3.2.2、rt_pin_get()函数

3.2.3、rt_pin_mode()函数

3.2.4、rt_pin_write()函数

3.2.5、rt_pin_read()函数

3.2.6、rt_pin_attach_irq()函数

3.2.7、rt_pin_detach_irq()函数

3.2.8、rt_pin_irq_enable()函数

3.3、PIN设备接口函数

3.3.1、rt_device_read()函数

3.3.2、rt_device_write()函数

3.3.3、rt_device_control()函数


1、UART

串口使用了设备模型的I/O 设备管理层、设备驱动框架层、设备驱动层

1.1、访问串口设备接口

函数描述
rt_device_find()查找设备
rt_device_open()打开设备
rt_device_read()读取数据
rt_device_write()写入数据
rt_device_control()控制设备
rt_device_set_rx_indicate()设置接收回调函数
rt_device_set_tx_complete()设置发送完成回调函数
rt_device_close()关闭设备

1.2、打开flag

#define RT_DEVICE_FLAG_RDONLY       0x001     /* 只读 */
#define RT_DEVICE_FLAG_WRONLY       0x002     /* 只写 */
#define RT_DEVICE_FLAG_RDWR         0x003     /* 可读可写 */

#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 发送模式 */

1.2.1、接收发送模式

串口数据接收和发送数据的模式分为 3 种:中断模式、轮询模式、DMA 模式。

注:在使用的时候,这 3 种模式只能选其一,若串口的打开参数 oflags 没有指定使用中断模式或者 DMA 模式,则默认使用轮询模式。

1.2.2、流模式

流模式用于向串口终端输出字符串:当输出的字符是?"\n"?(对应 16 进制值为 0x0A)时,自动在前面输出一个?"\r"(对应 16 进制值为 0x0D) 做分行。

1.3、配置参数

1.3.1、波特率

#define BAUD_RATE_2400                  2400
#define BAUD_RATE_4800                  4800
#define BAUD_RATE_9600                  9600
#define BAUD_RATE_19200                 19200
#define BAUD_RATE_38400                 38400
#define BAUD_RATE_57600                 57600
#define BAUD_RATE_115200                115200
#define BAUD_RATE_230400                230400
#define BAUD_RATE_460800                460800
#define BAUD_RATE_921600                921600
#define BAUD_RATE_2000000               2000000
#define BAUD_RATE_2500000               2500000
#define BAUD_RATE_3000000               3000000

1.3.2、数据位

#define DATA_BITS_5                     5
#define DATA_BITS_6                     6
#define DATA_BITS_7                     7
#define DATA_BITS_8                     8
#define DATA_BITS_9                     9

1.3.3、停止位

#define STOP_BITS_1                     0
#define STOP_BITS_2                     1
#define STOP_BITS_3                     2
#define STOP_BITS_4                     3

1.3.4、校验位

#define PARITY_NONE                     0
#define PARITY_ODD                      1
#define PARITY_EVEN                     2

1.3.5、高低位顺序

#define BIT_ORDER_LSB                   0
#define BIT_ORDER_MSB                   1

1.3.6、模式

#define NRZ_NORMAL                      0     /* normal mode */
#define NRZ_INVERTED                    1     /* inverted mode */

1.3.7、接收数据缓冲区默认大小

当串口使用中断接收模式打开时,串口驱动框架会根据 RT_SERIAL_RB_BUFSZ 大小开辟一块缓冲区用于保存接收到的数据。

#define RT_SERIAL_RB_BUFSZ              64

注:默认串口配置接收数据缓冲区大小为 RT_SERIAL_RB_BUFSZ,即 64 字节。若一次性数据接收字节数很多,没有及时读取数据,那么缓冲区的数据将会被新接收到的数据覆盖,造成数据丢失。

1.3.8、默认配置参数

#define RT_SERIAL_CONFIG_DEFAULT           \
{                                          \
    BAUD_RATE_115200, /* 115200 bits/s */  \
    DATA_BITS_8,      /* 8 databits */     \
    STOP_BITS_1,      /* 1 stopbit */      \
    PARITY_NONE,      /* No parity  */     \
    BIT_ORDER_LSB,    /* LSB first sent */ \
    NRZ_NORMAL,       /* Normal mode */    \
    RT_SERIAL_RB_BUFSZ, /* Buffer size */  \
    RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \
    0                                      \
}

1.4、UART设备对外接口

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);
};

1.4.1、rt_hw_serial_register()函数

该接口用于注册串口设备。

rt_err_t rt_hw_serial_register(struct rt_serial_device *serial,
                               const char              *name,
                               rt_uint32_t              flag,
                               void                    *data)

1.4.2、rt_serial_init()函数

该接口用于初始化串行设备。最终会调用设备驱动层注册的configure()函数配置设备。

static rt_err_t rt_serial_init(struct rt_device *dev)

1.4.3、rt_serial_open()函数

该接口用于打开串行设备。

static rt_err_t rt_serial_open(struct rt_device *dev, rt_uint16_t oflag)

1.4.4、rt_serial_close()函数

该接口用于关闭串行设备。

static rt_err_t rt_serial_close(struct rt_device *dev)

1.4.5、rt_serial_read()函数

该接口用于读取串行数据。

1)中断读取时,调用_serial_int_rx()函数

2)DMA读取时,调用_serial_dma_rx()函数

3)轮询读取时,调用_serial_poll_rx()函数

rt_size_t rt_serial_read(struct rt_device *dev,
                                rt_off_t          pos,
                                void             *buffer,
                                rt_size_t         size)

1.4.6、rt_serial_write()函数

该接口用于写入串行数据。

1)中断写入时,调用_serial_int_tx()函数

2)DMA写入时,调用_serial_dma_tx()函数

3)轮询写入时,调用_serial_poll_tx()函数

rt_size_t rt_serial_write(struct rt_device *dev,
                                 rt_off_t          pos,
                                 const void       *buffer,
                                 rt_size_t         size)

1.4.7、rt_serial_control()函数

?串口控制。

static rt_err_t rt_serial_control(struct rt_device *dev,
                                  int              cmd,
                                  void             *args)
cmdargs说明
RT_DEVICE_CTRL_SUSPEND/挂起串口设备
RT_DEVICE_CTRL_RESUME/恢复串口设备
RT_DEVICE_CTRL_CONFIG

serial_configure结构体

最终会调用设备驱动层注册的configure()函数配置串口

1.5、内部接口

1.5.1、rt_hw_serial_isr()函数

串口应用框架的中断处理函数。底层驱动进入串口中断时会调用此函数(具体实现取决于底层驱动)。

注:event的bit 0- bit7是事件;bit 8- bit15根据不同的事件定义不同,如DMA接收长度。

void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
RT_SERIAL_EVENT_RX_IND

中断接收。

1)调用设备驱动层注册的getc()函数按字节循环接收数据,并将其放入环形缓存区中。

2)如果设置了回调函数rx_indicate()函数,则调用rx_indicate()回调函数。

RT_SERIAL_EVENT_TX_DONE

发送中断。

调用rt_completion_done()函数,释放发送完成信号量。

RT_SERIAL_EVENT_TX_DMADONE

DMA发送中断。

1)从DMA发送数据队列取出数据。

2)如果数据队列中还有数据,则调用设备驱动层注册的dma_transmit()函数再次发送。

3)如果设置了回调函数tx_indicate()函数,则调用tx_indicate()回调函数。

RT_SERIAL_EVENT_RX_DMADONE

DMA接收中断(没有缓存区)。

1)直接调用rx_indicate()函数

DMA接收中断(存在缓存区)。

1)数据已直接被DMA放入缓存区,更新环形缓冲区信息。

2)如果设置了回调函数rx_indicate()函数,则调用rx_indicate()回调函数。

1.5.2、_serial_poll_rx()函数

轮询接收。最终会调用设备驱动层注册的getc()函数接收数据。

int _serial_poll_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)

1.5.3、_serial_poll_tx()函数

轮询发送。最终会调用设备驱动层注册的putc()函数接收数据。

int _serial_poll_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)

1.5.4、_serial_int_rx()函数

中断接收。中断接收时serial_rx为rt_serial_rx_fifo结构体(其实就是个环形缓存区),中断接收的数据保存在环形缓存区中。最终会从此环形缓冲区中按字节循环获取数据

int _serial_int_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)

1.5.5、_serial_int_tx()函数

中断发送。最终会调用设备驱动层注册的putc()函数按字节循环写入数据(每次发送时需等待发送中断完成)

rt_inline int _serial_int_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)

1.5.6、_serial_dma_rx()函数

DMA数据接收。

1)如果串口没有缓存区最终会调用设备驱动层注册的dma_transmit()函数接收数据,方向为RT_SERIAL_DMA_TX。

2)如果串口存在缓存区,DMA中断接收时serial_rx为rt_serial_rx_fifo结构体(其实就是个环形缓存区),DMA中断接收的数据保存在环形缓存区中。最终会从此环形缓冲区中一次性拷贝获取数据

int _serial_dma_rx(struct rt_serial_device *serial, rt_uint8_t *data, int length)

1.5.7、_serial_dma_tx()函数

DMA数据发送。DMA中断接收时serial_tx为rt_serial_tx_dma结构体(包含一个数据队列),将要写入的数据放入到数据队列中。最终会调用设备驱动层注册的dma_transmit()函数写入数据,方向为RT_SERIAL_DMA_TX。

int _serial_dma_tx(struct rt_serial_device *serial, const rt_uint8_t *data, int length)

1.6、底层接口

?struct rt_uart_ops
{
    rt_err_t (*configure)(struct rt_serial_device *serial, struct serial_configure *cfg);
    rt_err_t (*control)(struct rt_serial_device *serial, int cmd, void *arg);

    int (*putc)(struct rt_serial_device *serial, char c);
    int (*getc)(struct rt_serial_device *serial);

    rt_size_t (*dma_transmit)(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
};

1.6.1、dma_transmit()函数

1)方向为RT_SERIAL_DMA_TX的dma_transmit()函数在DMA发送时调用;

1)方向为RT_SERIAL_DMA_RX的dma_transmit()函数仅在DMA不存在缓存区读取时调用;?

1.6.2、control()函数

cmdarg

RT_DEVICE_CTRL_SET_INT/

RT_DEVICE_CTRL_CLR_INT

RT_DEVICE_FLAG_INT_RX
RT_DEVICE_FLAG_INT_TX

RT_DEVICE_CTRL_CONFIG/

RT_DEVICE_CTRL_CLR_INT

RT_DEVICE_FLAG_DMA_RX
RT_DEVICE_FLAG_DMA_TX
RT_DEVICE_CTRL_CLOSE/

1.7、使用示例

1.7.1、中断接收轮询发送

1)查找串口设备获取设备句柄。

2)初始化回调函数发送使用的信号量,然后以读写及中断接收方式打开串口设备。

3)设置串口设备的接收回调函数,并创建读取数据线程。读取数据线程会尝试读取一个字符数据,如果没有数据则会挂起并等待信号量,当串口设备接收到一个数据时会触发中断并调用接收回调函数,此函数会发送信号量唤醒线程,此时线程会马上读取接收到的数据。

1.8.2、DMA接收及轮询发送

1)查找串口设备获取设备句柄。

2)初始化回调函数发送使用的消息队列,然后以 DMA 接收及轮询发送方式打开串口设备。

3)设置串口设备的接收回调函数,并创建读取数据线程。读取数据线程会尝试读取接收到的字符数据,如果没有数据则会挂起并等待消息队列,当串口接收到一批数据后会调用接收回调函数,接收回调函数会把此时缓冲区的数据大小通过消息队列发送给等待的数据处理线程。线程获取到消息后被激活,并读取数据。

注:一般情况下 DMA 接收模式会结合 DMA 接收完成中断和串口空闲中断完成数据接收。

2、UART V2

2.1、新旧版本串口使用区别

2.1.1、操作模式

// 旧版本 oflags 的参数取值
RT_DEVICE_FLAG_INT_RX
RT_DEVICE_FLAG_INT_TX
RT_DEVICE_FLAG_DMA_RX
RT_DEVICE_FLAG_DMA_TX

// 新版本 oflags 的参数取值
RT_DEVICE_FLAG_RX_NON_BLOCKING
RT_DEVICE_FLAG_RX_BLOCKING
RT_DEVICE_FLAG_TX_NON_BLOCKING
RT_DEVICE_FLAG_TX_BLOCKING

旧版本的操作模式: 轮询、中断、DMA。

新版本的操作模式: 阻塞、非阻塞。

注:阻塞的实现基于完成信号量。

2.1.2、缓冲区宏定义

旧版本接收缓冲区统一为 RT_SERIAL_RB_BUFSZ ,旧版本没有发送缓冲区的设置。

新版本缓冲区进行了分离接收和发送,并且也可以对各个串口进行单独设置:

#define RT_SERIAL_RX_MINBUFSZ 64
#define RT_SERIAL_TX_MINBUFSZ 64

2.2、硬件工作模式选择

串口外设的遵循如下规则:

1)模式优先级为:DMA 模式 > 中断模式 > 轮询模式。即当有 DMA 配置时,默认使用 DMA 模式,以此类推。且非必要条件,不选择使用轮询模式。
2)串口默认配置接收和发送缓冲区
3)默认使用阻塞发送、非阻塞接收模式

2.2.1、配置发送

编号配置发送缓冲区(有 / 无)说明硬件工作模式(TX)应用层操作模式(TX)内部发送接口
(1)不使用缓存区,且设置缓存区长度为0轮询阻塞_serial_poll_tx()
(2)

不支持该模式

注:框架直接return?-RT_EINVAL

轮询非阻塞/
(3)使用缓存区中断阻塞_serial_fifo_tx_blocking_buf()
(4)使用缓存区中断非阻塞_serial_fifo_tx_nonblocking()
(5)不使用缓存区,但需要设置缓冲区长度大于0DMA阻塞_serial_fifo_tx_blocking_nbuf()
(6)使用缓存区DMA非阻塞_serial_fifo_tx_nonblocking()

注:对于模式1,如果必须使用轮询模式时,一定要将缓冲区大小配置为 0。

注:当使用 DMA 阻塞模式时,虽然不用缓冲区,但是也要将缓冲区长度设置为大于 0 的值,因为当缓冲区长度为 0 时,将会错误地使用轮询模式。

2.2.2、接收配置

编号配置接收缓冲区(有 / 无)说明硬件工作模式(RX)应用层操作模式(RX)内接接收接口
(1)不使用缓存区,且设置缓存区长度为0轮询阻塞_serial_poll_rx()
(2)

不支持该模式

注:框架直接return?-RT_EINVAL

轮询非阻塞/
(3)使用缓存区中断阻塞_serial_fifo_rx()
(4)使用缓存区中断非阻塞_serial_fifo_rx()
(5)使用缓存区DMA阻塞_serial_fifo_rx()
(6)使用缓存区DMA非阻塞_serial_fifo_rx()

注:对于模式1,如果必须使用轮询模式时,一定要将缓冲区大小配置为 0。

2.2.3、配置总结

1)当底层支持DMA时且缓存区长度不为0,用户在应用层对串口的操作模式进行配置时,无论配置阻塞或者非阻塞,均使用的是 DMA 模式。

2)当底层不支持DMA时且缓存区长度不为0,用户在应用层对串口的操作模式进行配置时,无论配置阻塞或者非阻塞,均使用的是中断模式。

2)当底层不支持DMA时且缓存区长度为0,用户在应用层对串口的操作模式进行配置时,无论配置阻塞或者非阻塞,均使用的是轮询模式。

2.3、内部接口

2.3.1、rt_hw_serial_isr()函数

RT_SERIAL_EVENT_RX_IND

中断接收。

1)在调用rt_hw_serial_isr前底层驱动已将中断接收的字节放到rt_ringbuffer中。

2)如果是阻塞接收且接收完成时,释放完成信号量。

3)如果设置了回调函数rx_indicate()函数,则调用rx_indicate()回调函数。

RT_SERIAL_EVENT_RX_DMADONE

DMA中断接收。

1)数据已直接被DMA放入缓存区,更新环形缓冲区信息。

2)如果是阻塞接收且接收完成时,释放完成信号量。

3)如果设置了回调函数rx_indicate()函数,则调用rx_indicate()回调函数。

RT_SERIAL_EVENT_TX_DONE

发送中断。

1)如果数据队列中还有数据,则调用设备驱动层注册的dma_transmit()函数再次发送。

2)如果数据队列中没有数据了,则调用tx_indicate()回调函数。

3)如果数据队列中没有数据了,如果是阻塞发送则调用rt_completion_done()函数,释放发送完成信号量。

注:发送中断每发送一个字节就会产生中断,所以要等发送完成才调用rt_completion_done()函数

RT_SERIAL_EVENT_TX_DMADONE

DMA发送中断。

1)直接调用tx_indicate()回调函数。

2)如果是阻塞发送则直接调用rt_completion_done()函数,释放发送完成信号量。

3)更新ringbuff,如果数据队列中还有数据,则调用设备驱动层注册的dma_transmit()函数再次发送。

注:DMA中断则是在传输半完成/传输完成时产生中断,直接可调用rt_completion_done()函数

void rt_hw_serial_isr(struct rt_serial_device *serial, int event)

2.3.2、_serial_fifo_tx_nonblocking()函数?

该函数用于非阻塞发送数据(DMA/中断)。

1)传输未启动,将数据拷贝到发送ringbuffer。最终会调用设备驱动层注册的transmit()函数,tx_flag为RT_SERIAL_TX_NON_BLOCKING,将ringbuffer中的连续线性数据发送(发送数据最多不超过ringbuffer的buffer_size-read_index)。

2)传输已启动,仅将数据拷贝到发送ringbuffer。

static rt_size_t _serial_fifo_tx_nonblocking(struct rt_device        *dev,
                                                    rt_off_t          pos,
                                              const void             *buffer,
                                                    rt_size_t         size)

2.3.3、_serial_fifo_tx_blocking_buf()函数?

该函数用于带有缓存区的阻塞发送数据(中断)。

1)当调度器未启动或处于流模式时,调用_serial_poll_tx()函数发送数据

2)若当前正处于传输中,直接返回

3)调用设备驱动层注册的transmit()函数,tx_flag为RT_SERIAL_TX_BLOCKING,将ringbuffer中的数据发送,并调用rt_completion_wait()函数等待发送完成。

4)重复步骤2直至数据全部发送完成(每次复制一段数据到ringbuffer中,直到数据的长度与大小相等?)。

static rt_size_t _serial_fifo_tx_blocking_buf(struct rt_device        *dev,
                                                     rt_off_t          pos,
                                               const void             *buffer,
                                                    rt_size_t          size)

2.3.4、_serial_fifo_tx_blocking_nbuf()函数?

该函数用于不带缓存区的阻塞发送数据(DMA)。

1)若当前正处于传输中,直接返回

2)调用设备驱动层注册的transmit()函数,tx_flag为RT_SERIAL_TX_BLOCKING,将ringbuffer中的数据发送,并调用rt_completion_wait()函数

注:transmit()函数的buf直接指向buffer!

static rt_size_t _serial_fifo_tx_blocking_nbuf(struct rt_device        *dev,
                                                      rt_off_t          pos,
                                                const void             *buffer,
                                                      rt_size_t         size)

3、PIN 设备

PIN设备使用I/O 设备管理层、设备驱动框架层、设备驱动层

3.1、PIN设备结构体

?/* PIN设备实现的方法 */
struct rt_pin_ops
{
    void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);
    void (*pin_write)(struct rt_device *device, rt_base_t pin, rt_base_t value);
    int (*pin_read)(struct rt_device *device, rt_base_t pin);
    rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_int32_t pin,
                      rt_uint32_t mode, void (*hdr)(void *args), void *args);
    rt_err_t (*pin_detach_irq)(struct rt_device *device, rt_int32_t pin);
    rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled);
    rt_base_t (*pin_get)(const char *name);
};

?/* PIN设备结构体 */
struct rt_device_pin
{
    struct rt_device parent;
    const struct rt_pin_ops *ops;
};

/* 此结构体用于底层驱动保存引脚中断回调函数信息 */
struct rt_pin_irq_hdr
{
    rt_int16_t        pin;
    rt_uint16_t       mode;
    void (*hdr)(void *args);
    void             *args;
};

3.1.1、PIN模式

#define PIN_MODE_OUTPUT         0x00
#define PIN_MODE_INPUT          0x01
#define PIN_MODE_INPUT_PULLUP   0x02
#define PIN_MODE_INPUT_PULLDOWN 0x03
#define PIN_MODE_OUTPUT_OD      0x04

3.1.2、引脚中断模式

#define PIN_IRQ_MODE_RISING             0x00
#define PIN_IRQ_MODE_FALLING            0x01
#define PIN_IRQ_MODE_RISING_FALLING     0x02
#define PIN_IRQ_MODE_HIGH_LEVEL         0x03
#define PIN_IRQ_MODE_LOW_LEVEL          0x04

3.1.3、中断使能

#define PIN_IRQ_DISABLE                 0x00
#define PIN_IRQ_ENABLE                  0x01

3.1.4、高低电平

#define PIN_LOW                 0x00
#define PIN_HIGH                0x01

3.2、PIN接口函数

3.2.1、rt_device_pin_register()函数

注册PIN设备。

int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data)

3.2.2、rt_pin_get()函数

获取引脚编号。最终会调用设备驱动层注册的pin_get()函数获取引脚编号。

rt_base_t rt_pin_get(const char *name)

注:name的格式可能为PE02, PE2, PE.02, PE.2, pe02, pe2, pe.02, pe.2等。具体的实现可能根据驱动的不同稍有差别。

3.2.3、rt_pin_mode()函数

设置引脚模式。最终会调用设备驱动层注册的pin_mode()函数设置引脚模式。

3.2.4、rt_pin_write()函数

设置引脚电平。最终会调用设备驱动层注册的pin_write()函数设置引脚电平。

3.2.5、rt_pin_read()函数

读取引脚电平。最终会调用设备驱动层注册的pin_read()函数读取引脚电平。

3.2.6、rt_pin_attach_irq()函数

绑定引脚中断回调函数。最终会调用设备驱动层注册的pin_attach_irq()函数绑定引脚中断回调函数。

3.2.7、rt_pin_detach_irq()函数

脱离引脚中断回调函数。最终会调用设备驱动层注册的pin_detach_irq()函数脱离引脚中断回调函数。

3.2.8、rt_pin_irq_enable()函数

使能引脚中断。最终会调用设备驱动层注册的pin_irq_enable()函数使能引脚中断。

3.3、PIN设备接口函数

struct rt_device_pin_status
{
    rt_uint16_t pin;
    rt_uint16_t status;
};

struct rt_device_pin_mode
{
    rt_uint16_t pin;
    rt_uint16_t mode;
};

3.3.1、rt_device_read()函数

读取PIN设备状态。最终会调用PIN设备驱动框架层的_pin_read()函数读取引脚状态。

pos参数无效。buffer参数为rt_device_pin_status结构体,需指定要读取的引脚pin;读取到的引脚状态保存在status中。读取失败返回0,读取成功返回size(size不要设置为0,否则无法判断是否读取成功)

rt_size_t rt_device_read(rt_device_t dev,
                         rt_off_t    pos,
                         void       *buffer,
                         rt_size_t   size)

3.3.2、rt_device_write()函数

设置PIN设备状态。最终会调用PIN设备驱动框架层的_pin_write()函数读取引脚状态。

pos参数无效。buffer参数为rt_device_pin_status结构体,指定要设置的引脚pin和引脚状态status。设置失败返回0,设置成功返回size(size不要设置为0,否则无法判断是否设置成功)

rt_size_t rt_device_write(rt_device_t dev,
                          rt_off_t    pos,
                          const void *buffer,
                          rt_size_t   size)

3.3.3、rt_device_control()函数

设置PIN设备模式。最终会调用PIN设备驱动框架层的_pin_control()函数设置PIN设备模式。

cmd参数无效。buffer参数为rt_device_pin_mode结构体,指定要设置的引脚pin和引脚模式mode。设置成功返回0,设置失败返回-RT_ERROR。

rt_err_t rt_device_control(rt_device_t dev, int cmd, void *arg)

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:50:48  更:2022-10-17 12:51:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 21:33:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码