#ifndef __HEAD_H__
#define __HEAD_H__
// #define PHY_LED1_MODER 0X50006000
// #define PHY_LED1_ODR 0X50006014
// #define PHY_RCC 0X50000A28
//定义寄存器组织结构体
typedef struct{
unsigned int moder;
unsigned int otyper;
unsigned int ospeedr;
unsigned int pupdr;
unsigned int idr;
unsigned int odr;
}gpio_t;
//定义GPIOE和GPIOF
#define GPIOE ((gpio_t *)0X50006000)
#define GPIOF ((gpio_t *)0X50007000)
#define RCC (*(volatile unsigned int *)0X50000A28)
#endif
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char buf[128] = {0};
int fd = open("/dev/mychrdev", O_RDWR);
if (fd < 0)
{
printf("打开设备文件失败\n");
exit(-1);
}
while (1)
{
printf("请输入控制哪个灯-- 1:led1 2:led2 3:led3 1:开 0关>>");
fgets(buf, sizeof(buf), stdin);
buf[strlen(buf)-1] = '\0';
write(fd, buf, sizeof(buf));
}
close(fd);
return 0;
}
#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/io.h>
#include "head.h"
int major; //用于保留主设备号
char kbuf[128] = {0};
unsigned int *led1_moder;
unsigned int *led1_odr;
unsigned int *led2_moder;
unsigned int *led2_odr;
unsigned int *led3_moder;
unsigned int *led3_odr;
unsigned int *vir_rcc;
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;
size = sizeof(kbuf) < size ? sizeof(kbuf) : size;
ret = copy_to_user(ubuf, kbuf, size);
if(ret)
{
printk("copy_to_user failed\n");
return -EIO;
}
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;
size = sizeof(kbuf) < size ? sizeof(kbuf) : size;
ret = copy_from_user(kbuf, ubuf, size);
if(ret)
{
printk("copy_from_user failed\n");
return -EIO;
}
//开关灯逻辑
if(kbuf[0] == '1')
{
// 1 开灯 0 关灯
if(kbuf[1] == '1')
{
(*led1_odr) |= (0x1 << 10);
}else{
(*led1_odr) &= (~(0x1 << 10));
}
}else if(kbuf[0] == '2')
{
if(kbuf[1] == '1')
{
(*led2_odr) |= (0x1 << 10);
}else{
(*led2_odr) &= (~(0x1 << 10));
}
}else if(kbuf[0] == '3')
{
if(kbuf[1] == '1')
{
(*led3_odr) |= (0x1 << 8);
}else{
(*led3_odr) &= (~(0x1 << 8));
}
}
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
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, "mychrdev", &fops);
if( major < 0)
{
printk("字符设备驱动注册失败\n");
return major;
}
printk("字符设备驱动注册成功major=%d\n", major);
//映射物理寄存器
printk("这是地址:GPIOE->MODER= %x\n", GPIOE->moder);
led1_moder = ioremap(0X50006000, 4);
led1_odr = ioremap(0X50006014, 4);
led2_moder = ioremap(0X50007000, 4);
led2_odr = ioremap(0X50007014, 4);
led3_moder = ioremap(0X50006000, 4);
led3_odr = ioremap(0X50006014, 4);
vir_rcc = ioremap(0X50000A28, 4);
printk("寄存器地址映射成功\n");
//寄存器初始化
//led1
(*vir_rcc) |= (0x1 << 4); //rcc使能
(*led1_moder) &= (~(0x3 << 20)); //设置使能
(*led1_moder) |= (0x1 << 20);
(*led1_odr) &= (~(0x1 << 10)); //灭灯
//led2
(*led2_moder) &= (~(0x3 << 20)); //设置使能
(*led2_moder) |= (0x1 << 20);
(*led2_odr) &= (~(0x1 << 10)); //灭灯
//led3
(*led3_moder) &= (~(0x3 << 16)); //设置使能
(*led3_moder) |= (0x1 << 16);
(*led3_odr) &= (~(0x1 << 8)); //灭灯
printk("硬件寄存器初始化成功\n");
return 0;
}
static void __exit mycdev_exit(void)
{
//取消寄存器 地址映射
iounmap(vir_rcc);
iounmap(led1_moder);
iounmap(led1_odr);
iounmap(led2_moder);
iounmap(led2_odr);
iounmap(led3_moder);
iounmap(led3_odr);
//字符设备驱动的注销
unregister_chrdev(major, "mychrdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");