驱动操作控制LED灯

news2024/11/27 17:41:26

控制LED灯:

驱动如何操作寄存器

rgb_led灯的寄存器是物理地址,在linux内核启动之后,

在使用地址的时候,操作的全是虚拟地址。需要将物理地址

转化为虚拟地址。在驱动代码中操作的虚拟地址就相当于

操作实际的物理地址。

物理地址<------>虚拟地址

void * ioremap(phys_addr_t offset, unsigned long size)

功能:将物理地址映射成虚拟地址

参数:

@offset :要映射的物理地址

@size   :大小(字节)

返回值:成功返回虚拟地址,失败返回NULL; 

void iounmap(void  *addr)

功能:取消映射

参数:

@addr :虚拟地址

返回值:无

RGB_led 

red  :gpioa28

GPIOXOUT   :控制高低电平的   0xC001A000

GPIOxOUTENB:输入输出模式    0xC001A004

GPIOxALTFN1:function寄存器  0xC001A024

green:gpioe13

0xC001e000

blue :gpiob12

0xC001b000

指针类型加1是加的他的类型大小

驱动控制灯

#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
int major=0;
#define CNAME "hello"
char kbuf[128]={0};
int dev=0;
#define RED_BASE  0XC001A000
#define BLUE_BASE  0XC001B000
#define GREEN_BASE 0XC001E000
unsigned int *red_base=NULL;
unsigned int *blue_base=NULL;
unsigned int *green_base=NULL;



ssize_t mycdev_read (struct file *file, char __user *user, size_t size, loff_t * loff)
{
   //printk("this is read");
   if(size>128){
   	size=128;
	}
    dev=copy_to_user(user,kbuf,size);
	if(dev)
		{
		printk("copy to user errer");
		return dev;
	}
   return 0;
}
ssize_t mycdev_write (struct file *file, const char __user *user, size_t size, loff_t *loff)
{
   //printk("this is write");
      if(size>128){
   	size=128;
	}
	dev=copy_from_user(kbuf,user,size);
   return 0;
}
int mycdev_open (struct inode *inode, struct file *file)
{
   printk("this is open");
   return 0;
}
int mycdev_release (struct inode *inode, struct file *file)
{
   printk("this is close");
   return 0;
}
	
const struct file_operations fops={
   .open=mycdev_open,
   .read=mycdev_read,
   .write=mycdev_write,
   .release=mycdev_release,
};

static int __init hello_init(void)//入口
{
  major=register_chrdev(major,CNAME,&fops);
  if(major<0)
  {
   printk("register chrdev error");
  }
  red_base=ioremap(RED_BASE,36);
  if(red_base==NULL)
  	{
	  printk("red ioremap error\n");
	  return -ENOMEM;
  }
  blue_base=ioremap(BLUE_BASE,36);
  if(blue_base==NULL)
  	{
	  printk("blue ioremap error\n");
	  return -ENOMEM;
  }
    green_base=ioremap(GREEN_BASE,36);
  if(green_base==NULL)
  	{
	  printk("green ioremap error\n");
	  return -ENOMEM;
  }

	*red_base &=~(1<<28);
	*(red_base+1) |=1<<28;
	*(red_base+9) |=3<<24;


  return 0;
}
static void __exit hello_exit(void)//出口
{
  iounmap(green_base);
  iounmap(blue_base);
  iounmap(red_base);
  unregister_chrdev(major,CNAME);
}
module_init(hello_init);//告诉内核驱动的入口
module_exit(hello_exit);//告诉内核驱动的出口
MODULE_LICENSE("GPL");

应用层控制灯

驱动层(只有部分程序)

#define RED_ON *red_base |= 1<<28
#define RED_OF *red_base &= ~(1<<28)
ssize_t mycdev_write (struct file *file, const char __user *user, size_t size, loff_t *loff)
{
   //printk("this is write");
      if(size>128){
   	size=128;
	}
	dev=copy_from_user(kbuf,user,size);
	if(kbuf[0]==1)
		{
		RED_ON;
	}
	else{
		RED_OF;
	}
   return 0;
}

