【Linux】【驱动】第一个相对完整的驱动编写

【Linux】【驱动】第一个相对完整的驱动编写

  • 1.驱动部分的代码
  • 2 app 代码
  • 3 操作相关的代码

这个章节会讲述去直接控制一个GPIO,高低电平。

因为linux不允许直接去操作寄存器,所以在操作寄存器的时候就需要使用到函数:ioremap 和iounmap
来作为寄存器的声明和注销

ioremap 做为地址的声明,如下图使用
CCM_CCGR1 = ioremap(0x20C406C, 4);

iounmap 作为取消声明。
iounmap(CCM_CCGR1);

1.驱动部分的代码

  1. 在函数的前面对寄存器的名称进行了说明,
  2. misc_init 中实现对GPIO的配置, 使能 GPIO5,设置 GPIO5_IO03 用于 GPIO,设置 GPIO5_IO03 作为 output 引脚
  3. 在misc_write 中实现了对GPIO的控制

PS:此代码还有一些不完善的地方,所以在实际的使用中可能会出现一些异常,带之后改正

#include <linux/init.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>	
#include <linux/uaccess.h>
#include <linux/io.h>


unsigned int *vir_gpio5_dr ;
 static volatile unsigned int *CCM_CCGR1 ;
static volatile unsigned int *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3;
static volatile unsigned int *GPIO5_GDIR ;
 static volatile unsigned int *GPIO5_DR ;

int misc_open(struct inode *inode, struct file *file)
{
	printk("misc_open\n");

	return 0;
}

int misc_release(struct inode *inode, struct file *file)
{
	printk("misc_release\n");
	return 0;

}

ssize_t misc_read(struct file *file,char __user *ubuf,size_t size,loff_t *loff_t)
{
	char kbuf[512] = "haha";

	if(copy_to_user(ubuf,kbuf,strlen(kbuf))!=0)
	{
		printk("error copying\n");
		return -1;
	}

	return 0;

}

ssize_t misc_write(struct file *file,const char __user *ubuf,size_t size,loff_t *loff_t)
{

	char kbuf[512] = {0};	
	if(copy_from_user(kbuf,ubuf,size)!= 0)
	{
		printk("misc_write error\n");
		return -1;

	}

	printk("kbuf = %d\n",kbuf[0]);
	if(kbuf[0] == 1)
		{
			*GPIO5_DR |=(1<<3);//设置GPIO
			printk(" kbuff  = 1\n");
		}
	else if(kbuf[0] == 0)
	{
		*GPIO5_DR &= ~(1<<3);//设置GPIO
		printk(" kbuff  = 0\n");
	}


	return 0;

}

struct file_operations misc_fops = {
	.owner	= THIS_MODULE,
	.open	= misc_open,
	.release = misc_release,
	.read	= misc_read,
	.write	= misc_write
};


struct miscdevice misc_dev = 
{
	.minor = MISC_DYNAMIC_MINOR,
	.name = "hello_misc",
	.fops = &misc_fops
};


//drivers for init
static int misc_init(void)
{
	unsigned int val;
	int ret = 0;
	ret = misc_register(&misc_dev);
	if(ret<0) 
	{
		printk("misc_register is failed\n");
		return -1;
	}
	printk("misc registe is succeed \n");
	
	//vir_gpio5_dr  = ioremap(GPIO5_DR,4);
	CCM_CCGR1 = ioremap(0x20C406C, 4);
	IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = ioremap(0x2290014, 4);
	GPIO5_GDIR = ioremap(0x020AC000 + 0x4, 4);
	GPIO5_DR = ioremap(0x020AC000 + 0, 4);
	*CCM_CCGR1 |= (3<<30);//使能 GPIO5
	//设置 GPIO5_IO03 用于 GPIO
	val = *IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3;
	val &= ~(0xf);
	val |= (5);
	*IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3 = val;

	//设置 GPIO5_IO03 作为 output 引脚
	*GPIO5_GDIR |= (1<<3);
/*
	if(vir_gpio5_dr==NULL)
	{
		printk("vir_gpio5_dr ioremap error ");
		return -EBUSY;
	}*/
	printk("GPIO5_DR ioremap ok\n");	
	
	return 0;
}


//drivers for exit 
static void misc_exit(void)
{
//
	misc_deregister(&misc_dev);

	iounmap(CCM_CCGR1);
	iounmap(IOMUXC_SNVS_SW_MUX_CTL_PAD_SNVS_TAMPER3);
	iounmap(GPIO5_GDIR);
	iounmap(GPIO5_DR);


	printk("misc exit \n");

}

module_init(misc_init);
module_exit(misc_exit);

MODULE_LICENSE("GPL");

