当前位置: 首页 > news >正文

012——LED模块驱动开发(基于I.MX6uLL)

目录

一、 硬件原理图

二、 驱动程序

三、 应用程序

四、 Makefile

五、操作


一、 硬件原理图

        又是非常经典的点灯环节 ,每次学新语言第一步都是hello world,拿到新板子或者学习新的操作系统,第一步就是点灯。

        LED 的驱动方式,常见的有四种。
① 使用引脚输出 3.3V 点亮 LED,输出 0V 熄灭 LED。
② 使用引脚拉低到 0V 点亮 LED,输出 3.3V 熄灭 LED。
有的芯片为了省电等原因,其引脚驱动能力不足,这时可以使用三极管驱动。
③ 使用引脚输出 1.2V 点亮 LED,输出 0V 熄灭 LED。
④ 使用引脚输出 0V 点亮 LED,输出 1.2V 熄灭 LED。
由此,主芯片引脚输出高电平/低电平,即可改变 LED 状态,而无需关注 GPIO
引脚输出的是 3.3V 还是 1.2V。所以简称输出 1 或 0:
⚫ 逻辑 1-->高电平
⚫ 逻辑 0-->低电平
        SOC级别的芯片通常电压都比较低,像我们之前用的exynos4412他是1.8V的,我们的i.MX6ULL则是可以做到更低的逻辑1,1.2V。现在最新的技术好像是0.8V的。电压降低的好处就是我们的功耗大幅减小。MCU为什么不降低呢,因为它是控制器需要高电压的驱动环境,所以一般都是3.3V和5V的。

这是板子上的LED的原理图

6ull的GPIO是这样描述的

看上面的原理图我找到了

        第五组GPIO的第三个也就是4*32+4-1 = 131

        每组GPIO有32个,我们0开始所以就是128+3 ,131就是我们的GPIO号

        知道这个就差不多可以写驱动程序了,这就是由操作系统和无操作系统的区别,裸机开发的话我们还要找到其它的寄存器,上面说到的那八个都要找到,但是因为GPIO是通用外设,操作系统已经处理过了,所以我们用的话就会很轻松,甚至可以直接给dev下的GPIO设备写值来控制。

然后我们就可以写代码了

二、 驱动程序

#include "asm-generic/errno-base.h"
#include "asm-generic/gpio.h"
#include "asm/uaccess.h"
#include <linux/module.h>
#include <linux/poll.h>#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/fcntl.h>
#include <linux/timer.h>struct gpio_desc{int gpio;int irq;char *name;int key;struct timer_list key_timer;
} ;static struct gpio_desc gpios[2] = {{131, 0, "led0", },//{132, 0, "led1", },
};/* 主设备号                                                                 */
static int major = 0;
static struct class *gpio_class;/* 实现对应的open/read/write等函数,填入file_operations结构体                   */
static ssize_t gpio_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{char tmp_buf[2];int err;int count = sizeof(gpios)/sizeof(gpios[0]);if (size != 2)return -EINVAL;err = copy_from_user(tmp_buf, buf, 1);if (tmp_buf[0] >= count)return -EINVAL;tmp_buf[1] = gpio_get_value(gpios[tmp_buf[0]].gpio);err = copy_to_user(buf, tmp_buf, 2);return 2;
}static ssize_t gpio_drv_write(struct file *file, const char __user *buf, size_t size, loff_t *offset)
{unsigned char ker_buf[2];int err;if (size != 2)return -EINVAL;err = copy_from_user(ker_buf, buf, size);if (ker_buf[0] >= sizeof(gpios)/sizeof(gpios[0]))return -EINVAL;gpio_set_value(gpios[ker_buf[0]].gpio, ker_buf[1]);return 2;    
}/* 定义自己的file_operations结构体                                              */
static struct file_operations gpio_key_drv = {.owner	 = THIS_MODULE,.read    = gpio_drv_read,.write   = gpio_drv_write,
};/* 在入口函数 */
static int __init gpio_drv_init(void)
{int err;int i;int count = sizeof(gpios)/sizeof(gpios[0]);printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);for (i = 0; i < count; i++){		/* set pin as output */err = gpio_request(gpios[i].gpio, gpios[i].name);if (err < 0) {printk("can not request gpio %s %d\n", gpios[i].name, gpios[i].gpio);return -ENODEV;}gpio_direction_output(gpios[i].gpio, 1);}/* 注册file_operations 	*/major = register_chrdev(0, "100ask_led", &gpio_key_drv);  /* /dev/gpio_desc */gpio_class = class_create(THIS_MODULE, "100ask_led_class");if (IS_ERR(gpio_class)) {printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);unregister_chrdev(major, "100ask_led_class");return PTR_ERR(gpio_class);}device_create(gpio_class, NULL, MKDEV(major, 0), NULL, "100ask_led"); /* /dev/100ask_gpio */return err;
}/* 有入口函数就应该有出口函数:卸载驱动程序时,就会去调用这个出口函数*/
static void __exit gpio_drv_exit(void)
{int i;int count = sizeof(gpios)/sizeof(gpios[0]);printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);device_destroy(gpio_class, MKDEV(major, 0));class_destroy(gpio_class);unregister_chrdev(major, "100ask_led");for (i = 0; i < count; i++){gpio_free(gpios[i].gpio);		}
}/* 7. 其他完善:提供设备信息,自动创建设备节点                                     */module_init(gpio_drv_init);
module_exit(gpio_drv_exit);MODULE_LICENSE("GPL");

