OK6410A学习笔记三:嵌入式Linux驱动之LED驱动
时间:11-21
来源:互联网
点击:
开发环境:
Windows7 + vmware workstation 6.5 + Ubuntu9.10
Linux Source Code: FORLINX_linux-3.0.1.tar.gz
ARM CROSS GCC: arm-linux-gcc v4.3.2
源码:
//s3c6410_led.c – driver file
#include
#include
#include
#include
#include
#define DEV_MAJOR 176
#define DEV_NAME "s3c6410_leds"
#define GPMCON 0x7F008820
#define GPMDAT 0x7F008824
#define GPMPUD 0x7F008828
volatile unsigned long *gpmcon = NULL;
volatile unsigned long *gpmdat = NULL;
volatile unsigned long *gpmpud = NULL;
static int s3c6410_led_open(struct inode *inode, struct file *filp)
{
//int ret;
printk(KERN_ALERT "This is open function of s3c6410 led driver.\n");
*gpmpud &= 0xffffffaa; //set GPM0~3 as pull up enabled
*gpmcon &= 0xffff1111; //set GPM0~3 as output
*gpmdat &= 0xfffffff0; //set GPM0~3 to low level, which turn on leds
return 0;
}
static ssize_t s3c6410_led_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos)
{
int val;
//copy_from_user(&val,buf,count);
printk(KERN_ALERT "This is write function of s3c6410 led driver.\n");
return count;
}
struct file_operations s3c6410_led_flops = {
.owner = THIS_MODULE,
.open = s3c6410_led_open,
.write = s3c6410_led_write,
};
static int __init s3c6410_led_init(void)
{
int ret;
//register led device driver into kernel
ret = register_chrdev(DEV_MAJOR,DEV_NAME,&s3c6410_led_flops);
//retriver the vritual address by ioremap
gpmcon = (volatile unsigned long *)ioremap(GPMCON,4); //32-bit reg
gpmdat = gpmcon + 1;
gpmpud = gpmcon + 2;
return 0;
}
static void __exit s3c6410_led_exit(void)
{
//unregister led device dirver from kernel
unregister_chrdev(DEV_MAJOR,DEV_NAME);
//iounmap
iounmap(gpmcon);
}
module_init(s3c6410_led_init);
module_exit(s3c6410_led_exit);
MODULE_DESCRIPTION("This is led driver sample for OK6410A board.");
MODULE_VERSION("1.0");
MODULE_AUTHOR("");
MODULE_LICENSE("Dual BSD/GPL");
//s3c6410_led_test.c – test file
#include
#include
int main(int argc,char* argv[])
{
int fd;
fd = open("/dev/s3c6410_led",0);
if(!fd){
printf("open s3c6410 led failed.\n");
}else{
printf("open s3c6410 led succeed.\n");
}
return 0;
}
解析:
1. 查看OK6410A开发板原理图,4个LED灯接在GPM0~3四个GPIO上。
2. 查看Samsung S3C6410X User’s Manual.pdf ,查看GPm端口操作说明,包括GPMCON,GPMDAT,GPMPUD三个寄存器的基地址以及配置信息,从而确定点亮LED灯和熄灭LED灯的操作。
3. 编写源代码,包括驱动源码和测试源码。这里比较重要的地方是,Linux驱动是工作在保护模式下,无法直接操作寄存器,因此必须将步骤二中找到的寄存器基地址通过IO地址重映射,从而得到虚拟地址进行操作,在驱动程序入口函数中使用ioremap()函数进行地址重映射,在退出函数中使用iounmap()结束地址重映射。另外,如果想在加载驱动的同时,让系统自动新建设备节点,则要将设备信息提供给系统内核,Linux系统支持的mdev机制会根据驱动程序提供的信息新建设备节点。在上述源码中并没有实现这一功能。
4. 编译源码
驱动程序Makefile如下:
obj-m:=s3c6410_led.o
KERNELDIR?=/usr/src/linux-3.0.1
default:
$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules
clean:
rm -rf *.o *~ *.ko *.mod.c *.order *.symvers
在终端下执行如下命令:
#make //编译驱动程序,得到s3c6410_led.ko文件
#arm-linux-gcc s3c6410_led_test.c –o s3c6410_led_test //编译测试源码
5. 拷贝s3c6410_led.ko和s3c6410_led_test到SD卡中,给开发板上电
Windows7 + vmware workstation 6.5 + Ubuntu9.10
Linux Source Code: FORLINX_linux-3.0.1.tar.gz
ARM CROSS GCC: arm-linux-gcc v4.3.2
源码:
//s3c6410_led.c – driver file
#include
#include
#include
#include
#include
#define DEV_MAJOR 176
#define DEV_NAME "s3c6410_leds"
#define GPMCON 0x7F008820
#define GPMDAT 0x7F008824
#define GPMPUD 0x7F008828
volatile unsigned long *gpmcon = NULL;
volatile unsigned long *gpmdat = NULL;
volatile unsigned long *gpmpud = NULL;
static int s3c6410_led_open(struct inode *inode, struct file *filp)
{
}
static ssize_t s3c6410_led_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos)
{
}
struct file_operations s3c6410_led_flops = {
};
static int __init s3c6410_led_init(void)
{
}
static void __exit s3c6410_led_exit(void)
{
}
module_init(s3c6410_led_init);
module_exit(s3c6410_led_exit);
MODULE_DESCRIPTION("This is led driver sample for OK6410A board.");
MODULE_VERSION("1.0");
MODULE_AUTHOR("");
MODULE_LICENSE("Dual BSD/GPL");
//s3c6410_led_test.c – test file
#include
#include
int main(int argc,char* argv[])
{
}
解析:
1.
2.
3.
4.
驱动程序Makefile如下:
obj-m:=s3c6410_led.o
KERNELDIR?=/usr/src/linux-3.0.1
default:
$(MAKE) -C $(KERNELDIR) M=$(shell pwd) modules
clean:
rm -rf *.o *~ *.ko *.mod.c *.order *.symvers
在终端下执行如下命令:
#make //编译驱动程序,得到s3c6410_led.ko文件
#arm-linux-gcc s3c6410_led_test.c –o s3c6410_led_test //编译测试源码
5.
OK6410ALinux驱动LED驱 相关文章:
- OK6410A学习笔记四:嵌入式Linux驱动之LED驱动进阶(11-21)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)