本文共 1974 字,大约阅读时间需要 6 分钟。
1、驱动程序 my_led_module.c
#include
#include
#include
#include
#include
#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 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
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://zxdko.baihongyu.com/