2023/5/17 用户程序控制三盏灯的亮灭
led1:0:灭;1:亮
led2:0:灭;1:亮
led3:0:灭;1:亮
输入格式:例:000、101
head.h
#ifndef __HEAD_H__
#define __HEAD_H__
#define RCC_AHB4_ENSETR 0x50000a28
#define GPIOE_MODER 0x50006000
#define GPIOE_ODR 0x50006014
#define GPIOF_MODER 0x50007000
#define GPIOF_ODR 0x50007014
#define GPIO_PIN_8 8
#define GPIO_PIN_10 10
#endif
mycdev.c
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"
unsigned int major;
char kbuf[128] = {0};
unsigned int *vir_rcc;
unsigned int *vir_moder1;
unsigned int *vir_odr1;
unsigned int *vir_odr3;
unsigned int *vir_moder2;
unsigned int *vir_odr2;
//封装驱动中的操作方法
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)
{
int ret;
//判断用户的需求,如果内核满足不了,给内核能满足的最大值
if(size > sizeof(kbuf))
{
size = sizeof(kbuf);
}
ret = copy_to_user(ubuf,kbuf,size);//内核向用户拷贝数据
if(ret)
{
printk("copy_to_user failed __%d__\n",__LINE__);
return ret;
}
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)
{
int ret;
//判断用户的需求,如果内核满足不了,给内核能满足的最大值
if(size > sizeof(kbuf))
{
size = sizeof(kbuf);
}
ret = copy_from_user(kbuf,ubuf,size);
if(ret)
{
printk("copy_from_user failed __%d__\n",__LINE__);
return ret;
}
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
//LED1开关
if('1' == kbuf[0])//开灯
{
(*vir_odr1) |= (1 << GPIO_PIN_10);
}else if('0' == kbuf[0])
{
(*vir_odr1) &= (~(1 << GPIO_PIN_10));
}
//LED2开关
if('1' == kbuf[1])//开灯
{
(*vir_odr2) |= (1 << GPIO_PIN_10);
}else if('0' == kbuf[1])
{
(*vir_odr2) &= (~(1 << GPIO_PIN_10));
}
//LED3开关
if('1' == kbuf[2])//开灯
{
(*vir_odr3) |= (1 << GPIO_PIN_8);
}else if('0' == kbuf[2])
{
(*vir_odr3) &= (~(1 << GPIO_PIN_8));
}
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,
.release = mycdev_close,
};
static int __init mycdev_init(void)
{
//字符设备驱动注册
major = register_chrdev(0,"mycdev",&fops);
if(major < 0)
{
printk("字符设备驱动加载失败\n");
return major;
}
printk("字符设备驱动加载成功,major = %d\n",major);
//进行LED的相关寄存器映射
vir_moder1 = ioremap(GPIOE_MODER,4);
if(NULL == vir_moder1)
{
printk("寄存器映射失败 __%d__\n",__LINE__);
return -ENOMEM;
}
vir_moder2 = ioremap(GPIOF_MODER,4);
if(NULL == vir_moder2)
{
printk("寄存器映射失败 __%d__\n",__LINE__);
return -ENOMEM;
}
vir_odr1 = ioremap(GPIOE_ODR,4);
if(NULL == vir_odr1)
{
printk("寄存器映射失败 __%d__\n",__LINE__);
return -ENOMEM;
}
vir_odr3 = ioremap(GPIOE_ODR,4);
if(NULL == vir_odr3)
{
printk("寄存器映射失败 __%d__\n",__LINE__);
return -ENOMEM;
}
vir_odr2 = ioremap(GPIOF_ODR,4);
if(NULL == vir_odr2)
{
printk("寄存器映射失败 __%d__\n",__LINE__);
return -ENOMEM;
}
vir_rcc = ioremap(RCC_AHB4_ENSETR,4);
if(NULL == vir_rcc)
{
printk("寄存器映射失败 __%d__\n",__LINE__);
return -ENOMEM;
}
printk("寄存器映射成功\n");
//寄存器初始化
//LED1、LED3初始化
(*vir_rcc) |= (1 << 4);
(*vir_moder1) &= (~(3 << GPIO_PIN_10*2));
(*vir_moder1) |= (1 << GPIO_PIN_10*2);
(*vir_odr1) &= (~(1 << GPIO_PIN_10));
(*vir_moder1) &= (~(3 << GPIO_PIN_8*2));
(*vir_moder1) |= (1 << GPIO_PIN_8*2);
(*vir_odr3) &= (~(1 << GPIO_PIN_8));
//LED2初始化
(*vir_rcc) |= (1 << 5);
(*vir_moder2) &= (~(3 << GPIO_PIN_10*2));
(*vir_moder2) |= (1 << GPIO_PIN_10*2);
(*vir_odr2) &= (~(1 << GPIO_PIN_10));
printk("寄存器初始化成功\n");
return 0;
}
static void __exit mycdev_exit(void)
{
//取消内存映射
iounmap(vir_rcc);
iounmap(vir_moder1);
iounmap(vir_moder2);
iounmap(vir_odr1);
iounmap(vir_odr2);
iounmap(vir_odr3);
//字符设备驱动注销
unregister_chrdev(major,"mycdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
demo.c
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char buf[128] = {0};
int fd = open("/dev/mycdev",O_RDWR);
if(fd < 0)
{
printf("设备文件打开失败\n");
exit(-1);
}
while(1)
{
memset(buf,0,sizeof(buf));
printf("请输入要进行的操作:");
fgets(buf,sizeof(buf),stdin);
buf[strlen(buf) -1] = 0;
write(fd,buf,sizeof(buf));
/*
memset(buf,0,sizeof(buf));
read(fd,buf,sizeof(buf));
printf("buf = %s\n",buf);
*/
}
close(fd);
return 0;
}