应用层(部分)

sleep(1);
buf[0]=buf[0]?0:1;
while(1)
	 {
    	write(fd,buf,sizeof(buf));
		sleep(1);
		buf[0]=buf[0]?0:1;
	 }

详细步骤

1.写宏定义灯的基地址

 2.虚拟地址声明

 3.去注册驱动下做地址映射

 物理地址 长度一个占四个 四九三十六

 

 其他灯同理去映射虚拟地址

 偏移地址

 int四字节 +1等于+4

 #include <linux/io.h>

取消地址

 

vi MAKEFILE

 打开开发板,关闭内核的

再make

放到nfs里

 

 进行应用:

内核层:

 

 

 

 应用层

 make一下

vi test.c

 

 

 

 

 

 vi MAKEFILE

 

 

 

 

 打开nfs

 

 

 

 

自动创建设备节点

#include 

自动创建设备节点:

struct class *cls;

cls = class_create(owner, name) /void class_destroy(struct class *cls)

功能:向用户空间提交目录信息

参数:

@owner :THIS_MODULE

@name  :目录名字

返回值:成功返回struct class *指针

失败返回错误码指针 int (-5)

if(IS_ERR(cls)){

}

struct device *device_create(struct class *class, struct device *parent,

                           dev_t devt, void *drvdata, const char *fmt, ...)

/void device_destroy(struct class *class, dev_t devt)

功能:向用户空间提交文件信息

参数:

           @class :目录名字(向用户空间提交目录信息时产生的返回值)

           @parent:NULL

           @devt  :设备号    MKDEV(major,0)

           @drvdata :NULL

           @fmt   :文件的名字

返回值:成功返回struct device *指针

              失败返回错误码指针 int (-5)

struct class*cls;
struct device *dev;	
//自动创建设备节点
	cls = class_create(THIS_MODULE,CNAME);
	if(IS_ERR(cls)){
		printk("class create error\n");
		return PTR_ERR(cls);
	}
	dev = device_create(cls,NULL,MKDEV(major,0),NULL
		,CNAME);
	if(IS_ERR(dev)){
		printk("device create error\n");
		return PTR_ERR(dev);
	}
//出口-》这里写了卸载时注销的函数
static void __exit hello_exit(void)//出口
{
  device_destroy(devc,MKDEV(major,1));//注销内容
  class_destroy(cls);//注销目录
  iounmap(green_base);
  iounmap(blue_base);
  iounmap(red_base);
  unregister_chrdev(major,CNAME);
}

注意:MKDEV(major,0)为一个宏用于配置主设备号和次设备号

详细步骤

写在入口

声明:

 在入口处

 改为

 

 

 

 

 

 make

 自动创建设备节点建立在dev里

ioctl函数

用户:

   #include 

   int ioctl(int fd, int request, ...);

(让点灯的代码变得简洁)

   参数:

@fd     : 打开文件产生的文件描述符

@request: 请求码(读写|第三个参数传递的字节的个数),

:在sys/ioctl.h中有这个请求码的定义方式。

@...    :可写、可不写,如果要写,写一个内存的地址

内核:

 long (*unlocked_ioctl) (struct file *, unsigned int,unsigned long)

作用:此函数指针原型位于struct file_operations结构体当中,配合应用层ioctl函数实现指令传递的功能

 

 vi test.c

 

 

 

 

 

 

 

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

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

相关文章

2023年5月榜单丨飞瓜数据B站UP主排行榜(哔哩哔哩)发布!

飞瓜轻数发布2023年5月飞瓜数据UP主排行榜&#xff08;B站平台&#xff09;&#xff0c;通过充电数、涨粉数、成长指数三个维度来体现UP主账号成长的情况&#xff0c;为用户提供B站号综合价值的数据参考&#xff0c;根据UP主成长情况用户能够快速找到运营能力强的B站UP主。 飞…