三、 应用程序


#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <poll.h>
#include <signal.h>static int fd;//int led_on(int which);
//int led_off(int which);
//int led_status(int which);/** ./led_test <0|1|2|..>  on * ./led_test <0|1|2|..>  off* ./led_test <0|1|2|..>*/
int main(int argc, char **argv)
{int ret;char buf[2];int i;/* 1. 判断参数 */if (argc < 2) {printf("Usage: %s <0|1|2|...> [on | off]\n", argv[0]);return -1;}/* 2. 打开文件 */fd = open("/dev/100ask_led", O_RDWR);if (fd == -1){printf("can not open file /dev/100ask_led\n");return -1;}if (argc == 3){/* write */buf[0] = strtol(argv[1], NULL, 0);if (strcmp(argv[2], "on") == 0)buf[1] = 0;elsebuf[1] = 1;ret = write(fd, buf, 2);}else{buf[0] = strtol(argv[1], NULL, 0);ret = read(fd, buf, 2);if (ret == 2){printf("led %d status is %s\n", buf[0], buf[1] == 0 ? "on" : "off");}}close(fd);return 0;
}

四、 Makefile

韦东山老师的makefile写的有点太潦草了,我们来优化一下

CC := $(CROSS_COMPILE)gcc
FILE_NAME = led_test
DRIVER_NAME = led_drv
# 定义NFS根文件系统目录  
FS_FILE = ~/nfs_rootfsKERN_DIR =  /home/book/program/100ask_imx6ull_mini-sdk/Linux-4.9.88 # 板子所用内核源码的目录# all:
# 	make -C $(KERN_DIR) M=`pwd` modules 
# 	$(CROSS_COMPILE)gcc -o led_test led_test.c
# 默认目标  
all:  @echo "Starting build process..."  @echo "Building kernel modules..."  make -C $(KERN_DIR) M=$(PWD) modules  @echo "Building $(FILE_NAME) test program..."  $(CC) -o $(FILE_NAME) $(FILE_NAME).c  # 安装目标  
install:  @echo "Installing $(DRIVER_NAME).ko to $(FS_FILE)..."  cp ./$(DRIVER_NAME).ko $(FS_FILE)  @echo "$(DRIVER_NAME).ko installed."  @echo "Installing $(FILE_NAME) to $(FS_FILE)..."  cp ./$(FILE_NAME) $(FS_FILE)  @echo "$(FILE_NAME) installed."  clean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.order  led_test# 参考内核源码drivers/char/ipmi/Makefile
# 要想把a.c, b.c编译成ab.ko, 可以这样指定:
# ab-y := a.o b.o
# obj-m += ab.oobj-m += led_drv.o
# 声明伪目标  
.PHONY: all clean install

五、操作

每次都要重新配置网络很难受所以我这面写了个脚本上机自动配置ip并且挂载nfs 

#!/bin/bash  # 定义变量  
NFS_SERVER="192.168.5.10"  
NFS_SHARE="/home/book/nfs_rootfs"  
IPADDR="192.168.5.110"
MOUNT_POINT="/mnt"
INTERFACE="eth0"  
# 设置本机IP
sleep 1
ifconfig $INTERFACE $IPADDR
sleep 1# 测试与NFS服务器的连通性  
ping -c 1 $NFS_SERVER > /dev/null 2>&1  
if [ $? -eq 0 ]; then  echo "NFS服务器 $NFS_SERVER 连通性正常"  
else  echo "无法与NFS服务器 $NFS_SERVER 建立连接"  exit 1  
fi  # 检查挂载点是否存在,如果不存在则创建  
if [ ! -d "$MOUNT_POINT" ]; then  mkdir -p "$MOUNT_POINT"  
fi  # 尝试挂载NFS共享  
mount -t nfs -o nolock,vers=3 $NFS_SERVER:$NFS_SHARE $MOUNT_POINT  
if [ $? -eq 0 ]; then  echo "NFS共享已成功挂载到 $MOUNT_POINT"  
else  echo "无法挂载NFS共享到 $MOUNT_POINT"  exit 1  
fi

