驱动程序代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LED_MAJOR 244
#define GPBCON_CFG_VAL ( (1<<10) | (1<<12) | (1<<14) | (1<<16) )
//GPB5,6,7,8 output mode
#define LED1 1
#define LED2 2
#define LED3 3
#define LED4 4
#define ON 1
#define OFF 0
static unsigned long led_major = LED_MAJOR;
struct led_dev
{
struct cdev cdev;
struct timer_list s_timer;
atomic_t led_no;
atomic_t sec_counter;
};
struct led_dev *led_devp;
volatile unsigned int *GPBCON=NULL;
volatile unsigned int *GPBDAT=NULL;
static void sec_timer_handler(unsigned long arg)
{
int num;
mod_timer(&led_devp->s_timer,jiffies+HZ);
atomic_inc(&led_devp->sec_counter);
num = atomic_read(&led_devp->led_no);
if(num == 4)
{
atomic_set(&led_devp->led_no,1);
}
else
{
}
}
atomic_inc(&led_devp->led_no);
static int led_open(struct inode *inode,struct file *filp)
{
struct timer_list *timer;
timer = &led_devp->s_timer;
init_timer(timer);
timer->function = sec_timer_handler;
timer->expires = jiffies+HZ;
add_timer(timer);
atomic_set(&led_devp->sec_counter,0);
atomic_set(&led_devp->led_no,0);
return 0;
}
static int led_release(struct inode *inode, struct file *filp)
{
del_timer(&led_devp->s_timer);
return 0;
}
static ssize_t led_read(struct file *filp, char __user *buf,
size_t size, loff_t *ppos)
{
}
int count,led_no;
int result;
count = atomic_read(&led_devp->sec_counter);
led_no = atomic_read(&led_devp->led_no);
result = (count<<3)+led_no;
if(put_user(result,(int*)buf))
{
return -EFAULT;
}
else
{
}
return sizeof(int);
static int led_ioctl(struct inode* inode, struct file* filp, unsigned int cmd,
unsigned long arg)
if( (arg > 4) || (arg < 1) )
{
printk(KERN_NOTICE "Led No. Error!\n");
}
switch(cmd)
{
case OFF: *GPBDAT |= 1<<(arg+4);
break;
case ON: *GPBDAT &= ~(1<<(arg+4));
break;
default: printk(KERN_NOTICE "cmd error!\n");
}
return 0;
{
}
static const struct file_operations led_fops =
{
.owner = THIS_MODULE,
.read = led_read,
.open = led_open,
.ioctl = led_ioctl,
.release = led_release,
};
static void led_setup_cdev(struct led_dev *dev, int index)
{
int err,devno = MKDEV(led_major,index);
cdev_init(&dev->cdev,&led_fops);
dev->cdev.owner = THIS_MODULE;
err = cdev_add(&dev->cdev,devno,1);
if(err)
{
printk(KERN_NOTICE "Error %d adding %d\n",err,index);
}
}
static int led_init(void)
{
int result;
dev_t devno = MKDEV(led_major,0);
if(led_major)
result = register_chrdev_region(devno,1,"led");
else
{
}
result = alloc_chrdev_region(&devno,0,1,"led");
led_major = MAJOR(devno);
if(result<0)
{
printk("register failed!");
return result;
}
/*涓鸿 澶囨弿杩扮粨鏋勫垎閰嶅唴瀛?/
led_devp =(struct led_dev*)kmalloc(sizeof(struct led_dev),GFP_KERNEL);
if(!led_devp)
{
result = -ENOMEM;
unregister_chrdev_region(devno,1);
}
memset(led_devp, 0 ,sizeof(struct led_dev));
led_setup_cdev(led_devp,0);
GPBCON = (volatile unsigned int*)ioremap(0x56000010,16);
GPBDAT = GPBCON+1;
*GPBCON = GPBCON_CFG_VAL;
*GPBDAT |= 0xf<<5;
return 0;
}
static void led_exit(void)
{
cdev_del(&led_devp->cdev);
kfree(led_devp);
unregister_chrdev_region(MKDEV(led_major,0),1);
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vanbreaker");
module_init(led_init);
module_exit(led_exit);
测试程序代码如下:
#include
#include
#include
#include
#include
#define ON 1
#define OFF 0
int main()
{
int fd;
int led_no,count = 0,old_count = 0;
int ret;
fd = open("/dev/led_timer",O_RDWR);
if(fd != -1)
{
while(1)
{
read(fd,&ret,sizeof(int));
led_no = ret&0x07;
count = ret>>3;
if(count != old_count)
{
if(led_no!=1)
{
ioctl(fd,OFF,led_no-1);
}
else
{
ioctl(fd,OFF,4);
}
ioctl(fd,ON,led_no);
printf("Led NO:%d
sec:%d\n",led_no,count);
old_count = count;
}
}
printf("Cannot Open File");
}
else
{
}
}