1.led驱动程序led.c如下
-
//moudle.h 包含了大量加载模块需要的函数和符号的定义
-
#include <linux/module.h>
-
//kernel.h以便使用printk()等函数
-
#include <linux/kernel.h>
-
//fs.h包含常用的数据结构,如struct file等
-
#include <linux/fs.h>
-
//uaccess.h 包含copy_to_user(),copy_from_user()等函数
-
#include <linux/uaccess.h>
-
//io.h 包含inl(),outl(),readl(),writel()等IO口操作函数
-
#include <linux/io.h>
-
#include <linux/miscdevice.h>
-
#include <linux/pci.h>
-
//init.h来指定你的初始化和清理函数,例如:module_init(init_function)、module_exit(cleanup_function)
-
#include <linux/init.h>
-
#include <linux/delay.h>
-
#include <linux/device.h>
-
#include <linux/cdev.h>
-
#include <linux/gpio.h>
-
#include <linux/irq.h>
-
#include <linux/sched.h>
-
#include <linux/interrupt.h>
-
#include <linux/poll.h>
-
//irq.h中断与并发请求事件
-
#include <asm/irq.h>
-
//下面这些头文件是IO口在内核的虚拟映射地址,涉及IO口的操作所必须包含
-
//#include <mach/gpio.h>
-
#include <mach/regs-gpio.h>
-
#include <plat/gpio-cfg.h>
-
#include <mach/hardware.h>
-
#include <mach/map.h>
-
-
-
static struct class *led_class;
-
static int major;
-
-
volatile unsigned long *gpmcon = NULL;
-
-
volatile unsigned long *gpmdat = NULL;
-
-
static int led_open(struct inode *inode, struct file *file)
-
{
-
/*把LED的GPIO口设置为输出*/
-
/* 配置GPM的0,1,2,3为输出 */
-
*gpmcon &= ~((0xE<<(0*4)) | (0xE<<(1*4)) | (0xE<<(2*4)) | (0xE<<(3*4)));
-
return 0;
-
}
-
-
static ssize_t led_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
-
{
-
int val;
-
-
if( copy_from_user(&val, buf, count) )//从用户(测试程序中)获得val的值,同时判断copy_from_user函数的返回值,如果不为0,说明出错
-
{
-
printk("error in function ‘copy_from_user’ !\n");
-
return -EFAULT;
-
}
-
-
if(val == 1)
-
{
-
// 点灯
-
-
*gpmdat &= ~((1<<0) | (1<<1) | (1<<2) | (1<<3));
-
-
printk("my led open\n");
-
}
-
else
-
{
-
// 灭灯
-
-
*gpmdat |= ((1<<0) | (1<<1) | (1<<2) | (1<<3));
-
-
printk("my led close\n");
-
}
-
-
return 0;
-
}
-
-
static struct file_operations led_fops = {
-
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
-
.open = led_open,
-
.write = led_write,
-
};
-
-
static int led_init(void)
-
{
-
major = register_chrdev(0, "led_dev", &led_fops);//注册,告诉内核
-
led_class = class_create(THIS_MODULE, "led_cls");
-
device_create(led_class, NULL, MKDEV(major, 0), NULL, "led");/* /dev/led */
-
-
gpmcon = (volatile unsigned long *)ioremap(0x7F008820, 16);//印射虚拟地址
-
-
gpmdat = gpmcon + 1;
-
return 0;
-
}
-
-
static void led_exit(void)
-
{
-
unregister_chrdev(major, "led_cls");
-
device_destroy(led_class, MKDEV(major, 0));
-
class_destroy(led_class);
-
iounmap(gpmcon);
-
}
-
-
module_init(led_init);
-
module_exit(led_exit);
-
-
MODULE_LICENSE("GPL");
2.led测试程序led_test.c代码如下
-
#include <sys/types.h>
-
#include <sys/stat.h>
-
#include <fcntl.h>
-
#include <stdio.h>
-
-
-
int main(int argc, char **argv)
-
{
-
int fd;
-
int val = 1;
-
-
/*打开/dev/led设备*/
-
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;
-
}
-
-
/*比较第二个参数,若为on,val的值设为1,否则为0*/
-
if (strcmp(argv[1], "on") == 0)
-
-
{
-
-
val = 1;
-
-
}
-
-
else
-
-
{
-
-
val = 0;
-
-
}
-
-
write(fd, &val, 4);//写val的数值,然后驱动程序利用copy_from_user函数取得val的值
-
return 0;
-
}
阅读(824) | 评论(0) | 转发(0) |