驱动启动LED

mycdev.c

#include 
#include 
#include 
#include 
#include 
#include "led.h"

unsigned int major;
char kbuf[128]={0};

//LED1  PE10
unsigned int *vir1_moder;
unsigned int *vir1_odr;
unsigned int *vir1_rcc;
//LED2  PF10
unsigned int *vir2_moder;
unsigned int *vir2_odr;
unsigned int *vir2_rcc;
//LED3  PE8
unsigned int *vir3_moder;
unsigned int *vir3_odr;
unsigned int *vir3_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 *iof)
{
    //向用户拷贝
    int ret;
    if(size> sizeof(kbuf))
        size=sizeof(kbuf);
    ret=copy_to_user(ubuf,kbuf,size);
    if(ret)
    {
        printk("向用户拷贝失败\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 *iof)
{
    int ret;
    //从用户拷贝
    if(size>sizeof(kbuf))
        size=sizeof(kbuf);
    ret=copy_from_user(kbuf,ubuf,size);
        if(ret)
    {
        printk("从用户拷贝失败\n");
        return -EIO;
    }
    if(kbuf[0]=='1')
    {
        //LED1亮灯
        (*vir1_odr) |=(0x1<<10);
    }
    else if(kbuf[0] == '0')
    {
        //LED1灭灯
        (*vir1_odr) &=(~(0x1<<10));
    }
    else if(kbuf[0] == '2')
    {
        //LED2亮灯
        (*vir2_odr) |=(0x1<<10);
    }
    else if(kbuf[0] == '3')
    {
        //LED2灭灯
        (*vir2_odr) &=(~(0x1<<10));
    }
    else if(kbuf[0] == '4')
    {
        //LED3亮灯
        (*vir3_odr) |=(0x1<<8);
    }
    else if(kbuf[0] == '5')
    {
        //LED3灭灯
        (*vir3_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,"mycdev",&fops);
    if(major<0)
    {
        printk("字符设备驱动注册失败\n");
        return major;
    }
    printk("字符设备驱动注册成功major=%d\n",major);
    //LED1相关寄存器映射
    vir1_moder=ioremap(PHY_GPIOE_MODER,4);
    if(vir1_moder==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    vir1_odr=ioremap(PHY_GPIOE_ODR,4);
    if(vir1_odr==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    vir1_rcc=ioremap(PHY_RCC,4);
    if(vir1_rcc==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    printk("LED1物理内存映射为虚拟内存成功\n");
    //LED1相关寄存器初始化 
    //GPIOE使能
    (*vir1_rcc) |= (0x1<<4); 
    //设置为输出
    (*vir1_moder) &=(~(0x3<<20));
    (*vir1_moder) |=(0x1<<20);
    //灭灯
    (*vir1_odr) &=(~(0x1<<10));
    printk("LED1相关寄存器初始化成功");
    
    //LED2相关寄存器映射
    vir2_moder=ioremap(PHY_GPIOF_MODER,4);
    if(vir2_moder==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    vir2_odr=ioremap(PHY_GPIOF_ODR,4);
    if(vir2_odr==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    vir2_rcc=ioremap(PHY_RCC,4);
    if(vir2_rcc==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    printk("LED2物理内存映射为虚拟内存成功\n");
    //LED2相关寄存器初始化 
    //GPIOF使能
    (*vir2_rcc) |= (0x1<<5); 
    //设置为输出
    (*vir2_moder) &=(~(0x3<<20));
    (*vir2_moder) |=(0x1<<20);
    //灭灯
    (*vir2_odr) &=(~(0x1<<10));
    printk("LED2相关寄存器初始化成功");
    //LED3相关寄存器映射
    vir3_moder=ioremap(PHY_GPIOE_MODER,4);
    if(vir3_moder==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    vir3_odr=ioremap(PHY_GPIOE_ODR,4);
    if(vir3_odr==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    vir3_rcc=ioremap(PHY_RCC,4);
    if(vir3_rcc==NULL)
    {
        printk("物理内存映射失败\n");
        return -EFAULT;
    }
    printk("LED3物理内存映射为虚拟内存成功\n");
    //LED3相关寄存器初始化 
    //GPIOE使能
    (*vir3_rcc) |= (0x1<<4); 
    //设置为输出
    (*vir3_moder) &=(~(0x3<<16));
    (*vir3_moder) |=(0x1<<16);
    //灭灯
    (*vir3_odr) &=(~(0x1<<8));
    printk("LED3相关寄存器初始化成功");
    return 0;
}

static void __exit mycdev_exit(void)
{
    //内存取消映射
    iounmap(vir1_rcc);
    iounmap(vir1_odr);
    iounmap(vir1_moder);
    iounmap(vir2_rcc);
    iounmap(vir2_odr);
    iounmap(vir2_moder);
    iounmap(vir3_rcc);
    iounmap(vir3_odr);
    iounmap(vir3_moder);
    //字符设备驱动的注销
    unregister_chrdev(major,"mycdev");
}

module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");

led.h

#ifndef __LED_H__
#define __LED_H__
//LED1 PE10
//LED2 PF10
//LED3 PE8

#define PHY_GPIOE_MODER 0x50006000
#define PHY_GPIOF_MODER 0x50007000
#define PHY_GPIOE_ODR 0x50006014
#define PHY_GPIOF_ODR 0x50007014
#define PHY_RCC 0x50000A28

#endif

test.c

#include 
#include 
#include 
#include 
#include 
#include 
#include "led.h"
int main(int argc,const char * argv[])
{
    char buf[128]={0};
    int fd=open("/dev/mycdev",O_RDWR);
    if(fd < 0)
    {
        printf("打开设备文件失败\n");
        return -1;
    }
    while(1)
    {
        printf("请输入控制码:0(LED1灭灯),1(LED1亮灯),2(LED2亮灯),3(LED2灭灯),4(LED3亮灯),5(LED3灭灯)\n");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1]='\0';
        write(fd,buf,sizeof(buf));
        memset(buf,0,sizeof(buf));//清空buf
    }
    close(fd);
    return 0;
}

你可能感兴趣的:(c语言)