驱动day8作业

news2024/12/29 14:21:34

基于GPIO子系统编写cdLED驱动,编写应用程序进行测试

设置定时器,5秒钟打印一次hello world

驱动程序

#include <linux/init.h>
#include <linux/module.h>
#include<linux/of.h>
#include<linux/of_gpio.h>
#include<linux/gpio.h>
#include <linux/timer.h>
#include <linux/fs.h>
#include <linux/io.h>
#include <linux/device.h>
#include "head.h"

int major; //字符设备驱动注册主设备号
struct class *cls;    //用于向上提交目录
struct device *dev;    //用于向上提交设备节点
//unsigned  int gpiono;
struct gpio_desc *gpiono[3];
struct timer_list mytimer;   //分配定时器对象

//封装操作方法
int mycdev_open(struct inode *inode, struct file *file)
{
	printk("%s:%s:%d\n", __FILE__,__func__,__LINE__);
	return 0;
}

ssize_t mycdev_read(struct file *file, char *ubuf, size_t size,loff_t *lof)
{
	printk("%s:%s:%d\n", __FILE__,__func__,__LINE__);
	return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *lof)
{
	printk("%s:%s:%d\n", __FILE__,__func__,__LINE__);
	return 0;
}
long mycdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	printk("%s:%s:%d\n", __FILE__,__func__,__LINE__);
	int which;
	int ret = copy_from_user(&which, (void*)arg,4); 
	if(ret)
	{
		printk("copy_from_user failed\n");
		return -EIO;
	}
	switch(cmd)
	{
		case LED_ON:
			switch(which)
			{
				case 1:
					gpiod_set_value(gpiono[0],1);
					break;
				case 2:
					gpiod_set_value(gpiono[1], 1);
					break;
				case 3:
					gpiod_set_value(gpiono[2], 1);
					break;
			}
			break;
		case LED_OFF:
			switch(which)
			{
				case 1:
					gpiod_set_value(gpiono[0],0);
					break;
				case 2:
					gpiod_set_value(gpiono[1], 0);
					break;
				case 3:
					gpiod_set_value(gpiono[2], 0);
					break;
			}
			break;
	}
	return 0;
}
int mycdev_close(struct inode *inode, struct file *file)
{
	printk("%s:%s:%d\n", __FILE__,__func__,__LINE__);
	return 0;
}
//定义操作方法结构体变量
struct file_operations fops = {
	.open = mycdev_open,
	.read = mycdev_read,
	.write = mycdev_write,
	.unlocked_ioctl = mycdev_ioctl,
	.release = mycdev_close,
};
//定时器处理函数
void mytimer_function(struct timer_list *timer)
{
	printk("hello world\n");
	//再次启用定时器
	mod_timer(timer,jiffies+5*HZ);
} 
static int __init mycdev_init(void)
{

	//字符设备驱动注册
	major = register_chrdev(0, "mycdev",&fops);
	if(major < 0)
	{
		printk("字符设备驱动注册失败\n");
		return major;
	}

	/****************************udev创建设备节点的原************************/
	//向上提交目录
	cls = class_create(THIS_MODULE, "mycdev");
	if(IS_ERR(cls))
	{
		printk("向上提交目录失败\n");
		return -PTR_ERR(cls); 
	}
	//向上提交设备节点信息
	int i;
	for(i=0; i<3; i++)
	{
		dev = device_create(cls, NULL,MKDEV(major,i),NULL, "myled%d",i );
		if(IS_ERR(dev))
        {
            printk("向上提交设备节点失败\n");
            return -PTR_ERR(dev);
        }
	}
	printk("向上提交设备节点成功\n");
/******************************************************************/
	//解析设备树节点信息
	dnode = of_find_node_by_path("/myled");
	if(dnode == NULL)
	{
		printk("解析设备树节点失败\n");
		return -ENXIO;
	}

//新版GPIO子系统接口   在设备树节点中解析出GPIO对象,并向内核申请
    for(i=0; i<3; i++)
    {
        gpiono[i] = gpiod_get_from_of_node(dnode, "led-gpios", i, GPIOD_OUT_LOW, NULL);
    if(IS_ERR(gpiono[i]))
    {
	    printk("申请gpio信息失败\n");
	    return -PTR_ERR(gpiono[i]);
    }
}

    //初始化定时器对象
    timer_setup(&mytimer, mytimer_function, 0);
    mytimer.expires=jiffies+5*HZ;

    //注册定时器并启用
    add_timer(&mytimer);
    return 0;
}

