当前位置:网站首页>I.MX6U-驱动开发-2-LED驱动
I.MX6U-驱动开发-2-LED驱动
2022-07-29 03:32:00 【重邮研究森】
1.地址映射
Linux驱动开发可以操作寄存器,但不能直接对寄存器物理地址进行读写(裸机可以),因为linux会使能MMU。
Linux下操作的是虚拟地址,需要先把物理地址转为虚拟地址,使用方法为:
ioremap:从物理地址转为虚拟地址 虚拟地址=ioremap(物理地址,大小)

iounmap:iounmap(虚拟地址)

2.led驱动框架搭建
包括注册函数,注销函数,file_operations结构体(owner,open,release,write)
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#define LED_MAJOR 200
#define LED_NAME "led"
static int led_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int led_release(struct inode *inode,struct file *filp)
{
return 0;
}
static ssize_t led_write(struct file *filp, const char __user *buf,size_t count, loff_t *ppos)
{
return 0;
}
static const struct file_operations led_fops={
.owner=THIS_MODULE,
.write=led_write,
.open=led_open,
.release=led_release,
};
//注册
static int __init led_init(void)
{
int ret=0;
/*1.注册字符设备*/
ret=register_chrdev(LED_MAJOR,LED_NAME,&led_fops);
if(ret<0)
{
printk("register fail\r\n");
return -EIO;
}
printk("led_init\r\n");
return 0;
}
//卸载
static void __exit led_exit(void)
{
/*注销字符设备*/
unregister_chrdev(LED_MAJOR,LED_NAME);
printk("led_exit\r\n");
}
/*注册驱动和卸载驱动*/
module_init(led_init);
module_exit(led_exit);
//license
MODULE_LICENSE("GPL");
MODULE_AUTHOR("liujiasen");3.驱动程序编写
1.初始化led的IO(使能时钟,IO复用,电气属性,输入输出设置)
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#define LED_MAJOR 200
#define LED_NAME "led"
//寄存器物理地址
#define CCM_CCGR1_BASE (0X020C406C)
#define SW_MUX_GPIO1_IO03_BASE (0X020E0068)
#define SW_PAD_GPIO1_IO03_BASE (0X020E02F4)
#define GPIO1_DR_BASE (0X0209C000)
#define GPIO1_GDIR_BASE (0X0209C004)
//虚拟地址
static void __iomem *IMX6U_CCM_CCGR1;
static void __iomem *SW_MUX_GPIO1_IO03;
static void __iomem *SW_PAD_GPIO1_IO03;
static void __iomem *GPIO1_DR;
static void __iomem *GPIO1_GDIR;
#define LEDOFF 0
#define LEDON 1
//led 打开和关闭
void led_switch(u8 sta)
{
u32 val=0;
if(sta==LEDON)
{
val=readl(GPIO1_DR);//读取寄存器的值
val &=~(1<<3);//把bit3值为0 打开led
writel(val,GPIO1_DR);
}
else
{
//close led
val=readl(GPIO1_DR);//读取寄存器的值
val |=(1<<3);//把bit3值为0 close led
writel(val,GPIO1_DR);
}
}
static int led_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int led_release(struct inode *inode,struct file *filp)
{
return 0;
}
static ssize_t led_write(struct file *filp, const char __user *buf,size_t count, loff_t *ppos)
{
int retvalue;
unsigned char databuf[1];
retvalue=copy_from_user(databuf,buf,count);
if(retvalue<0)
{
printk("kernel write fail\r\n");
return -EFAULT;
}
//判断开灯还是关灯
led_switch(databuf[0]);
return 0;
}
static const struct file_operations led_fops={
.owner=THIS_MODULE,
.write=led_write,
.open=led_open,
.release=led_release,
};
//注册
static int __init led_init(void)
{
int ret=0;
unsigned int val=0;
/*1.初始化LED灯 地址映射*/
IMX6U_CCM_CCGR1=ioremap(CCM_CCGR1_BASE,4);
SW_MUX_GPIO1_IO03=ioremap(SW_MUX_GPIO1_IO03_BASE,4);
SW_PAD_GPIO1_IO03=ioremap(SW_PAD_GPIO1_IO03_BASE,4);
GPIO1_DR=ioremap(GPIO1_DR_BASE,4);
GPIO1_GDIR=ioremap(GPIO1_GDIR_BASE,4);
/*2.初始化LED灯 时钟*/
val=readl(IMX6U_CCM_CCGR1);//读取寄存器的值
val &=~(3<<26);//把26,27值为0
val |=3<<26;//把26,27值为1
writel(val,IMX6U_CCM_CCGR1);//把值写入寄存器
/*复用*/
writel(5, SW_MUX_GPIO1_IO03);
/*电器属性*/
writel(0x10B0, SW_PAD_GPIO1_IO03);
/*GPIO输入输出*/
val = readl(GPIO1_GDIR);
val &= ~(1 << 3); /* 清除以前的设置 */
val |= (1 << 3); /* 设置为输出 */
writel(val, GPIO1_GDIR);
/*莫认为高点平输出点亮led*/
val=readl(GPIO1_DR);//读取寄存器的值
val &=~(1<<3);//把bit3值为0 打开led
writel(val,GPIO1_DR);
/*1.注册字符设备*/
ret=register_chrdev(LED_MAJOR,LED_NAME,&led_fops);
if(ret<0)
{
printk("register fail\r\n");
return -EIO;
}
printk("led_init\r\n");
return 0;
}
//卸载
static void __exit led_exit(void)
{
unsigned int val=0;
//close led
val=readl(GPIO1_DR);//读取寄存器的值
val |=(1<<3);//把bit3值为0 close led
writel(val,GPIO1_DR);
/*取消地址映射*/
iounmap(IMX6U_CCM_CCGR1);
iounmap(SW_MUX_GPIO1_IO03);
iounmap(SW_PAD_GPIO1_IO03);
iounmap(GPIO1_DR);
iounmap(GPIO1_GDIR);
/*注销字符设备*/
unregister_chrdev(LED_MAJOR,LED_NAME);
printk("led_exit\r\n");
}
/*注册驱动和卸载驱动*/
module_init(led_init);
module_exit(led_exit);
//license
MODULE_LICENSE("GPL");
MODULE_AUTHOR("liujiasen");2.进行测试
通过注册和注销点亮和关闭led
4.应用程序编写
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*
ledAPP <filename> <0:1> 1:open 2close
*/
//应用程序参数个数,传入的具体参数内容,格式为字符串
int main(int argc,char *argv[])
{
int ret=0;
int fd=0;
unsigned char databuf[1];
char *filename;
char readbuf[100],writebuf[100];
static char usrdata[]={"usr data!"};
if(argc!=3)
{
printf("Eroor usage\r\n");
return -1;
}
filename=argv[1];
//RDWR具有读写
fd=open(filename,O_RDWR);
if(fd<0){
printf("can't open file %s\r\n",filename);
return -1;
}
databuf[0]=atoi(argv[2]);
ret=write(fd,databuf,sizeof(databuf));
if(ret<0)
{
printf("write fail\r\n");
close(fd);
return -1;
}
close(fd);
return 0;
}边栏推荐
- Asynchronous callback future mode of concurrent mode
- 最新二开版漫画小说听书三合一完整源码/整合免签接口/搭建教程/带采集接口
- Machine learning [numpy]
- A simple and general method to obtain the size of function stack space
- [technology 1]
- (nowcoder22529C)dinner(容斥原理+排列组合)
- Does domestic ERP have a chance to beat sap?
- Introduction and comparison of unicast, multicast (target broadcast, multicast), broadcast, flooding, flooding
- 再学EXKMP(EXKMP模板)
- Learn exkmp again (exkmp template)
猜你喜欢

