ok6410 linux的第一个驱动LED驱动
//驱动程序代码
-
-
-
-
-
-
-
-
-
-
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
#include
-
#include
-
#include
-
-
#include
-
#include
-
#include
-
-
-
-
-
#define DEVICE_NAME "OK6410_LED"
-
-
-
-
static long OK6410_LED_ioctl(
-
struct file *file,
-
unsigned int cmd,
-
unsigned long arg);
-
static ssize_t OK6410_LED_write(
-
struct file *file,
-
const char __user *buff,
-
size_t size,
-
loff_t *loff);
-
static ssize_t OK6410_LED_read(
-
struct file *file,
-
char __user *buff,
-
size_t size,
-
loff_t *loff);
-
-
-
-
-
-
-
-
static struct file_operations dev_fops = {
-
.owner = THIS_MODULE,
-
.unlocked_ioctl = OK6410_LED_ioctl,
-
.read = OK6410_LED_read,
-
.write = OK6410_LED_write
-
};
-
-
-
static struct miscdevice misc = {
-
.minor = MISC_DYNAMIC_MINOR,
-
.name = DEVICE_NAME,
-
.fops = &dev_fops,
-
};
-
-
-
struct semaphore led_sem;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
static int __init OK6410_LED_init(void)
-
{
-
int ret;
-
unsigned int reg;
-
-
-
reg = readl(S3C64XX_GPMCON);
-
reg &= (~0xffff);
-
reg |= 0x1111;
-
writel(reg,S3C64XX_GPMCON);
-
reg = readl(S3C64XX_GPMDAT);
-
reg |= 0xf;
-
writel(reg,S3C64XX_GPMDAT);
-
-
ret = misc_register(&misc);
-
if(ret < 0)
-
{
-
printk(KERN_ALERT DEVICE_NAME " can't initialized LED!\n");
-
return ret;
-
}
-
init_MUTEX(&led_sem);
-
printk(KERN_ALERT DEVICE_NAME " initialized\n");
-
return 0;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
static long OK6410_LED_ioctl(
-
struct file *file,
-
unsigned int cmd,
-
unsigned long arg)
-
{
-
return 0;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
static ssize_t OK6410_LED_write(
-
struct file *file,
-
const char __user *buff,
-
size_t size,
-
loff_t *loff)
-
{
-
unsigned int reg;
-
-
if(down_interruptible(&led_sem))
-
return -ERESTARTSYS;
-
reg = readl(S3C64XX_GPMDAT);
-
reg &= (~0xf);
-
reg |= buff[0] & 0xf;
-
writel(reg,S3C64XX_GPMDAT);
-
up(&led_sem);
-
-
return 0;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
static ssize_t OK6410_LED_read(
-
struct file *file,
-
char __user *buff,
-
size_t size,
-
loff_t *loff)
-
{
-
unsigned int reg;
-
-
if(down_interruptible(&led_sem))
-
return -ERESTARTSYS;
-
reg = readl(S3C64XX_GPMDAT);
-
buff[0] = reg | 0xfffffff0;
-
up(&led_sem);
-
-
return 0;
-
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
static void __exit OK6410_LED_exit(void)
-
{
-
unsigned int reg;
-
-
-
reg = readl(S3C64XX_GPMCON);
-
reg &= (~0xffff);
-
writel(reg,S3C64XX_GPMCON);
-
misc_deregister(&misc);
-
}
-
-
-
-
-
module_init(OK6410_LED_init);
-
module_exit(OK6410_LED_exit);
-
-
MODULE_AUTHOR("cp1300@139.com");
-
MODULE_DESCRIPTION("OK6410(S3C6410) LED Driver");
-
MODULE_LICENSE("GPL");
//测试代码
-
-
-
-
-
-
-
-
-
-
-
#include
-
#include
-
#include
-
#include
-
#include
-
#include
-
-
-
-
int main(void)
-
{
-
int fd;
-
int retval;
-
unsigned char led;
-
-
-
printf("LED test...\n");
-
fd = open("/dev/OK6410_LED",O_RDWR);
-
if(fd == -1)
-
{
-
printf("open led error!\n");
-
exit(-1);
-
}
-
else
-
{
-
printf("open led ok!\n");
-
}
-
while(1)
-
{
-
for(retval = 0;retval < 4;retval ++)
-
{
-
led = 1 << retval;
-
led = ~led;
-
write(fd,&led,sizeof((unsigned char)1));
-
-
-
usleep(1000 * 100);
-
}
-
-
for(retval = 2;retval > 0;retval --)
-
{
-
led = 1 << retval;
-
led = ~led;
-
write(fd,&led,sizeof((unsigned char)1));
-
-
-
usleep(1000 * 100);
-
}
-
-
}
-
close(fd);
-
exit(0);
-
}
本驱动程序使用的是混杂设备驱动模型,主设备号为10,使用次设备号来区分不同的设备,使用宏MISC_DYNAMIC_MINOR可以自动分配次设备号。
makefile代码如下:
ifneq ($(KERNELRELEASE),)
obj-m:=led_drive.o
else
KERNELDIR:=/opt/kernel/linux-3.0.1
PWD:=$(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *.mod.c *.mod.o *~ module* Module*
endif
KERNELDIR为内核路径,led_drive.o中的led_drive来自于源码文件名led_drive.c
执行make编译完成后会在模块源码目录下生成led_drive.ko
在开发板创建目录/lib/modules/3.0.1/,3.0.1为内核版本,可以通过cat /proc/version查看。将led_drive.ko拷贝至/lib/modules/3.0.1/,执行insmod led_drive.ko,会在/dev/目录下生成设备文件OK6410_LED。执行ls -l OK6410_LED 可以看到其主设备号为10,自动分配的次设备号为54。执行应用程序led_drive_test,可观察到led出现流水灯效果。
阅读(1030) | 评论(0) | 转发(0) |