【RTT驱动框架分析01】-pin/gpio驱动分析

0gpio使用测试

LED测试

#define LED1_PIN        GET_PIN(C,  1)
void led1_thread_entry(void* parameter)
{rt_pin_mode(LED1_PIN, PIN_MODE_OUTPUT);while(1){rt_thread_delay(50);    //delay 500msrt_pin_write(LED1_PIN, PIN_HIGH);rt_thread_delay(50);    //delay 500msrt_pin_write(LED1_PIN, PIN_LOW);}
}

key轮训测试

#define KEY1_PIN        GET_PIN(A,  4)
#define KEY2_PIN        GET_PIN(A,  5)
#define KEY3_PIN        GET_PIN(A,  6)#define KEY1  rt_pin_read(KEY1_PIN)
#define KEY2  rt_pin_read(KEY2_PIN)
#define KEY3  rt_pin_read(KEY3_PIN)#define KEY1_PRES   1
#define KEY2_PRES   2
#define KEY3_PRES   3
uint8_t KEY_Scan(uint8_t mode)
{static uint8_t key_up=1;if(mode){key_up = 1;}if(key_up && (KEY1 == 0 || KEY2 == 0 || KEY3 == 0)){rt_thread_delay(1);key_up=0;if(KEY1 == 0){return KEY1_PRES;}else if(KEY2 == 0){return KEY2_PRES;}else if(KEY3 == 0){return KEY3_PRES;}} else if(KEY1 == 1 && KEY2 == 1 && KEY3 == 1){key_up = 1;}return 0;
}void key_test(void)
{rt_uint8_t key;rt_pin_mode(KEY1_PIN, PIN_MODE_INPUT_PULLUP);rt_pin_mode(KEY2_PIN, PIN_MODE_INPUT_PULLUP);while(1){key = KEY_Scan(0);switch(key){case KEY1_PRES:rt_kprintf("key1 pressed.\n");break;case KEY2_PRES:rt_kprintf("key2 pressed.\n");break;case KEY3_PRES:break;default:break;}rt_thread_delay(5);}
}

key中断测试

#define KEY3_PIN        GET_PIN(A,  6)
void key3_irq(void *args)
{rt_kprintf("enter key3 interrupt callback.\n");
}
void key_test(void)
{rt_pin_mode(KEY3_PIN, PIN_MODE_INPUT_PULLUP);rt_pin_attach_irq(KEY3_PIN, PIN_IRQ_MODE_FALLING, key3_irq, RT_NULL);rt_pin_irq_enable(KEY3_PIN, ENABLE);
}

1.设备抽象接口rt_device

struct rt_device
{struct rt_object          parent;                   /**< 继承至内核对象 */enum rt_device_class_type type;                     /**< device type 设备类型 can uart 等*/rt_uint16_t               flag;                     /**< device flag */rt_uint16_t               open_flag;                /**< device open flag */rt_uint8_t                ref_count;                /**< reference count */rt_uint8_t                device_id;                /**< 0 - 255 *//* device call back 发送和接收的回调函数 */rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size);rt_err_t (*tx_complete)(rt_device_t dev, void *buffer);/* 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);
#endif#if defined(RT_USING_POSIX)const struct dfs_file_ops *fops;struct rt_wqueue wait_queue;
#endifvoid                     *user_data;                /**< device private data */
};

1.1.核对象

struct rt_object
{char       name[RT_NAME_MAX];                       /**< name of kernel object */rt_uint8_t type;                                    /**< type of kernel object */rt_uint8_t flag;                                    /**< flag of kernel object */#ifdef RT_USING_MODULEvoid      *module_id;                               /**< id of application module */
#endifrt_list_t  list;                                    /**< list node of kernel object */
};

pin设备驱动框架

该框架主要包含内容有:

  1. 一个继承至设备驱动框架的rt_device 对象
  2. 一个pin相关的操作函数集
    1. gpio模式配置
    2. gpio 读写函数
    3. 中断绑定解绑函数
    4. 中断使能函数
  3. pin设备的注册函数int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data);
//操作函数
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);/* TODO: add GPIO interrupt */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);
};//pin设备驱动核心结构
struct rt_device_pin
{struct rt_device parent;const struct rt_pin_ops *ops;
};

N32L40x 的驱动程序drv_driver.c 分析

1.gpio 到gpio id的映射关系

/*这个宏 ## 就是连接符号
*/
#define __N32L40X_PORT(port)  GPIO##port##_BASE
//gpioid 和 [gpio分组h和pin] 的关系 gpioid = (gpio分组-gpio_base)*16+pin
#define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__N32L40X_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN)

