标签:des class blog code http tar
LED驱动程序主要实现了TQ2440开发板上的4个LED灯的硬件驱动,实现了对引脚GPIOB5、GPIOB6、GPIOB7、GPIOB8的高低电平设置(common-smdk.c中已经实现了对引脚的配置),利用测试程序调用该驱动程序,通过命令控制LED灯的亮灭。
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/device.h>
#define DEVICE_NAME "My_led" /**加载模块后执行cat/proc/devices中看到的设备名称**/
#define Led_MAJOR 103 /**主设备号**/
#define LED_ON 1
#define LED_OFF 0
/**Led的控制引脚**/
static unsigned long led_table[ ] =
{
S3C2410_GPB5,
S3C2410_GPB6,
S3C2410_GPB7,
S3C2410_GPB8,
};
static int My_led_open(struct inode *inode,struct file *file)
{
printk("My_led open\n");
return 0;
}
static int My_led_ioctl(struct inode * inode, struct file * file,unsigned int cmd,unsigned long arg)
{
if(arg > 4)
{
return -1;
}
switch(cmd)
{
case LED_ON:
s3c2410_gpio_setpin(led_table[arg], 0);//设置指定引脚为输出电平为0
return 0;
case LED_OFF:
s3c2410_gpio_setpin(led_table[arg], 1);//设置指定引脚为输出电平为1
return 0;
default:
return -1;
}
}
static struct file_operations My_led_fops =
{
.owner = THIS_MODULE,
.open = My_led_open,
.ioctl = My_led_ioctl,
};
static struct class *led_class;
static int __init My_led_init(void)
{
int ret;
printk("My_led start\n");
/**注册字符设备驱动程序**/
/**参数为主设备号、设备名字、file_operations结构**/
/**这样主设备号就与file_operations联系起来**/
ret = register_chrdev(Led_MAJOR, DEVICE_NAME, &My_led_fops);
if(ret < 0)
{
printk("can't register major number\n");
return ret;
}
//注册一个类,使mdev可以在"/dev/目录下建立设备节点"
led_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(led_class))
{
printk("failed in My_led class.\n");
return -1;
}
device_create(led_class, NULL, MKDEV(Led_MAJOR,0), NULL, DEVICE_NAME);
printk(DEVICE_NAME "initialized\n");
return 0;
}
static void __exit My_led_exit(void)
{
unregister_chrdev(Led_MAJOR, DEVICE_NAME);
device_destroy(led_class, MKDEV(Led_MAJOR,0));//注销设备节点
class_destroy(led_class);//注销类
}
module_init(My_led_init);
module_exit(My_led_exit);
MODULE_LICENSE("GPL");
#define DEVICE_NAME "My_led" //加载模块后执行cat/proc/devices中看到的设备名称
#define Led_MAJOR 103 //主设备号
#define LED_ON 1
#define LED_OFF 0 My_led_ioctl函数中要输入的参数命令,LED_ON会执行打开灯的命令、LED_OFF执行关闭灯的命令
定义一个led_table[ ] 数组,在后面调用时要方便些。
详细说明一下S3C2410_GPB5是什么意思:
如上图所示,是关于S3C2410_GPB5相关的所有代码。通过上面的代码可以得出S3C2410_GPB5为37。实际上S3C2410_GPB5就是端口的编号,bank是分组的基号码,offset是组内的偏移量。TQ2440开发板的GPIOB的第五个引脚为37。
此函数主要负责响应应用程序的相关命令,然后根据命令执行相关的代码。cmd命令包括宏定义的LED_ON、LED_OFF。
s3c2410_gpio_setpin()函数
自认为这是本驱动程序最重要的一个函数,它的作用是:将指定的引脚设置为低电平或者高电平。本驱动程序中只是用了内核提供的这一个接口来实现对引脚的控制,但是肯定会研究一下这个函数。
如果不注册这个类,那么当在开发板上挂载驱动之后,还要做的一件事是手动“生成设备节点”,就是利用mknod命令。但是驱动程序都是随操作系统的运行而开始工作的,因此生成设备节点要让它自动生成,而并非手动。所以才会注册这样一个类,在挂载驱动之后,自动将设备节点生成。注册类的核心代码:
led_class = class_create(THIS_MODULE, DEVICE_NAME);
if(IS_ERR(led_class))
{
printk("failed in My_led class.\n");
return -1;
}
device_create(led_class, NULL, MKDEV(Led_MAJOR,0), NULL, DEVICE_NAME);
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main()
{
int fd,i,cmd;
fd=open("/dev/My_led",0);
if (fd<0)
{
printf("open led_driver error");
exit(1);
}
while(1)
{
scanf("%d",&cmd);
switch(cmd)
{
case 0:
printf("All off\n");
for(i = 0;i < 4;i ++)
ioctl(fd,0,i);
break;
case 1:
printf("light first led\n");
ioctl(fd,1,0);
break;
case 2:
printf("light second led\n");
ioctl(fd,0,0);
ioctl(fd,1,1);
break;
case 3:
printf("light third led\n");
ioctl(fd,0,1);
ioctl(fd,1,2);
break;
case 4:
printf("light fourth led\n");
ioctl(fd,0,2);
ioctl(fd,1,3);
break;
case 5:
printf("All light \n");
for(i = 0;i < 4;i ++)
ioctl(fd,1,i);
break;
default:
i = 10;
break;
}
if (i == 10)
break;
}
return 0;
}
这个错误的主要原因很可能是内核的版本不同,不同内核的头文件存放的路径不相同。因此,当编译驱动程序报错“找不到文件”时,检查头文件的路径是否正确
下面是驱动程序的Makefile文件
#LED_makefile KERNELDIR := /home/xg/linux_arm/linux-2.6.30.4/ PWD :=$(shell pwd) all: make -C $(KERNELDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=/opt/opt/EmbedSky/4.3.3/bin/arm-linux- test: /opt/opt/EmbedSky/4.3.3/bin/arm-linux-gcc -o test test.c clean: rm -rf *.o *ko obj-m :=My_led.o当时出的错误就是编译器的路径没有搞清楚。
【Linux驱动】TQ2440 LED驱动程序,布布扣,bubuko.com
标签:des class blog code http tar
原文地址:http://blog.csdn.net/xgsilence/article/details/30123765