最后我们上传一下

相关文章:

012——LED模块驱动开发(基于I.MX6uLL)

目录 一、 硬件原理图 二、 驱动程序 三、 应用程序 四、 Makefile 五、操作 一、 硬件原理图 又是非常经典的点灯环节 &#xff0c;每次学新语言第一步都是hello world&#xff0c;拿到新板子或者学习新的操作系统&#xff0c;第一步就是点灯。 LED 的驱动方式&#xff0…...

基于springboot实现房屋租赁管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现房屋租赁系统演示 摘要 房屋是人类生活栖息的重要场所&#xff0c;随着城市中的流动人口的增多&#xff0c;人们对房屋租赁需求越来越高&#xff0c;为满足用户查询房屋、预约看房、房屋租赁的需求&#xff0c;特开发了本基于Spring Boot的房屋租赁系统。 …...

168.乐理基础-中古调式概述

如果到这五线谱还没记住还不认识的话去看102.五线谱-高音谱号与103.五线谱-低音谱号这两个里&#xff0c;这里面有五线谱对应的音名&#xff0c;对比着看 如果不认识调号去看112.五线谱的调号&#xff08;一&#xff09;、113.五线谱的调号&#xff08;二&#xff09;、114.快…...

【项目实战】【Docker】【Git】【Linux】部署V2rayA项目

今天着手了一个全新领域的项目&#xff0c;从完全没有头绪到成功运行&#xff0c;记录一下具体的部署流程 github项目链接V2rayA 一开始拿到以后完全没有抓手&#xff0c;去阅读了一下他的帮助文档 写着能用docker运行&#xff0c;就去下载了一个Docker配置了一下 拉取代码到…...

mac 切换 jdk

查看 mac 上都有哪些版本 /usr/libexec/java_home -V看准版本切换 按前缀切换 比如 export JAVA_HOME/usr/libexec/java_home -v 1.8这样会随机一个 1.8 的 如果想再确定一个比如 openjdk export JAVA_HOME/usr/libexec/java_home -v 1.8.0_292这个方式是临时的&#xff0c…...

MD5加密返回32位密文字符串

前言&#xff1a; 项目中需要调用其他系统的 api 接口&#xff0c;接口使用的是按一定规则生成 MD5 密文作为签名来进行身份验证&#xff0c;本文仅记录 32 位 MD5 密文的生成方式&#xff0c;仅供参考。 什么是MD5 加密&#xff1f; MD5 加密是一种加密算法&#xff0c;MD5…...

npm常用命令技巧

NPM (Node Package Manager) 是 JavaScript 的包管理工具&#xff0c;广泛用于管理项目中的依赖。无论是前端项目还是Node.js后端项目&#xff0c;NPM 都扮演着重要的角色。本文将介绍 NPM 中常用的几个命令&#xff0c;并提供相应的代码示例。 1. 初始化项目&#xff1a;npm …...

intellij idea 使用git撤销(取消)commit

git撤销(取消) 未 push的 commit Git&#xff0c;选择分支后&#xff0c;右键 Undo Commit &#xff0c;会把这个 commit 撤销。 git撤销(取消) 已经 push 的 commit 备份分支内容&#xff1a; 选中分支&#xff0c; 新建 分支&#xff0c;避免后续因为操作不当&#xff0c;导…...

【计算机网络】四层负载均衡和七层负载均衡

前言 1、分层方式 首先我们知道&#xff0c;在计算机网络中&#xff0c;常用的协议分层方式&#xff1a;OSI和TCP/IP&#xff0c;以及实际生产中使用的协议划分方式。 在OSI中&#xff0c;各层的职责如下&#xff1a; 应用层&#xff1a;对软件提供接口以使程序能使用网络服…...

IP-guard WebServer 任意文件读取漏洞复现

0x01 产品简介 IP-guard是由溢信科技股份有限公司开发的一款终端安全管理软件,旨在帮助企业保护终端设备安全、数据安全、管理网络使用和简化IT系统管理。 0x02 漏洞概述 由于IP-guard WebServer /ipg/static/appr/lib/flexpaper/php/view.php接口处未对用户输入的数据进行严…...

【IoTDB 线上小课 01】我们聊聊“金三银四”下的开源