Producer consumer model of concurrent model

NXP i.mx8mp-deepviewrt

Learn more than 4000 words, understand the problem of this pointing in JS, and handwrite to realize call, apply and bind

Whole process record of yolov3 target detection

for_ Example of each usage

04 | background login: login method based on account and password (Part 1)

Excel拼接数据库语句

复现20字符短域名绕过以及xss相关知识点

ShardingSphere之水平分表实战(三)

Shardingsphere's level table practice (III)
随机推荐
i. MX 8m plus integrated dedicated neural processing engine (NPU)
最新二开版漫画小说听书三合一完整源码/整合免签接口/搭建教程/带采集接口
C language programming | exchange binary odd and even bits (macro Implementation)
暴力递归到动态规划 01 (机器人移动)
通过递归实现多级联动
Swing V2: towards a larger model with larger capacity and higher resolution
HDU multi School Game 2 1011 DOS card
How to realize shortcut keys for interface scaling by vscade
Kotlin companion object vs global function
Install the packet capturing certificate
Easy to use remote sensing data set download website~~~
JS regular expression finds the number of times a character (string) appears (one line of code)
RTP send and receive h265
AI_ Drug: VAE of molecular generation model (I)
The Federal Reserve raised interest rates again, Powell "let go of doves" at 75 basis points, and US stocks reveled
Matlab learning -- structured programs and user-defined functions
VISO fast rendering convolution block
for_ Example of each usage
Flask creation process day05-06 creation project
Pp-yoloe details