- 论坛徽章:
- 0
|
此次笔记记录了linux驱动程序的编写、加载,并通过测试程序验证,旨在掌握linux驱动程序的大体步骤和工作原理。
程序通过控制s3c2440的GPB5\6\7\8来控制四个LED灯。
1、GPIO的配置。 GPIO配置函数放在kernel-2.6.13/include/asm/arch-s3c2410/hardware.h中。例如s3c2410_gpio_cfgpin();s3c2410_gpio_setpin(), and so on, 这些函数的实现在kernel-2.6.13/arch/arm/mach-s3c2410/gpio.c中。
void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
{
void __iomem *base = S3C2410_GPIO_BASE(pin);
unsigned long mask;
unsigned long con;
unsigned long flags;
if(pin
mask = 1
}else{
mask = 3
}
local_irp_save(flags);
con = __raw_read(base+0x00);
con &= ~mask;
con |= function;
__raw_write(con, base+0x00);
local_irq_restore(flags);
}
2、在此列出micor2440开发板LED驱动程序的代码清单以作分析
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "leds" //驱动名称
#define LED_MAJOR 231 //驱动设备号
static unsigned long led_table[]={
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};
static unsigned long led_cfg_table[]={
S3C2410_GPB5_OUTP,
S3C2410_GPB6_OUTP,
S3C2410_GPB7_OUTP,
S3C2410_GPB8_OUTP,
};
static int qq2440_leds_ioctl(
struct inode *inode,
struct file *file,
unsigned int cmd,
unsigned long arg)
{
switch(cmd){
case 0:
case 1:
if(arg>4)
return -EINVAL;
s3c2410_gpio_setpin(led_table[arg], !cmd);
return 0;
default:
return -EINVAL;
}
}
static struct file_operations qq2440_leds_fops={
.owner = THIS_MODULE,
.ioctl = qq2440_leds_ioctl,
};
static int __init qq2440_leds_init(void)
{
int ret;
int i;
ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &qq2440_leds_fops);
if(ret
printk(DEVICE_NAME "can't register major number\n");
return ret;
}
devfs_mk_cdev(MKDEV(LED_MAJOR,0),S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP,DEVICE_NAME);
for(i=0;i
s3c2410_gpio_cfgpin(led_table,led_cfg_table);
s3c2410_gpio_setpin(led_table,1);
}
printk(DEVICE_NAME "initialized\n");
return 0;
}
static void __exit qq2440_leds_exit(void)
{
devfs_remove(DEVICE_NAME);
unregister_chrdev(LED_MAJOR,DEVICE_NAME);
}
module_init(qq2440_leds_init);
module_exit(qq2440_leds_exit);
3、LED测试程序
#include
#include
#include
#include
int main(int argc,char **argv)
{
int on;
int led_no;
int fd;
if(argc!=3||sscanf(argv[1],"%d",&led_no!=1)||sscanf(argv[2],"%d",&on)
!=1||on1||led_no3)
{
fprintf(stderr, "Usage:leds led_no 0|1\n");
exit(1);
}
fd = open("/dev/leds", 0);
if(fd
ioctl(fd, on, led_no);
close(fd);
return 0;
}
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/74101/showart_1896512.html |
|