编译ok6410linux内核,OK6410A学习笔记三:嵌入式Linux驱动之LED驱动

开发环境:

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卡中,给开发板上电

a4c26d1e5885305701be709a3d33442f.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值