static void __exit mycdev_exit(void)
{
	//注销定时器
	del_timer(&mytimer);
	int i;
	for(i=0; i<3; i++)
	{
	gpiod_set_value(gpiono[i], 0);
	
	//释放gpio编号
	gpiod_put(gpiono[i]);
	//销毁设备节点信息
	device_destroy(cls, MKDEV(major, i));
	}
	
	//销毁目录
	class_destroy(cls);
	//注销字符设备驱动
	unregister_chrdev(major, "mycdev");
}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");



应用程序

#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include<unistd.h>
#include<string.h>
#include "head.h"


int main(int argc, char const *argv[])
{
    int fd = open("/dev/myled0", O_RDWR);
    if(fd < 0)
    {
        printf("打开设备文件失败\n");
        exit(-1);
    }1
    while(1)
    {
        int a;
        printf("请输入1(开灯)0(关灯)>>");
        scanf("%d", &a);
        int b;
        printf("请输入 1(LED1) 2(LED2) 3(LED3)>>");
        scanf("%d", &b);
    
        switch(a)
        {
            case 1:
                ioctl(fd, LED_ON,&b);
                break;
            case 0:
                ioctl(fd, LED_OFF,&b);
                break; 
        }
    }
    close(fd);
    return 0;
}

head.h

#ifndef __HEAD_H__
#define __HEAD_H__
#define LED_ON _IOW('l', 1, int)
#define LED_OFF _IOW('l',0, int)
#endif

运行效果

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

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

相关文章

npm install报错,解决记录

第一步&#xff1a;检查和安装 我这里建议检查 1.node.js版本是否和前使用版本一致 2.npm版本是否和前使用版本一致 3.vue版本是否和前使用版本一致 4.vue脚手架是否和前使用版本一致 5.npm镜像是否和前使用版本一致 1.检查版本 【node版本】 命令&#xff1a;node -v 结果&a…

2023年下半年 系统集成项目管理工程师 真题考点(一二三四批次)(10月28、29)(网友回忆版)

文章目录 第一批部分考点整体管理采购管理风险管理二&#xff1a;EAC 第二批部分考点如下&#xff1a; 第三批部分考点如下&#xff1a; 第一批 部分考点 1、案例考了关键路径和工期&#xff0c;风险管理、采购、风险、招投标&#xff0c;整体管理。 2、计算题有关键路径和挣…

Windows下Jenkins自动化部署SpringBoot应用

Windows下Jenkins自动化部署SpringBoot应用 1、下载安装包 下载地址&#xff1a; 一个是 msi 程序&#xff1a; https://mirrors.aliyun.com/jenkins/windows/ 一个是 war 程序&#xff1a; https://get.jenkins.io/war-stable/ https://mirrors.jenkins.io/war/ 这里我…

关于线性模型的底层逻辑解读 (机器学习 细读01)