2 app 代码

  1. 通过atoi 函数实现对命令框指令的读写,
  2. 通过write来是线对buf数字的传递
#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"


/*
 * @description		: main主程序
 * @param - argc 	: argv数组元素个数
 * @param - argv 	: 具体参数
 * @return 			: 0 成功;其他 失败
 */
int main(int argc, char *argv[])
{
	int fd;
	char buf[64] = {0};

	//fd = open(argv[1], O_RDONLY);
	fd = open("/dev/hello_misc", O_RDWR);

	if(fd < 0)
	{
		perror("open error");
		return fd;

	}
	buf[0] = atoi(argv[1]);

	write(fd,buf,sizeof(buf));
	close(fd);
	return 0;
}

3 操作相关的代码

编译app 代码

arm-buildroot-linux-gnueabihf-gcc -o miscApp miscApp.c

编译驱动代码
make

清除驱动代码
make clean

挂载nfs

mount -t nfs -o nolock,vers=3 192.168.5.15:/home/book/nfs_rootfs /mnt

删除文件

rm -f + chrdevbase.ko

传递文件,将misc.ko 传到 /home/book/nfs_rootfs/

cp misc.ko /home/book/nfs_rootfs/

允许PrintK

echo "7 4 1 7"> /proc/sys/kernel/printk

安装驱动

insmod misc.ko

列出驱动列表

lsmod

移除驱动

 rmmod misc

给驱动传递数据1

./miscApp 1

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

线性代数的学习和整理10:各种特殊类型的矩阵(草稿-----未完成 建设ing)

目录 1 图形化分类 1.1对称矩阵 1.2 梯形矩阵 1.3 三角矩阵 1.3.1 上三角矩阵 1.4 对角线矩阵 2 按各自功能分 2.1 等价矩阵 2.2 增广矩阵 2.3 伴随矩阵 2.4 正交矩阵 2.5 正交矩阵 2.6 相似矩阵 1 图形化分类 1.1对称矩阵 1.2 梯形矩阵 1.3 三角矩阵 1.3.1 上…

【ARM-Linux】项目,语音刷抖音项目

文章目录 所需器材装备操作SU-03T语音模块配置代码&#xff08;没有用wiring库&#xff0c;自己实现串口通信&#xff09;结束 所需器材 可以百度了解以下器材 orangepi-zero2全志开发板 su-03T语音识别模块 USB-TTL模块 一个安卓手机 一根可以传输的数据线 装备操作 安…

windows Etcd的安装与使用

一、简介 etcd是一个分布式一致性键值存储&#xff0c;其主要用于分布式系统的共享配置和服务发现。 etcd由Go语言编写 二、下载并安装 1.下载地址&#xff1a; https://github.com/coreos/etcd/releases 解压后的目录如下&#xff1a;其中etcd.exe是服务端&#xff0c;e…

C语言弯道超车必做好题锦集(编程题)

目录 前言&#xff1a; 1.计算日期到天数转换 2.尼科彻斯定理 3.密码检查 4.图片整理 5.寻找数组的中心下标 6.字符个数统计 7.多数元素 前言&#xff1a; 编程想要学的好&#xff0c;刷题少不了&#xff0c;我们不仅要多刷题&#xff0c;还要刷好题&#xff01;为此我…

C# .aspx网页获取RFID读卡器HTTP协议提交的访问文件Request获得卡号、机号,Response回应驱动读卡器显示响声

本示例使用的设备&#xff1a;RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) 服务端代码&#xff1a; using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.…

iptables的使用规则

环境中为了安全要限制swagger的访问&#xff0c;最简单的方式是通过iptables防火墙设置规则限制。 在测试服务器中设置访问swagger-ui.html显示如下&#xff0c;区分大小写&#xff1a; iptables设置限制访问9783端口的swagger字段的请求&#xff1a; iptables -A INPUT -p t…

Python可视化工具库实战

Matplotlib Matplotlib 是 Python 的可视化基础库&#xff0c;作图风格和 MATLAB 类似&#xff0c;所以称为 Matplotlib。一般学习 Python 数据可视化&#xff0c;都会从 Matplotlib 入手&#xff0c;然后再学习其他的 Python 可视化库。 Seaborn Seaborn 是一个基于 Matplo…

Vue 中 diff 算法原理

一、Diff 概念 Vue 基于虚拟 DOM 做更新。diff 算法的核心就是比较两个虚拟节点的差异&#xff0c;返回一个 patch 对象&#xff0c;这个对象的作用就是存储两个节点不同的地方&#xff0c;最后用 patch 里记录的信息进行更新真实DOM。 diff 算法的在很多场景下都有应用&#…

计算机竞赛 地铁大数据客流分析系统 设计与实现

