设备驱动 - Led

LED驱动程序点击打开链接

led.c

#include <linux/module.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/cdev.h>
#include <linux/fs.h>
#include <linux/io.h>
#include "led.h"

#define	LEDCON 0xE0200060
#define LEDDAT 0xE0200064

#define DEVICE_NAME	"tqled"

volatile unsigned int *led_config;
volatile unsigned int *led_data;

struct cdev cdev;   //描述字符设备
dev_t devno;		//定义主、次设备号
static struct class *led_class;
static long led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	switch(cmd)
	{
		case LED_ON:
			writel(0x00, led_data);
			printk("open Led!\n");
			return 0;
		case LED_OFF:
			writel(0xFF, led_data);
			printk("close Led!\n");
			return 0;
		default:
			return -EINVAL;
	}
}

static int led_open(struct inode *inode, struct file *file)
{
	//初始化控制寄存器
	led_config = (volatile unsigned int *)ioremap(LEDCON, 4);	//物理地址转换为虚拟地址
	writel(0x00011000, led_config);

	led_data = (volatile unsigned int *)ioremap(LEDDAT, 4);
	//writel(0x00000018, led_data);
	
	return 0;
}


static struct file_operations led_fops =
{
	.owner = THIS_MODULE,
	.unlocked_ioctl = led_ioctl,
	.open = led_open,
	.release = NULL,
};

//注册函数
static int __init led_init(void)
{
	int ret = 0;
	cdev_init(&cdev, &led_fops);
	alloc_chrdev_region(&devno, 0, 1, DEVICE_NAME);		//动态分配设备编号
	ret = cdev_add(&cdev, devno, 1);		//向内核注册cdev

	//自动注册驱动至/dev/目录
	led_class = class_create(THIS_MODULE, DEVICE_NAME);
	if(IS_ERR(led_class)){
		printk("Err: failed in led-class.\n");
		return -1;
	}
	device_create(led_class, NULL, devno, NULL, DEVICE_NAME);

	return ret;
}

//注销函数
static void __exit led_exit(void)
{
	cdev_del(&cdev);		//注销cdev
	unregister_chrdev_region(devno, 1);  //释放设备号

	class_destroy(led_class);

	iounmap(led_config);
	iounmap(led_data);
}

module_init(led_init);
module_exit(led_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jerry.Gou");
MODULE_DESCRIPTION("TQ210 led driver");
led.h
#define LED_MAGIC 'L'
#define LED_ON	_IO(LED_MAGIC, 1)
#define LED_OFF _IO(LED_MAGIC, 0)
Makefile
obj-m := led.o
KDIR := /root/code/Kernel_3.0.80_stable

all:
	@make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm

clean:
	@rm -rf *.o *.ko *.order *.symvers *.bak .*.cmd *.mod.o *.mod.c .tmp_versions

cp:
	@make clean
	@make
	cp *.ko /root/code/rootfs/Drive/

测试程序

led_test.c

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>

#define LED_MAGIC 'L'
#define LED_ON	_IO(LED_MAGIC, 0)
#define LED_OFF _IO(LED_MAGIC, 1)


//测试LED的点亮、熄灭功能
int main(int argc, char **argv)
{
	int fd;
	int val;
	fd = open("/dev/tqled", O_RDWR);
	if(fd < 0)
	{
		printf("can't open led!\n");
	}

	if(argc != 2)
	{
		printf("Usage :\n");
		printf("%s <on|off>\n", argv[0]);
		return 0;
	}
	
	val = atoi(argv[1]);  //字符串转化为整数
	if (val == 1)
		ioctl(fd, LED_ON);
	else
		ioctl(fd, LED_OFF);
	return 0;
}
Makefile
objs := led_test.o

test:$(objs)
	@arm-linux-gcc -o test $^

dep_files := $(foreach f,$(objs),.$(f).d)
dep_files := $(wildcard $(dep_files))

ifneq ($(dep_files),)
  include $(dep_files)
endif

%.o : %.c 
	@arm-linux-gcc -Wp,-MD,.$@.d -c -o $@ $<
	
cp:
	cp test /root/code/rootfs/Drive/led_test
clean:
	rm *.o test




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值