Linux 嵌入式驱动开发:LED控制(2)---不依赖于linux内核程序

本文详细介绍了Mini2440开发板上的LED驱动程序实现过程,包括驱动程序my_led_module.c的主要功能、文件操作结构以及通过ioctl进行LED状态控制的方法。此外,还提供了测试程序的链接。

1、驱动程序 my_led_module.c

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <asm/io.h>
#include <linux/fs.h>
 
#define DEVICE_NAME "mini2440_leds" //设备名称
#define LED_MAJOR  260
#define LED_ON      1       //LED亮状态
#define LED_OFF     0       //LED灭状态

volatile unsigned long virt, phys;//用于存放虚拟地址和物理地址
volatile unsigned long *GPBCON, *GPBDAT, *GPBUP;//用与存放三个寄存器的地址
 
static int leds_open(struct inode *inode, struct file *file){
    return 0;
}
 
static int leds_ioctl(struct inode *inode, struct file *file
    ,unsigned int cmd, unsigned long arg){
 
    //检测是第几个LED,因开发板上只有4个,索引从0开始    
    if(arg < 0 || arg > 3){
        return -EINVAL;
    }
 
    //判断LED要执行哪种状态
    switch(cmd){
        case LED_ON:{
        	if(arg == 0){
        		*GPBDAT &= 0x1C0;
        	}
        	else if(arg == 1){
        		*GPBDAT &= 0x1A0;
        	}
        	else if(arg == 2){
        		*GPBDAT &= 0x160;
        	}
        	else if(arg == 3){
        		*GPBDAT &= 0x0E0;
        	}
            break;
        }
        case LED_OFF:{
        	if(arg == 0){
        		*GPBDAT |= 0x020;
        	}
        	else if(arg == 1){
        		*GPBDAT |= 0x040;
        	}
        	else if(arg == 2){
        		*GPBDAT |= 0x080;
        	}
        	else if(arg == 3){
        		*GPBDAT |= 0x100;
        	}
            break;
        }
        default:{
            return -EINVAL;
        }
    }
 
    return 0;
}
 
static struct file_operations leds_fops = {
    .owner 	= THIS_MODULE,
    .open	= leds_open,
    .ioctl	= leds_ioctl,
};

void led_device_init(void){
	// 0x56000010 + 0x10 包揽全所有的IO引脚寄存器地址
	phys = 0x56000010; // 0x56000010=GPBCON
	//在虚拟地址空间中申请一块长度为0x10的连续空间
	//这样,物理地址phys到phys+0x10对应虚拟地址virt到virt+0x10
	virt =(unsigned long)ioremap(phys, 0x10);
	GPBCON = (unsigned long *)(virt + 0x00);//指定需要操作的三个寄存器的地址
	GPBDAT = (unsigned long *)(virt + 0x04);
	GPBUP  = (unsigned long *)(virt + 0x08);

	// GPBCON
	*GPBCON = 0x154FD;
	// GPBDAT
	*GPBDAT = 0x1E0;
	// GPBUP
	*GPBUP = 0x7FF;
}
 
static int __init led_init(void){
    int ret;
    led_device_init();

    // 设备的注册
    ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &leds_fops);
 
    if(ret < 0){
        printk(DEVICE_NAME " register falid!\n");
    }
    else {
        printk(DEVICE_NAME " initialized!\n");
    }
 
    return ret;
}
 
static void __exit led_exit(void){
    //注销设备
    unregister_chrdev(LED_MAJOR, DEVICE_NAME);
}
 
module_init(led_init);
module_exit(led_exit);
 
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Benjamin");
MODULE_DESCRIPTION("Mini2440 led driver");

2、测试程序见:

http://my.oschina.net/hanshubo/blog/542096


转载于:https://my.oschina.net/hanshubo/blog/543672

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值