2.如何实现注册pin设备

  1. 定义一个rt_pin_ops对象分别实现内部的 模式设置函数,读写函数,中断绑定和解绑函数,中断使能函数
  2. 注册rt_pin_ops对象到内核

3.外部中断的处理办法

  1. 外部中断统一调用N32L40X_GPIO_EXTI_IRQHandler处理函数
  2. 外部中断的回到函数统一放在一个 pin_irq_hdr_tab 数组内部

中断处理

在这里插入图片描述

中断绑定

绑定的实质就是给pin_irq_hdr_tab 内部的对象成员赋值操作
在这里插入图片描述

外部中断相关的结构

主要是存储用户注册中断处理函数

struct rt_pin_irq_hdr
{rt_int16_t        pin;rt_uint16_t       mode;//上升沿,下降沿等触发方式void (*hdr)(void *args);//用户绑定的中断处理函数void             *args;//参数
};

gpio时钟分组

在rtconfig.h中可能涉及需要开启gpio时钟

在这里插入图片描述

中断使能和关闭

内部实质就是设置中断分组和中断的触发模式中断优先级

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/13862.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL之深入InnoDB存储引擎——物理文件

文章目录 一、参数文件二、日志文件三、表结构定义文件四、InnoDB 存储引擎文件1、表空间文件2、重做日志文件 一、参数文件 当 MySQL 实例启动时&#xff0c;数据库会先去读一个配置参数文件&#xff0c;用来寻找数据库的各种文件所在位置以及指定某些初始化参数。在默认情况…

6-Linux的磁盘分区和挂载

Linux的磁盘分区和挂载 Linux分区查看所有设备的挂载情况 将磁盘进行挂载的案例增加一块磁盘的总体步骤1-在虚拟机中增加磁盘2- 分区3-格式化分区4-挂载分区5-进行永久挂载 磁盘情况查询查询系统整体磁盘使用情况查询指定目录的磁盘占用情况 磁盘情况-工作实用指令统计文件夹下…

Vue3搭建启动

Vue3搭建&启动 一、创建项目二、启动项目三、配置项目1、添加编辑器配置文件2、配置别名3、处理sass/scss4、处理tsx(不用的话可以不处理) 四、添加Eslint 一、创建项目 npm create vite 1.project-name 输入项目名vue3-vite 2.select a framework 选择框架 3.select a var…

关于前端框架vue2升级为vue3的相关说明

一些框架需要升级 当前&#xff08;202306&#xff09; Vue 的最新稳定版本是 v3.3.4。Vue 框架升级为最新的3.0版本&#xff0c;涉及的相关依赖变更有&#xff1a; 前提条件&#xff1a;已安装 16.0 或更高版本的Node.js&#xff08;摘&#xff09; 必须的变更&#xff1a;核…

C语言进阶——文件的打开(为什么使用文件、什么是文件、文件的打开和关闭)

目录 为什么使用文件 什么是文件 程序文件 数据文件 文件名 文件的打开和关闭 文件指针 打开和关闭 为什么使用文件 在之前学习通讯录时&#xff0c;我们可以给通讯录中增加、删除数据&#xff0c;此时数据是存放在内存中&#xff0c;当程序退出的时候&#xff0c;通讯…

【弹力设计篇】聊聊灾备设计、异地多活设计

单机&集群架构 对于一个高可用系统来说&#xff0c;为了提升系统的稳定性&#xff0c;需要以下常用技术服务拆分、服务冗余、限流降级、高可用架构设计、高可用运维&#xff0c;而本篇主要详细介绍下&#xff0c;高可用架构设计。容灾备份以及同城多活&#xff0c;异地多活…

OpenCV实现高斯模糊加水印

# coding:utf-8 # Email: wangguisendonews.com # Time: 2023/4/21 10:07 # File: utils.pyimport cv2 import PIL from PIL import Image import numpy as np from watermarker.marker import add_mark, im_add_mark import matplotlib.pyplot as plt# PIL Image转换成OpenCV格…

redis分布式锁

Redis 作者继续论述&#xff0c;如果对方认为&#xff0c;发生网络延迟、进程 GC 是在步骤 3 之后&#xff0c;也就是客户端确认拿到了锁&#xff0c;去操作共享资源的途中发生了问题&#xff0c;导致锁失效&#xff0c;那这不止是 Redlock 的问题&#xff0c;任何其它锁服务例…

Flowable-任务-脚本任务

定义 脚本任务&#xff08;Script Task&#xff09;是一种自动执行的活动。当流程执行到达脚本任务时&#xff0c;会执行相应的 脚本&#xff0c;完毕后继续执行后继路线。脚本任务无须人为参与&#xff0c;可以通过定义脚本实现自定义的业务逻辑。 图形标记 脚本任务显示为…

