分类: LINUX
2009-03-20 14:42:19
一.编写模块的初始化函数:
static int __init s
{
int ret;
ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s
if(ret < 0) {
printk(DEVICE_NAME "can't register major number\n");
return ret;
}
printk(DEVICE_NAME "initialized\n");
return 0;
}
二.编写模块的撤销函数
static void __exit s
{
unregister_chrdev(LED_MAJOR, DEVICE_NAME);
}
三.指定驱动程序的初始化函数和卸载函数
module_init(s
module_exit(s
四.定义s
static sturct file_operations s
.owner = THIS_MODULE,
.open = s
.ioctl = s
};
五.编写s
static int s
{
int i;
for(i=0; i<4; i++) {
s
}
return 0;
}
六.编写s
static int s
{
if (arg > 4) {
return -EINVAL;
}
switch(cmd) {
case IOCTL_LED_ON:
s
return 0;
case IOCTL_LED_OFF:
s
return 0;
default:
return -EINVAL;
}
}
七.加入描述信息:
MODULE_AUTHOR("ckz");
MODULE_DESCRIPTION("S
MODULE_LICENSE("GPL");
八.加入头文件信息:
#include
#include
#include
#include
#include
#include
#include
#include
九.加入宏定义:
#define DEVICE_NAME "leds" /* 加载模式后,执行”cat /proc/devices”命令看到的设备名称 */
#define LED_MAJOR 231 /* 主设备号 */
/* 应用程序执行ioctl(fd, cmd, arg)时的第2个参数 */
#define IOCTL_LED_ON 0
#define IOCTL_LED_OFF 1
/* 用来指定LED所用的GPIO引脚 */
static unsigned long led_table [] = {
S
S
S
S
};
/* 用来指定GPIO引脚的功能:输出 */
static unsigned int led_cfg_table [] = {
S
S
S
S
};
十.把源代码s
十一. 在内核根目录上执行 make modules,可以生成drivers/char/s
十二.编写驱动测试程序:
#include
#include
#include
#include
#define IOCTL_LED_ON 0
#define IOCTL_LED_OFF 1
int main(int argc, char **argv)
{
unsigned int led_no;
int fd = -1;
fd = open("/dev/leds", 0);
if (fd < 0) {
printf("Can't open /dev/leds\n");
return -1;
}
led_no = strtoul(argv[1], 0 , 0) - 1;
if (led_no > 3) {
printf("Led number too larger\n");
close(fd);
return 0;
}
if(!strcmp(argv[2], "on")) {
ioctl(fd, IOCTL_LED_ON, led_no);
} else {
ioctl(fd, IOCTL_LED_OFF, led_no);
}
close(fd);
return 0;
}
十三.测试程序的Makefile:
CROSS=arm-linux-
all: led_test
led_test: led_test.c
$(CROSS)gcc -o $@ led_test.c -static
clean:
@rm -rf led_test *.o
十四.把生成led_test程序放到文件系统中
十五.在板子的根目录中建立设备文件:
Mknod /dev/leds c 231 0
测试:
Led_test 1 on
Led_test 1 off