Git—版本管理工具

作用&#xff1a;分布式版本控制 一句话&#xff1a;在开发的过程中用于管理对文件、目录或工程等内容的修改历史&#xff0c;方便查看历史记录&#xff0c;备份以便恢复以前的版本的软件工程技术 官网下载安装&#xff1a;https://git-scm.com/ 命令大全&#xff1a;https://g…

OceanBase 4.1 全面测评及部署流程,看这篇就够了【建议收藏】

背景 测试 OceanBase 对比 MySQL&#xff0c;TiDB 的性能表现&#xff0c;数据存储压缩&#xff0c;探索多点内部项目一个数据库场景落地 Oceanbase&#xff08;MySQL->OceanBase&#xff09;。 单机测试 准备 OBD 方式部署单机 文件准备 wget https://obbusiness-pri…

Bilinear CNN:细粒度图像分类网络,对Bilinear CNN中矩阵外积的解释。

文章目录 一、Bilinear CNN 的网络结构二、矩阵外积&#xff08;outer product&#xff09;2.1 外积的计算方式2.2 外积的作用 三、PyTorch 网络代码实现 细粒度图像分类&#xff08;fine-grained image recognition&#xff09;的目的是区分类别的子类&#xff0c;如判别一只狗…

【web自动化测试】Web网页测试针对性的流程解析

前言 测试行业现在70%是以手工测试为主&#xff0c;那么只有20%是自动化测试&#xff0c;剩下的10%是性能测试。 有人可能会说&#xff0c;我现在做手工&#xff0c;我为什么要学自动化呢&#xff1f;我去学性能更好性能的人更少&#xff1f; 其实&#xff0c;性能的要求比自动…

蓝桥杯2022年第十三届决赛真题-齿轮

题目描述 这天&#xff0c;小明在组装齿轮。 他一共有 n 个齿轮&#xff0c;第 i 个齿轮的半径为 ri&#xff0c;他需要把这 n 个齿轮按一定顺序从左到右组装起来&#xff0c;这样最左边的齿轮转起来之后&#xff0c;可以传递到最右边的齿轮&#xff0c;并且这些齿轮能够起到提…

小程序容器与PWA是一回事吗?

PWA代表“渐进式网络应用”&#xff08;Progressive Web Application&#xff09;。它是一种结合了网页和移动应用程序功能的技术概念。PWA旨在提供类似于原生应用程序的用户体验&#xff0c;包括离线访问、推送通知、后台同步等功能&#xff0c;同时又具有网页的优势&#xff…

软件验收测试该怎么进行?权威的软件检测机构应该具备哪些资质?

软件测试是软件开发周期中非常重要的一个环节。软件测试的目的是发现软件在不同环境下的各种问题&#xff0c;保证软件在发布前能够达到用户的要求。软件验收测试是软件测试的最后一个环节&#xff0c;该环节主要验证软件是否满足用户需求。那么对于软件验收测试&#xff0c;该…

分布式事务二 Seata使用及其原理剖析

一 Seata 是什么 Seata 介绍 Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本…

【Spring源码】Spring源码导入Idea

1.基础环境准备 相关软件、依赖的版本号 Spring源码版本 5.3.x软件 ideaIU-2021.1.2.exeGradle gradle-7.2-bin.zip https://services.gradle.org/distributions/gradle-7.2-bin.zip - 网上说要单独下载gradle并配置环境变量&#xff0c;亲测当前5.3.X版本通过gradlew的方式进…

虚函数详解及应用场景

目录 概述1. 虚函数概述2. 虚函数的声明与重写3. 析构函数与虚函数的关系4. 虚函数的应用场景4.1. 多态性4.2. 接口定义与实现分离4.3. 运行时类型识别4.4. 多级继承与虚函数覆盖 结论 概述 虚函数是C中一种实现多态性的重要机制&#xff0c;它允许在基类中声明一个函数为虚函…

