简单驱动程序

字符设备驱动(点灯)

驱动程序leddrv.c

#include 
	#include 
	#include 
	#include 
	#include 
	#include 
	#include 
	#include 
	#include 
	#include 
	#include 
	#define S3C2440_GPA(n)  (0<<16 | n)
	#define S3C2440_GPB(n)  (1<<16 | n)
	#define S3C2440_GPC(n)  (2<<16 | n)
	#define S3C2440_GPD(n)  (3<<16 | n)
	#define S3C2440_GPE(n)  (4<<16 | n)
	#define S3C2440_GPF(n)  (5<<16 | n)
	#define S3C2440_GPG(n)  (6<<16 | n)
	#define S3C2440_GPH(n)  (7<<16 | n)
	#define S3C2440_GPI(n)  (8<<16 | n)
	#define S3C2440_GPJ(n)  (9<<16 | n)
	static int led_pin = S3C2440_GPF(5);
	static int major;
	static struct class *led_class;
	static volatile unsigned int *gpio_con;
	static volatile unsigned int *gpio_dat;
	static unsigned int gpio_base[] = {
		0x56000000, // GPACON寄存处地址
		0x56000010, // GPBCON寄存处地址
		0x56000020, // GPCCON寄存处地址
		0x56000030, // GPDCON寄存处地址
		0x56000040, // GPECON寄存处地址
		0x56000050, // GPFCON寄存处地址
		0x56000060, // GPGCON寄存处地址
		0x56000070, // GPHCON寄存处地址
		0x56000080, // GPICON寄存处地址
		0x56000090, // GPJCON寄存处地址
	};
	//1.分配
	static struct file_operations myled_oprs = {
		.owner = THIS_MODULE, //模块本身
		.open = led_open,
		.write = led_write,
		.release = led_close,
	}
	//2.设置
	static int led_open(struct inode * node, struct file * filp){
		//不能直接操作物理地址,需要映射。举例GPF5
		int bank = led_pin >> 16;
		int base = gpio_base(bank);
		int pin = led_pin & 0xffff;
		gpio_con = ioremap(base, 8);//8为映射的大小,一般为一页。
		gpio_dat = gpio_con + 1;//指针加4
		*gpio_con &= ~(3<<(pin * 2));//bit10、11清零操作
		*gpio_con |= ~(1<<(pin * 2));//bit10、11置1,设置为输出。
		return 0;
	}
	static ssize_t led_write(struct file *filp, const char __user *buf, size_t size, loff_t *off){
		//根据应用传入的值来设置LED引脚
		unsigned char val;
		int pin = led_pin & 0xffff;
		copy_from_user(&val, buf, 1);
		if(val){
		//点灯
			*gpio_dat &= ~(1<

测试程序ledtest.c

#include 
	#include 
	#include 
	#include 
	
	int main(int argc, char **argv){
		int fd;
		int val = 1;
		fd = open("dev/led", O_RDWR);
		if(fd < 0){
			printf("Can't open!\n");
		}
		if(argc != 2){
			printf("Usage : \n");
			printf(" %s \n", argv[0]);
			return 0;
		}
		if(strcmp(argv[1], "on") == 0){
			val = 1;
		}else{
			val = 0;
		}
	}

使用方法:

       将leddrv.c放入内核目录,然后编译内核。

       交叉编译ledtest.c,将编译好的ledtest应用程序放到板端执行。

你可能感兴趣的:(Linux)