原文:
http://www.cnblogs.com/hebaichuanyeah/
驱动IO口点亮一个LED。。基本上就是嵌入式领域的“helloworld”。
初识6410,裸机调试IO口。
http://www.cnblogs.com/hebaichuanyeah/p/3276735.html
linux环境下驱动包括三类:字符设备驱动,块设备驱动,网络设备驱动。
linux的驱动程序,可以编写成模块,加载到内核中。
linux的操作设备,是以文件的形式。
简单的IO口驱动,driver_led.c文件:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/uaccess.h> /* copy_to_user,copy_from_user */
#include <linux/miscdevice.h>
#include <linux/pci.h>
#include <mach/map.h>
#include <mach/regs-gpio.h>
#include <mach/gpio-bank-m.h>
#include <plat/gpio-cfg.h>
#define LED_MAJOR 240
int led_open (struct inode *inode,struct file *filp)
{
unsigned tmp;
tmp = readl(S3C64XX_GPMCON);
tmp &= 0xffff0000;
tmp |= 0x00001111;
writel(tmp, S3C64XX_GPMCON);
writel(0xffffffff, S3C64XX_GPMDAT);
printk("open led
");
return 0;
}
ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)
{
return count;
}
ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
{
char wbuf[1];
unsigned tmp;
copy_from_user(wbuf,buf,count);
tmp = readl(S3C64XX_GPMDAT);
tmp &= 0xfffffff0;
tmp |= wbuf[0];
writel(tmp, S3C64XX_GPMDAT);
//writel(0x02,S3C64XX_GPMDAT);
return count;
}
int led_release (struct inode *inode, struct file *filp)
{
return 0;
}
struct file_operations led_fops ={
.owner = THIS_MODULE,
.open = led_open,
.read = led_read,
.write = led_write,
.release = led_release,
};
int __init led_init (void)
{ int rc;
printk ("led init
");
rc = register_chrdev(LED_MAJOR,"led",&led_fops);
if (rc <0)
{
printk ("register %s char dev error
","led");
return -1;
}
printk ("success
");
return 0;
}
void __exit led_exit (void)
{
unregister_chrdev(LED_MAJOR,"led");
printk ("module exit
");
return ;
}
module_init(led_init);
module_exit(led_exit);
编写makefile文件
all: install cp clean
obj-m := driver_led.o
KDIR := /forlinux/linux-3.0.1/
install:
make -C $(KDIR) M=$(shell pwd) modules
cp:
cp driver_led.ko /mnt/share/
clean:
make -C $(KDIR) M=$(shell pwd) clean
编译生成的driver_led文件复制到 /mnt目录下(共享)。
led_test.c 简单的流水灯测试程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main (void)
{
int fd;
char buf[4]={~0x01,~0x02,~0x04,~0x08};
fd = open("/dev/my_led",O_RDWR);
if (fd < 0)
{
printf ("Open /dev/my_led file error
");
return -1;
}
while(1)
{
write(fd,&buf[0],1);
sleep(1);
write(fd,&buf[1],1);
sleep(1);
write(fd,&buf[2],1);
sleep(1);
write(fd,&buf[3],1);
sleep(1);
}
return 0;
}
编译后,生成文件复制到目标机。
运行命令:
加载驱动模块
insmod driver_led.ko
建立驱动文件
mknod /dev/my_led c 240 0
运行调试程序
./led_test
LED流水灯。