PDCCH monitoring capability

欢迎关注同名微信公众号“modem协议笔记”。 前段时间看search space set group (SSSG) switching相关内容时&#xff0c;注意到R17和R16的描述由于PDCCH monitoring capability的变化&#xff0c;内容有些不一样。于是就顺带看了下R16 R17PDCCH monitoring capability的内容。…

Domino 14.0早期测试版本

大家好&#xff0c;才是真的好。 本篇是超级图片篇&#xff0c;图片多&#xff0c;内容丰富&#xff0c;流量党请勿手残。 前天我们说到Engageug2023正在如火如荼进行&#xff0c;主题是“The Future is Now”。 因为时差的关系&#xff0c;实际上在写这篇公众号时&#xff…

设计模式(七):结构型之适配器模式

设计模式系列文章 设计模式(一)&#xff1a;创建型之单例模式 设计模式(二、三)&#xff1a;创建型之工厂方法和抽象工厂模式 设计模式(四)&#xff1a;创建型之原型模式 设计模式(五)&#xff1a;创建型之建造者模式 设计模式(六)&#xff1a;结构型之代理模式 设计模式…

Java --- springboot3之web内容协商原理

一、内容协商原理 HttpMessageConverter 定制 HttpMessageConverter 来实现多端内容协商 编写WebMvcConfigurer提供的configureMessageConverters底层&#xff0c;修改底层的MessageConverter ResponseBody由HttpMessageConverter处理 标注了ResponseBody的返回值 将会由支持它…

蹭个高考热度,中国人民大学与加拿大女王大学金融硕士项目给你更多的选择

今日各大平台热搜都被“高考”霸屏&#xff0c;朋友圈里到处都是高考的祝福。期待莘莘学子都将交上满意的答卷&#xff0c;考出理想的未来。针对职场上的我们而言高考已是过去时&#xff0c;但知识的力量却是无穷的&#xff0c;在职的我们依然可以向上生长&#xff0c;中国人民…

FreeRTOS_任务相关API函数

目录 1. 任务创建和删除 API 函数 1.1 函数 xTaskCreate() 1.2 函数 xTaskCreateStatic() 1.3 函数 xTaskCreateRestricted() 1.4 函数 vTaskDelete() 2. 任务创建和删除实验&#xff08;动态方法&#xff09; 2.1 实验程序与分析 3. 任务创建和删除实验&#xff08;静…

ZC-CLS381RGB颜色识别——配置寄存器组(上)

文章目录 前言一、ZC-CLS381RGB简介二、配置寄存器组1.主控寄存器2.检测速率寄存器2.增益寄存器2.颜色数据寄存器 三、状态转移图和信号波形图绘制总结 前言 在现代工业生产中&#xff0c;颜色识别技术已经成为了一个非常重要的技术。颜色识别可以用于产品质量检测、物料分类、…

特瑞仕|常见电子元器件的故障现象及原因详解

​电子元器件是现代电子设备中不可或缺的组成部分&#xff0c;但在长时间的使用过程中&#xff0c;它们也可能会出现各种故障现象。本文将详细介绍一些常见电子元器件的故障现象及原因&#xff0c;以帮助读者更好地理解和处理这些问题。 一、电阻器 故障现象&#xff1a;电阻值…

湖南人的商业策略:用“副产品免费”的模式,推动主产品消费

湖南人的商业策略&#xff1a;用“副产品免费”的模式&#xff0c;推动主产品消费 什么是副产品免费模式&#xff1f;(主产品要钱&#xff0c;副产品不要钱) 免费商业模型设计的核心就是通过延长产业链&#xff0c;以此来达到利润链条的延伸&#xff0c;在这个过程中衍生和挖掘…