关于 IoTDB&#xff0c;关于物联网&#xff0c;关于时序数据库&#xff0c;关于开源...你是否仍有很多疑问&#xff1f; 除了自己钻研文档&#xff0c;群里与各位“大佬”的沟通&#xff0c;你是否还希望能够有个学习“捷径”&#xff1f; 天谋科技发起社区小伙伴&#xff0c;正…...

2024053期传足14场胜负前瞻

2024053期售止时间为4月6日&#xff08;周六&#xff09;21点00分&#xff0c;敬请留意&#xff1a; 本期深盘多&#xff0c;1.5以下赔率1场&#xff0c;1.5-2.0赔率8场&#xff0c;其他场次是平半盘、平盘。本期14场难度中等。以下为基础盘前瞻&#xff0c;大家可根据自身判断…...

C语言------冒泡法排序

一.前情提要 1.介绍 冒泡法排序法&#xff1a; 1)冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它重复地遍历要排序的列表&#xff0c;一次比较相邻的两个元素&#xff0c;并且如果它们的顺序错误就将它们交换过来。重复这个过程直到没有需…...

C#(C Sharp)学习笔记_Enum枚举类型【十三】

什么是枚举类型 枚举类型(Enum) 是由基础整型数值类型的一组命名常量定义的值类型。枚举包含自己的值&#xff0c;但不能继承或传递继承。 语法 // enum enum_name // enum_name variable enum_name.enum_value// 定义一个枚举类型——例如&#xff1a; enum enum_name {va…...

乐知付-如何制作html文件可双击跳转到指定页面?

标题: 乐知付-如何制作html文件可双击跳转到指定页面&#xff1f; 标签: [乐知付, 乐知付加密, 密码管理] 分类: [网站,html] 为了便于买家理解使用链接进行付费获取密码&#xff1b;现开发个小工具&#xff0c;将支付链接转为浏览器可识别的文件&#xff0c;双击打开即可跳转到…...

电工技术学习笔记——直流电路及其分析方法

一、直流电路 电路的组成 1. 电压和电流的参考方向 电压&#xff08;Voltage&#xff09;&#xff1a;电压是电场力对电荷产生的作用&#xff0c;表示为电荷单位正电荷所具有的能量。在电路中&#xff0c;电压通常被定义为两点之间的电势差&#xff0c;具有方向性&#xff0c;…...

详解python中的迭代

如果给定一个list或tuple&#xff0c;我们可以通过for循环来遍历这个list或tuple&#xff0c;这种遍历我们称为迭代&#xff08;Iteration&#xff09;。 在Python中&#xff0c;迭代是通过for ... in来完成的&#xff0c;而很多语言比如C语言&#xff0c;迭代list是通过下标完…...

机器学习模型——集成算法(三)

前面我们说了bagging算法和Boosting算法 接下来我们学习Adaboost算法 Adaboost基本概念&#xff1a; AdaBoost &#xff08;Adaptive Boosting&#xff0c;自适应提升&#xff09;: 算法原理是将多个弱学习器进行合理的结合&#xff0c;使其成为一个强学习器。 Adaboost采用…...

企业微信企业主体变更认证介绍

企业微信变更主体有什么作用&#xff1f; 说一个自己亲身经历的事情&#xff0c;当时我在一家教育公司做运营&#xff0c;公司所有客户都是通过企业微信对接的。后来行业整顿&#xff0c;公司不得不注销&#xff0c;换了营业执照打算做技能培训&#xff0c;但发现注销后原来的企…...

如何降低AI功耗? —— 超低功耗的仿生硬件

一、背景 仿生硬件&#xff08;Bionic Hardware&#xff09;这一术语通常指的是受自然界的生物系统启发而设计制造的电子或机械硬件设备&#xff0c;它们在功能、结构、材料、能源效率等方面模仿生物体的特性&#xff0c;以实现更高效、智能、自适应或环境友好的性能。在人工智…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

C++中string流知识详解和示例

一、概览与类体系 C 提供三种基于内存字符串的流&#xff0c;定义在 <sstream> 中&#xff1a; std::istringstream&#xff1a;输入流&#xff0c;从已有字符串中读取并解析。std::ostringstream&#xff1a;输出流&#xff0c;向内部缓冲区写入内容&#xff0c;最终取…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

MySQL中【正则表达式】用法

MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现&#xff08;两者等价&#xff09;&#xff0c;用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例&#xff1a; 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

【分享】推荐一些办公小工具

1、PDF 在线转换 https://smallpdf.com/cn/pdf-tools 推荐理由&#xff1a;大部分的转换软件需要收费&#xff0c;要么功能不齐全&#xff0c;而开会员又用不了几次浪费钱&#xff0c;借用别人的又不安全。 这个网站它不需要登录或下载安装。而且提供的免费功能就能满足日常…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...