一 多元线性回归 线性回归是机器学习中 有监督机器学习 下的一种算法。 回归问题主要关注的是因变量(需要预测的值&#xff0c;可以是一个也可以是多个)和一个或多个数值型的自变量(预测变量)之间的关系。 需要预测的值:即目标变量&#xff0c;target&#xff0c;y&#xff0c…

稀疏矩阵存储

实验内容 1、&#xff08;1&#xff09;题目要求&#xff1a;如图所示&#xff0c;任意输入一个稀疏矩阵M&#xff0c;用三元组顺序表压缩存储该稀疏矩阵M&#xff0c;然后求其转置矩阵T&#xff0c;并输出转置矩阵T。 三元组的表示和初始化&#xff0c;用线性表 typedef st…

七彩童年有“米小圈”陪伴!

长期以来&#xff0c;我对孩子看的电视和动画片都很谨慎&#xff0c;怕有不好的内容会对孩子产生误导&#xff0c;不利于小孩子健康成长。令我没想到的是在这个假期里&#xff0c;“米小圈”的出现&#xff0c;让我对动画片的看法有了很大的改变&#xff0c;也让我对孩子观看动…

关爱通分享丨三大步九小步—重构管理价值链,驱动福利进阶

企业人才素质不断提升&#xff0c;对生活品质和精神层面的追求越来越高&#xff0c;也倒推企业不断改善管理、健全福利制度&#xff0c;激发员工的积极性和创造力。企业成本激增&#xff0c;但预期价值未能完全实现&#xff0c;为此&#xff0c;笔者在价值驱动管理理念的基础上…

如何使用贝锐花生壳内网穿透实现远程打印?

打印机是现在办公必不可少的工具&#xff0c;我们常常需要使用打印机复印或打印各种文件资料&#xff0c;下面给大家介绍下如何通过花生壳发布内网打印机实现外网远程打印。 PS&#xff1a;本文使用花生壳8客户端映射发布Toshiba e-STUDIO3540C打印机&#xff1b;其它打印机型…

【文献分享】基于线特征的激光雷达和相机外参自动标定

论文题目&#xff1a;Line-based Automatic Extrinsic Calibration of LiDAR and Camera 中文题目&#xff1a;基于线特征的激光雷达和相机外参自动标定 作者&#xff1a;Xinyu Zhang, Shifan Zhu, Shichun Guo, Jun Li, and Huaping Liu 作者机构&#xff1a;清华大学汽车安…

微信小程序备案教你快速小程序备案

下面是小程序备案的步骤&#xff1a; 1. 在微信公众平台上登录小程序账号&#xff0c;进入“设置”页面。 2. 点击“账号信息”栏&#xff0c;进入账号信息页面。 3. 点击“备案”栏&#xff0c;进入备案页面。 4. 在备案页面中&#xff0c;选择需要备案的域名或网站&#…

Flash(Animate)和木疙瘩的元件学习和理解

元件就是讲一个图形或素材封装到一个容器里面&#xff01;可以被任何舞台、页面通过从仓库中拖拽的方式无限重复使用&#xff0c;类似unity中的预制体&#xff01; Flash(Animate)和木疙瘩中元件唯一区别&#xff1a;木疙瘩中一个元件A中不可以添加另一个元件B&#xff01; 一…

操作系统运行机制

文章目录 操作系统运行机制特权指令VS非特权指令内核态VS用户态中断和异常内中断(异常)外中断中断机制基本原理中断处理过程 系统调用系统调用和库函数的区别为什系统调用时必须的&#xff1f;什么功能需要用到系统调用系统调用的过程小结 操作系统内核 操作系统运行机制 特权…

防火墙的技术(NAT NAT-Server 策略路由 ) 第二十课

防火墙的技术(NAT NAT-Server 策略路由 ) 第二十课 环境的准备工作 1 配置如图所示的所有的IP地址 1 配置IIP地址 2 配置防火墙中的基本配置 防火墙的默认管理口的ip地址 <USG6000-ISP-LOCAL>display current-configuration 2023-10-28 02:54:08.620 !Software Ver…

YugaByteDB -- 全新的 “PostgreSQL“ 存储层

文章目录 0 背景1 架构1.1 Master1.2 TServer1.3 Tablet 2 读写链路2.1 DDL2.2 DML2.3 事务 3 KEY 的设计4 Rocksdb 在 YB 中的一些实践总结 0 背景 YugaByteDB 的诞生也是抓住了 spanner 推行的NewSQL 浪潮的尾巴&#xff0c;以 PG 生态为基础 用C实现的 支持 SQL 以及 CQL 语…

Linux多核CPU启动内核调试(详细)总结

目录 一、综述二、调试流程简介2.1 大体流程2.2 spin-table简介 三、uboot和内核配置3.1 uboot配置3.2 timer配置3.3 GIC中断配置3.4 驱动确认3.5 SMP配置3.6 内核config配置 四、其他相关链接1、[交叉编译linux内核总结](https://blog.csdn.net/Luckiers/article/details/1245…

Apache服务的搭建与配置(超详细版)

前言 Apache是一种常见的Web服务器软件&#xff0c;广泛用于Linux和其他UNIX操作系统上。它是自由软件&#xff0c;可以通过开放源代码的方式进行自由分发和修改。Apache提供了处理静态和动态内容的能力&#xff0c;而且还支持多种编程语言和脚本&#xff0c;如PHP、Python和P…

Doremy‘s Connecting Plan(cf 906 div2)

Doremy生活在一个由编号从1到n的n个城市组成的国家&#xff0c;第二个城市居住着ai人。它可以被建模为具有n节点的无向图。最初&#xff0c;图形中没有边。现在Doremy想要使图连通。 要做到这一点&#xff0c;她可以在i和j之间添加一条边,并且满足以下条件 其中S是当前在i或j的…

分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测(自注意力机制)

分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09; 目录 分类预测 | Matlab实现KOA-CNN-BiGRU-selfAttention多特征分类预测&#xff08;自注意力机制&#xff09;分类效果基本描述程序设计参考资料 分类效果 基本描述 1.M…

基于UDP/TCP的网络通信编程实现

小王学习录 今日鸡汤Socket套接字基于UDP来实现一个网络通信程序DatagramSocket类DatagramPacket类基于UDP的服务器端代码基于UDP的客户端代码基于TCP来实现一个网络通信程序ServerSocket类Socket类基于TCP的服务器端代码基于TCP的客户端代码优化之后的服务器端代码补充TCP长短…

RabbitMQ学习04

文章目录 发布确认1. 发布确认的原理2. 发布确认的策略2.1.开启发布确认的方法2.2.单个确认2.3.批量确认发布2.4.异步确认发布2.5.如何处理异步未确认消息2.6 总结&#xff1a; 发布确认 1. 发布确认的原理 生产者将信道设置成 confirm 模式&#xff0c;一旦信道进入 confirm …