linux驱动开发-点亮第一个led灯

linux驱动开发-点亮第一个led灯

  • 一.背景知识
  • 二.如何写驱动程序
  • 三.实战演练
    • 3.1 查询原理图
    • 3.2 配置引脚为gpio模式
    • 3.3 配置引脚为输出模式
    • 3.4 DR寄存器
  • 四.代码实例
    • 4.1 驱动层
    • 4.2 应用层

一.背景知识

我们这里使用的是百问网的imx_6ullpro的开发板。这里和裸机不同的是,这类开发板可以运行linux操作系统,所以和裸机开发有点不同。
另外前面博主以及写过51,32单片机的技术博客,入门都是从点灯开始,这里也不例外。

二.如何写驱动程序

其实驱动程序和我们的裸机程序也类似。也需要操作寄存器来控制引脚。而不同的是程序是运行在操作系统之上的,可以调用标准c库以及内核提供的函数接口,且需要将文件编译为ko文件,加载进linux内核中才能运行。下面我通过实际代码来讲解驱动程序,这样才能更加理解驱动。

三.实战演练

3.1 查询原理图

我们可以看原理图得知,开发板上有一个led可以操控,引脚为GPIO5_3,这样我们只需要操作对应寄存器即可。

3.2 配置引脚为gpio模式

可以看到此寄存器地址:0x02290000+0x14,需要将此寄存器的MUX_MODE配置为101才能使用GPIO5_IO3。
请添加图片描述

3.3 配置引脚为输出模式

可以看出地址为0x020A_C004,配置0为输入模式,配置1为输出模式
请添加图片描述

3.4 DR寄存器

DR寄存器也就是配置引脚输出电平是高电平还是低电平
请添加图片描述

四.代码实例

前面都是相关知识的介绍,包括原理图以及寄存器。下面我们进行代码的讲解。

4.1 驱动层

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <asm/io.h>static int major;
static struct class *led_class;/* registers */
// IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 地址:0x02290000 + 0x14
static volatile unsigned int *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3;// GPIO5_GDIR 地址:0x020AC004
static volatile unsigned int *GPIO5_GDIR;//GPIO5_DR 地址:0x020AC000
static volatile unsigned int *GPIO5_DR;static ssize_t led_write(struct file *filp, const char __user *buf,size_t count, loff_t *ppos)
{char val;int ret;/* copy_from_user : get data from app */ret = copy_from_user(&val, buf, 1);/* to set gpio register: out 1/0 */if (val){/* set gpio to let led on */*GPIO5_DR &= ~(1<<3);}else{/* set gpio to let led off */*GPIO5_DR |= (1<<3);}return 1;
}static int led_open(struct inode *inode, struct file *filp)
{/* enable gpio5* configure gpio5_io3 as gpio* configure gpio5_io3 as output */*IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 &= ~0xf;*IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 |= 0x5;*GPIO5_GDIR |= (1<<3);return 0;
}static struct file_operations led_fops = {.owner		= THIS_MODULE, //默认THIS_MOUDLE.write		= led_write, //绑定应用层write函数.open		= led_open,//绑定应用层open函数
};/* 入口函数 */
static int __init led_init(void)
{printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);//注册设备,返回主设备号major = register_chrdev(0, "100ask_led", &led_fops);/* ioremap *///物理地址转换为裸机地址IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = ioremap(0x02290000 + 0x14, 4);// GPIO5_GDIR 地址:0x020AC004GPIO5_GDIR = ioremap(0x020AC004, 4);//GPIO5_DR 地址:0x020AC000GPIO5_DR  = ioremap(0x020AC000, 4);//创建设备类led_class = class_create(THIS_MODULE, "myled");//创建设备device_create(led_class, NULL, MKDEV(major, 0), NULL, "myled"); /* /dev/myled */return 0;
}
//出口函数
static void __exit led_exit(void)
{iounmap(IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3);iounmap(GPIO5_GDIR);iounmap(GPIO5_DR);device_destroy(led_class, MKDEV(major, 0));class_destroy(led_class);unregister_chrdev(major, "100ask_led");
}module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");

