头文件
#define LED_ON _IO('L',0) /*给ioctl函数用的*/
#define LED_OFF _IO('L',1) /*给ioctl函数用的*/
/*给write函数来实现时用的*/
struct led_action
{
int action; /*ON = LED_ON, OFF = LED_OFF*/
int nr; /*0 = LED1,1 = LED2,2 =LED3, 3 = LED4*/
};
应用层序
#include
#include
#include
#include
#include "led.h"
int main(int argc, const char *argv[])
{
int fd;
int i = 0;
fd = open("/dev/led", O_RDWR);
if(fd < 0)
{
perror("open");
exit(1);
}
while(1)
{
ioctl(fd, LED_ON, i);
usleep(100000);
ioctl(fd, LED_OFF, i);
usleep(100000);
i++;
if(i == 4)
i = 0;
}
return 0;
}
驱动实现函数
#include
#include
#include
#include
#include
#include
#include
#include
#include "led.h"
#define s5pc100_GPG3CON 0xe03001c0
#define s5pc100_GPG3DAT 0xe03001c4
dev_t devno;
int led_major = 250;
int led_minor = 0;
int number_of_devices = 1;
MODULE_LICENSE("GPL");
struct led_device
{
struct cdev cdev;
void __iomem *gpg3con;
void __iomem *gpg3dat;
};
struct led_device *led_device;
static int s5pc100_led_open(struct inode *inode,struct file *file)
{
return 0;
}
static int s5pc100_led_close(struct inode *inode,struct file *file)
{
return 0;
}
static int s5pc100_led_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg)
{
switch(cmd)
{
case LED_ON:
writel((readl(led_device->gpg3dat) & ~0xf)| 0x1 << arg,led_device->gpg3dat);
break;
case LED_OFF:
writel(readl(led_device->gpg3dat) & ~(0x1 cdev,&led_fops);
led_device->cdev.owner = THIS_MODULE;
ret = cdev_add(&led_device->cdev,devno,number_of_devices);
if(ret < 0)
{
printk(KERN_ERR "can't add led_device error = %d\n",ret);
goto err2;
}
printk(KERN_INFO "device have done!\n");
/*映射IO*/
led_device->gpg3con = ioremap(s5pc100_GPG3CON,4);
if(led_device->gpg3con == NULL)
{
ret = -ENOMEM;
goto err3;
}
led_device->gpg3dat = ioremap(s5pc100_GPG3DAT,4);
if(led_device->gpg3dat == NULL)
{
ret = -ENOMEM;
goto err4;
}
/*初始化寄存器,设置io为输出模式,并让灯全亮*/
writel((readl(led_device->gpg3con) & ~0xffff)| 0x1111,led_device->gpg3con);
writel(readl(led_device->gpg3dat) | 0xf,led_device->gpg3dat);
printk(KERN_INFO "write ok!\n");
return 0;
err4:
iounmap(led_device->gpg3con);
err3:
cdev_del(&led_device->cdev);
err2:
kfree(led_device);
err1:
unregister_chrdev_region(devno,number_of_devices);
return ret;
}
static void __exit s5pc100_led_exit(void)
{
iounmap(led_device->gpg3dat);
iounmap(led_device->gpg3con);
cdev_del(&led_device->cdev);
kfree(led_device);
unregister_chrdev_region(devno,number_of_devices);
}
module_init(s5pc100_led_init);
module_exit(s5pc100_led_exit);
阅读(2454) | 评论(0) | 转发(0) |