驱动开发

编写led灯驱动:

驱动代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/err.h>
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include<linux/io.h>
#include<linux/delay.h>
#include<linux/string.h>
#define CHRNAME "ledchrdev"

unsigned int *led1_odr;
unsigned int *led2_odr;
unsigned int *led3_odr;

unsigned int *vir_moder;
unsigned int *vir_rcc;

char buf[100] = {0};
int major = 0;
ssize_t ledchrdev_write (struct file *fd, const char __user *user, size_t count, loff_t *off)
{
    int ret = 0;
    if(count>sizeof(buf))
    count=sizeof(buf);
    ret = copy_from_user(buf,user,count);
    if(ret)
    {
        printk("数据从内核拷贝失败\r\n");
        return -EIO;
    }
    switch(buf[0])
    {
        case '1':
        {
            *led1_odr |= (1<<10);
        }
        break;
        case '2':
        {
            *led2_odr |= (1<<10);
        }
        break;
        case '3':
        {
            *led3_odr |= (1<<8);
        }
        break;
        case '0':
        {
            *led1_odr &= (~(1<<10));
            *led2_odr &= (~(1<<10));
            *led3_odr &= (~(1<<8));
        }
        break;
    }
    
    return count;

}
int ledchrdev_open (struct inode *node, struct file *fd)
{
    return 0;
}
int ledchrdev_release (struct inode *node, struct file *fd)
{
    return 0;
}

struct file_operations ledchrdev_fops = 
{
    .open = ledchrdev_open,
    .release = ledchrdev_release,
    .write = ledchrdev_write,
};

static void led_init(void)
{
    //led1初始化
    vir_moder = ioremap(0x50006000,4);
    led1_odr = ioremap(0x50006014,4);
    vir_rcc = ioremap(0x50000A28,4);

    *vir_moder &= (~(3<<20));
    *vir_moder |= (1<<20);
     *led1_odr &= (~(1<<10));
    *vir_rcc |= (1<<4);
    printk("led1_init success!\r\n");

    //led2初始化
    vir_moder = ioremap(0x50007000,4);
    led2_odr = ioremap(0x50007014,4);
    vir_rcc = ioremap(0x50000A28,4);

    *vir_moder &= (~(3<<20));
    *vir_moder |= (1<<20);
    *led2_odr &= (~(1<<10));
    *vir_rcc |= (1<<5);
     printk("led2_init success!\r\n");


    //led3初始化
    vir_moder = ioremap(0x50006000,4);
    led3_odr = ioremap(0x50006014,4);
    vir_rcc = ioremap(0x50000A28,4);

    *vir_moder &= (~(3<<16));
    *vir_moder |= (1<<16);
     *led3_odr &= (~(1<<8));
    *vir_rcc |= (1<<4);
    printk("led3_init success!\r\n");

}


//gpioe_moder[21:20]->01 0X50006000
//GPIOE_ODR[10]->1 0X50006014
//RCC_MP_AHB4ENSETR->1 0X50000A28
static int __init ledchrdev_init(void)
{
    major = register_chrdev(0,CHRNAME,&ledchrdev_fops);
    if(major < 0)
    {
        printk("register_chrdev failed!\r\n");
        return major;
    }
    led_init();

    printk("major = %d\r\n",major);
    printk("ledchrdev init\r\n");
    return 0;
}



static void __exit ledchrdev_exit(void)
{
    iounmap(vir_moder);
    iounmap(led1_odr);
    iounmap(led2_odr);
    iounmap(led3_odr);
    iounmap(vir_rcc);

    unregister_chrdev(major,CHRNAME);
    printk("ledchrdev exit\r\n");
}

module_init(ledchrdev_init);
module_exit(ledchrdev_exit);
MODULE_LICENSE("GPL");

应用测试代码:

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
void delay()
{
    int i,j;
    for(i=0;i<4000;i++)
        for(j=0;j<2000;j++);
}
int main()
{
    char buf[128] = {};
    int fd = open("/dev/ledchrdev",O_RDWR);
    if(fd<0)
    {
        printf("打开设备文件失败\n");
        return -1;
    }
    while(1)
    {
        printf("请输入命令 0:关灯   1:LED1  2:LED2   3:LED3    4:流水灯\n");
        fgets(buf,sizeof(buf),stdin);
        buf[strlen(buf)-1] = '\0';
        if(buf[0] == '4')
        {
            while(1)
            {
                if((buf[0]++) == '4')
                {
                    buf[0] = '1';
                }
                delay();
                write(fd,buf,sizeof(buf));
                delay();
                write(fd,"0",sizeof("0"));
            }
        }
        write(fd,buf,sizeof(buf));
    }
    close(fd);
    return 0;
}

实现结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值