数据结构基础:3.单链表的实现。

单链表的介绍和实现 一.基本概念1.基本结构2.结构体节点的定义&#xff1a; 二.功能接口的实现0.第一个节点&#xff1a;plist1打印链表2创建一个节点3.头插4.头删5.尾插6.尾删7.查找8.在pos之前插入x9.在pos之后插入x10.删除pos位置11.删除pos的后一个位置12.链表释放 三.整体…

C语言每天一练----输出水仙花数

题目&#xff1a;请输出所有的"水仙花数" 题解&#xff1a;所谓"水仙花数"是指一个3位数,其各位数字立方和等于该数本身。 例如, 153是水仙花数, 因为153 1 * 1 * 1 5 * 5 * 5 3 * 3 * 3" #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h&g…

【自动化运维】Ansible常见模块的运用

目录 一、Ansible简介二、Ansible安装部署2.1环境准备 三、ansible 命令行模块3.1&#xff0e;command 模块3.2&#xff0e;shell 模块3.3&#xff0e;cron 模块3.4&#xff0e;user 模块3.5&#xff0e;group 模块3.6&#xff0e;copy 模块3.7&#xff0e;file 模块8&#xff…

【雕爷学编程】MicroPython动手做(10)——零基础学MaixPy之神经网络KPU

早上百度搜“神经网络KPU”&#xff0c;查到与非网的一篇文章《一文读懂APU/BPU/CPU/DPU/EPU/FPU/GPU等处理器》&#xff0c;介绍各种处理器非常详细&#xff0c;关于“KPU”的内容如下&#xff1a; KPU Knowledge Processing Unit。 嘉楠耘智&#xff08;canaan&#xff09;号…

找不到mfc140u.dll怎么解决

第一&#xff1a;mfc140u.dll有什么用途&#xff1f; mfc140u.dll是Windows操作系统中的一个动态链接库文件&#xff0c;它是Microsoft Foundation Class (MFC)库的一部分。MFC是 C中的一个框架&#xff0c;用于构建Windows应用程序的用户界面和功能。mfc140u.dll包含了MFC库中…

杂谈项——关于我在bw上的见闻,以及个人对二次元游戏行业方面的前瞻

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;今天为大家带来一点不一样的&#xff0c;首先先光速叠一下甲&#xff1a; 在此说明博主并不是一个什么都知道的大佬&#xff0c;只是一个普通的老二次元以及期望以后能…

HCIP重发布实验

目录 实验要求&#xff1a; 步骤一&#xff1a;拓扑设计IP地址规划 拓扑设计 R1 R2 R3 R4 发布路由 R1 R2 R3 R4 双向重发布 在R2和R4 上进行 R2 R4 检查R1 修改开销值选路 择优选择去4.0网段的路径 测试&#xff1a;​编辑 择优选择去32网段的路径 测试&…

短视频矩阵源码/系统搭建/源码

一、短视频矩阵系统开发需要具备以下能力 短视频技术能力&#xff1a;开发人员应具备短视频相关技术能力&#xff0c;如视频编解码、视频流媒体传输等。 大数据存储和处理能力&#xff1a;短视频矩阵系统需要处理大量的视频数据&#xff0c;因此需要具备大数据存储和处理的能力…

JavaScript快速入门:ComPDFKit PDF SDK 快速构建 Web端 PDF阅读器

JavaScript快速入门&#xff1a;ComPDFKit PDF SDK 快速构建 Web端 PDF阅读器 在当今丰富的网络环境中&#xff0c;处理 PDF 文档已成为企业和开发人员的必需品。ComPDFKit 是一款支持 Web 平台并且功能强大的 PDF SDK&#xff0c;开发人员可以利用它创建 PDF 查看器和编辑器&…

初探webAssembly | 京东物流技术团队

1 WebAssembly是什么&#xff1f; 一种运行在现代网络浏览器中的新型代码&#xff0c;并且提供新的性能特性和效果 W3C WebAssembly Community Group开发的一项网络标准&#xff0c;对于浏览器而言&#xff0c;WebAssembly 提供了一条途径&#xff0c;让各种语言编写的代码以接…

【Visual Studio】VS调用tensorflow C++API的配置(无需编译)

windows利用vs2015调用tensorflow c api 1. 首先下载并安装visual studio Visual Studio 2015 安装教程&#xff08;附安装包&#xff09;&#xff0c;按照博客中顺序来就可以 如果在安装过程中提示安装包丢失或损坏&#xff0c;参考VS2015安装过程中安装包丢失或损坏解决办…