4.2 应用层

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>// ledtest /dev/myled on
// ledtest /dev/myled offint main(int argc, char **argv)
{int fd;char status = 0;if (argc != 3){printf("Usage: %s <dev> <on|off>\n", argv[0]);printf("  eg: %s /dev/myled on\n", argv[0]);printf("  eg: %s /dev/myled off\n", argv[0]);return -1;}// openfd = open(argv[1], O_RDWR);if (fd < 0){printf("can not open %s\n", argv[0]);return -1;}// writeif (strcmp(argv[2], "on") == 0){status = 1;}write(fd, &status, 1);return 0;	
}

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

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

相关文章

python爬虫selenium和ddddocr使用

python爬虫selenium和ddddocr使用 selenium使用 selenium实际上是web自动化测试工具&#xff0c;能够通过代码完全模拟人使用浏览器自动访问目标站点并操作来进行web测试。 通过pythonselenium结合来实现爬虫十分巧妙。 由于是模拟人的点击来操作&#xff0c;所以实际上被反…

SSM培训报名管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 SSM 培训报名管理系统是一套完善的信息系统&#xff0c;结合SSM框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主 要采用B/S模式开…

BUUCTF 小明的保险箱 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 小明有一个保险箱&#xff0c;里面珍藏了小明的日记本&#xff0c;他记录了什么秘密呢&#xff1f;。。。告诉你&#xff0c;其实保险箱的密码四位纯数字密码。 密文&#xff1a; 下载附件&#xff0c;得到一张.jpg…

【CPP】类和对象

1- Classes and Objects Structures A struct in C is a type consisting of a sequence of data membersSome functions/Statements are needed to operate the data members of an object of a struct type 不不小心操作错误&#xff0c;不小心越界 Classes You should b…

【SVN内网穿透】实现远程访问Linux SVN服务

文章目录 前言1. Ubuntu安装SVN服务2. 修改配置文件2.1 修改svnserve.conf文件2.2 修改passwd文件2.3 修改authz文件 3. 启动svn服务4. 内网穿透4.1 安装cpolar内网穿透4.2 创建隧道映射本地端口 5. 测试公网访问6. 配置固定公网TCP端口地址6.1 保留一个固定的公网TCP端口地址6…

Django实战项目-学习任务系统-用户管理

接着上期代码框架&#xff0c;开发第6个功能&#xff0c;用户管理&#xff0c;查看用户信息和学生用户属性值&#xff0c;尤其是总积分值&#xff0c;还可以查看积分流水明细&#xff0c;完成任务奖励积分&#xff0c;兑换物品消耗积分。 第一步&#xff1a;编写第6个功能-用户…

uniapp中APP端使用echarts用formatter设置y轴保留2位小数点不生效

uniapp使用echarts&#xff0c;在内置浏览器中&#xff0c;设置保留2位小数能正常显示&#xff08;代码如下&#xff09;&#xff0c;但是在APP端这个设置不起作用。 yAxis: {type: value,axisLabel: {formatter: function (val) {return val.toFixed(2); //y轴始终保留小数点…

idea使用MyBatisX插件

1.MyBatisX功能 (1).实现mapper和xml的跳转 (2).自动生成java文件&#xff0c;比如mapper、service、dao、pojo 2.安装MyBatisX插件 install后然后重启idea即可 3.使用MyBatieX实现mapper和xml跳转 &#xff08;1&#xff09;.点击mapper中的红色图标即可跳转到对应的xml方…

echarts 饼图中心添加图片

需求 问题 - 暂时无法解决&#xff08;如果图标居中不存在该问题&#xff09; 由于此处饼图位置不处于当前 echarts 图表容器的中心位置&#xff0c;而是偏左一点&#xff0c;我们需要设置&#xff1a; 中心图片所在靠左位置【见 - 主要代码1】官方手册 https://echarts.apache…

Android 优质的UI组件汇总

1、RuleView &#xff1a;Android自定义标尺控件(选择身高、体重等) 链接&#xff1a;https://github.com/cStor-cDeep/RuleView 2、DashboardView &#xff1a;Android自定义仪表盘View&#xff0c;仿新旧两版芝麻信用分、炫酷汽车速度仪表盘 链接&#xff1a;https://git…

VsCode 只有一个标签页 编辑区只能打开一个文件

产生如图所示的问题&#xff1a; 可能是不小心取消了勾选 勾选&#xff0c;Show Tabs

Flutter笔记:完全基于Flutter绘图技术绘制一个精美的Dash图标(下)

Flutter笔记 完全基于Flutter绘图技术绘制一个精美的Dart吉祥物Dash 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/arti…