#include
#include
#include
#include
#include
#include "myled.h"
unsigned int major = 0;
gpio_t* gpioe_virt_base = NULL;
gpio_t* gpiof_virt_base = NULL;
unsigned int* rcc_ahb4_base = NULL;
char kbuf[128] = {0};
#define LED1_ON (gpioe_virt_base->ODR |= (0x1 << 10))
#define LED1_OFF (gpioe_virt_base->ODR &= (~(0x1 << 10)))
#define LED2_ON (gpiof_virt_base->ODR |= (0x1 << 10))
#define LED2_OFF (gpiof_virt_base->ODR &= (~(0x1 << 10)))
#define LED3_ON (gpioe_virt_base->ODR |= (0x1 << 8))
#define LED3_OFF (gpioe_virt_base->ODR &= (~(0x1 << 8)))
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 __user * ubuf, size_t size, loff_t *loff)
{
int ret;
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
if(size > sizeof(kbuf)) size = sizeof(kbuf);
ret = copy_to_user(ubuf,kbuf,size);
if(ret)
{
printk("copy to user is error\n");
return -EIO;
}
return size;
}
ssize_t mycdev_write(struct file *file, const char __user *ubuf, size_t size, loff_t *loff)
{
int ret;
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
if(size > sizeof(kbuf)) size = sizeof(kbuf);
ret = copy_from_user(kbuf,ubuf,size);
if(ret)
{
printk("copy from user is error\n");
return -EIO;
}
//kbuf[0] 代表哪一盏灯 kbuf[0] = 0 kbuf[1] = 1 kbuf[2] = 2
//kbuf[1] 代表灯的状态 kbuf[1] = 0 kbuf[1] = 1
switch(kbuf[0])
{
case 0:
kbuf[1]?LED1_ON:LED1_OFF;
break;
case 1:
kbuf[1]?LED2_ON:LED2_OFF;
break;
case 2:
kbuf[1]?LED3_ON:LED3_OFF;
break;
}
return size;
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
const struct file_operations fops ={
.open = mycdev_open,
.read = mycdev_read,
.write = mycdev_write,
.release = mycdev_close,
};
static int __init mycdev_init(void)
{
//1.注册字符设备驱动
major = register_chrdev(0,CNAME,&fops);
if(major < 0)
{
printk("register_chrdev is error\n");
return major;
}
//2.将GPIOE、GPIOF、RCC地址进行映射
gpioe_virt_base = ioremap(GPIOE_BASE_ADDR,sizeof(gpio_t));
if(gpioe_virt_base == NULL)
{
printk("gpioe ioremap is error\n");
return -ENOMEM;
}
gpiof_virt_base = ioremap(GPIOF_BASE_ADDR,sizeof(gpio_t));
if(gpiof_virt_base == NULL)
{
printk("gpiof ioremap is error\n");
return -ENOMEM;
}
rcc_ahb4_base = ioremap(RCC_PHY_ADDR,4);
if(rcc_ahb4_base == NULL)
{
printk("rcc ioremap is error\n");
return -ENOMEM;
}
//3.将led1灯进行初始化
*rcc_ahb4_base |= (0x3 << 4);
//1>设置GPIOE--->PE10引脚为输出模式
gpioe_virt_base->MODER &= (~(0x3 << 20));
gpioe_virt_base->MODER |= (0x1 << 20);
//2>设置GPIOE_ODR--->PE10引脚输出低电平
gpioe_virt_base->ODR &= (~(0x1 << 10));
//4.将led2灯进行初始化
//1>设置GPIOF--->PF10引脚为输出模式
gpiof_virt_base->MODER &= (~(0x3 << 20));
gpiof_virt_base->MODER |= (0x1 << 20);
//2>设置GPIOF_ODR--->PF10引脚输出低电平
gpiof_virt_base->ODR &= (~(0x1 << 10));
//3.将led3灯进行初始化
//1>设置GPIOE--->PE8引脚为输出模式
gpioe_virt_base->MODER &= (~(0x3 << 16));
gpioe_virt_base->MODER |= (0x1 << 16);
//2>设置GPIOE_ODR--->PE8引脚输出低电平
gpioe_virt_base->ODR &= (~(0x1 << 8));
return 0;
}
static void __exit mycdev_exit(void)
{
iounmap(gpioe_virt_base);
iounmap(gpiof_virt_base);
iounmap(rcc_ahb4_base);
unregister_chrdev(major,CNAME);
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
#ifndef __MYLED_H__
#define __MYLED_H__
#define CNAME "myled"
typedef struct {
volatile unsigned int MODER; // 0x00
volatile unsigned int OTYPER; // 0x04
volatile unsigned int OSPEEDR; // 0x08
volatile unsigned int PUPDR; // 0x0C
volatile unsigned int IDR; // 0x10
volatile unsigned int ODR; // 0x14
volatile unsigned int BSRR; // 0x18
volatile unsigned int LCKR; // 0x1C
volatile unsigned int AFRL; // 0x20
volatile unsigned int AFRH; // 0x24
volatile unsigned int BRR; // 0x28
volatile unsigned int res;
volatile unsigned int SECCFGR; // 0x30
}gpio_t;
#define RCC_PHY_ADDR 0x50000A28
#define GPIOE_BASE_ADDR 0x50006000
#define GPIOF_BASE_ADDR 0x50007000
#endif
#include
#include
#include
#include
#include
#include
int main(int argc, char const *argv[])
{
int fd;
char ubuf[128] = {0};
fd = open("/dev/myled",O_RDWR);
if(fd == -1)
{
perror("open is error");
exit(1);
}
while(1)
{
//LED1灯操作
ubuf[0] = 0;
ubuf[1] = 1;
write(fd,ubuf,sizeof(ubuf));
sleep(1);
ubuf[1] = 0;
write(fd,ubuf,sizeof(ubuf));
sleep(1);
//LED2灯操作
ubuf[0] = 1;
ubuf[1] = 1;
write(fd,ubuf,sizeof(ubuf));
sleep(1);
ubuf[1] = 0;
write(fd,ubuf,sizeof(ubuf));
sleep(1);
//LED3灯操作
ubuf[0] = 2;
ubuf[1] = 1;
write(fd,ubuf,sizeof(ubuf));
sleep(1);
ubuf[1] = 0;
write(fd,ubuf,sizeof(ubuf));
sleep(1);
}
close(fd);
return 0;
}