文章目录 1 前言1.1 实现目的 2 数据集2.2 数据集概况2.3 数据字段 3 实现效果3.1 地铁数据整体概况3.2 平均指标3.3 地铁2018年9月开通运营的线路3.4 客流量相关统计3.4.1 线路客流量排行3.4.2 站点客流量排行3.4.3 入站客流排行3.4.4 整体客流随时间变化趋势3.4.5 不同线路客…

6.oracle中listagg函数使用

1. 作用 可以实现行转列&#xff0c;将多列数据聚合为一列&#xff0c;实现数据的压缩 2. 语法 listagg(measure_expr&#xff0c;delimiter) within group ( order by order_by_clause); 解释&#xff1a; measure_expr可以是基于任何列的表达式 delimiter分隔符&#xff0c…

创建harbor仓库并进行一些操作

文章目录 前言一、使用mysql:5.6和 owncloud 镜像&#xff0c;构建一个个人网盘。二、安装搭建私有仓库 Harbor1、安装docker-compse2、安装harbor 3、修改配置文件4、运行脚本5 登入harbor仓库总结 前言 本篇文章需要完成的以下几个操作&#xff1a; 使用mysql:5.6和 ownclo…

爬虫逆向实战(二十)--某99网站登录

一、数据接口分析 主页地址&#xff1a;某99网站 1、抓包 通过抓包可以发现登录接口是AC_userlogin 2、判断是否有加密参数 请求参数是否加密&#xff1f; 通过查看“载荷”可以发现txtPassword和aws是加密参数 请求头是否加密&#xff1f; 无响应是否加密&#xff1f; 无…

【Git版本控制工具使用---讲解一】

Git版本控制工具使用 安装设置用户名签名和邮箱Git常用的命令 初始化本地库查看本地状态Git 命令添加暂存区提交本地库查看版本信息修改文件版本穿梭 安装 首先根据自身电脑的配置选择性的安装是32位的还是64位的Git版本控制工具 我这边安装的是64位的 以下是我安装的时候的过…

C语言:选择+编程(每日一练Day8)

目录 选择题&#xff1a; 题一&#xff1a; 题二&#xff1a; 题三&#xff1a; 题四&#xff1a; 题五&#xff1a; 编程题&#xff1a; 题一&#xff1a;字符个数统计 思路一&#xff1a; 题二&#xff1a;多数元素 思路一&#xff1a; 本人实力有限可能对一些…

事件捕获和事件冒泡

事件捕获和事件冒泡与事件流有关系。 以下代码&#xff0c;点击 aa &#xff0c;控制台会打印什么呢&#xff1f; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content&q…

Docker(一)-安装、架构、业务开发常用命令、Dockerile、镜像卷、镜像仓库

基于业务开发使用Docker Docker是一个开源的容器引擎&#xff0c;它有助于更快地交付应用。Docker可将应用程序和基础设施层隔离&#xff0c;并且能将基础设施当作程序一样进行管理。使用 Docker可更快地打包、测试以及部署应用程序&#xff0c;并可以缩短从编写到部署运行代码…

App Inventor 2 开发 ChatGPT 对话App

ChatGPT大家应该不会陌生&#xff0c;它的回答内容非常的专业及深入&#xff0c;具有实际的可指导性。我们通过App Inventor 2开发一个简单的对话App&#xff0c;先看效果&#xff1a; App Inventor 2 ChatGPT教育领域对话演示 代码块如下&#xff1a; 用到的核心组件“ChatBot…

kafka--技术文档--spring-boot集成基础简单使用

阿丹&#xff1a; 查阅了很多资料了解到&#xff0c;使用了spring-boot中整合的kafka的使用是被封装好的。也就是说这些使用其实和在linux中的使用kafka代码的使用其实没有太大关系。但是逻辑是一样的。这点要注意&#xff01; 使用spring-boot整合kafka 1、导入依赖 核心配…

Web3和去中心化:互联网的下一个演化阶段

文章目录 Web3和去中心化的定义Web3&#xff1a;去中心化&#xff1a; 为什么Web3和去中心化如此重要&#xff1f;数据隐私和安全&#xff1a;去中心化的创新&#xff1a;去除中间商&#xff1a; Web3和去中心化的应用领域去中心化金融&#xff08;DeFi&#xff09;&#xff1a…

掌握AI助手的魔法工具:解密Prompt(提示)在AIGC时代的应用「上篇」

在当今的AIGC时代&#xff0c;我们面临着越来越多的人工智能技术和应用。其中一个引人注目的工具就是Prompt&#xff08;提示&#xff09;。它就像是一种魔法&#xff0c;可以让我们与AI助手进行更加互动和有针对性的对话。那么&#xff0c;让我们一起来了解一下Prompt&#xf…