TinyS3C6410Linux下LED灯驱动移植过程.docx
《TinyS3C6410Linux下LED灯驱动移植过程.docx》由会员分享,可在线阅读,更多相关《TinyS3C6410Linux下LED灯驱动移植过程.docx(10页珍藏版)》请在冰豆网上搜索。
TinyS3C6410Linux下LED灯驱动移植过程
UT-S3C6410ARM11Linux下的LED驱动
一、实验环境
操作系统:
fedora13
交叉编译环境:
arm-Linux-gcc或以上,
6410板子内核源码路径在:
忘了,需要厂家给的内核源代码
硬件平台:
S3C6410开发板(其他类型的开发板也可以注意配置GPIO)
注:
交叉编译环境一定要装好,一般的开发板给的配套资料中都会有,安装过程也都有详细的过程,如果没有,亲,你只有自己解决了。
也可以联系我(****************),泪奔支持你们。
二、实验原理
控制LED是最简单的一件事情,就像学C语言时候写的“helloworld”程序一样,是一个入门的程序。
首先来了解一下相关的硬件知识:
UT-S3C6410 LED原理图
UT-S3C6410 LED外部引脚图
从上面的原理图可以得知,LED与CPU引脚的连接方法如下,高电平点亮。
LED1 -GPM0
LED2-GPM1
LED3 -GPM2
LED4 -GPM3
从数据手册可以找到相应的控制方法。
这里我们以LED1为例,介绍一下LED1的操作方法,其他的类似,请大家自行分析。
通过上面可以得知,需要先将GPM0设置为输出方式。
将寄存器GPMCON低四位配置成0001。
然后将GPMDAT寄存器的第0位置1灯亮,置LED0灯亮,开发板上有四个LED所以要对GPMDAT的低四位进行操作,就可以实现对灯的亮灭操作了。
三、实验步骤
1、编写驱动程序
mini6410_leds.c
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineDEVICE_NAME"leds"
staticlongsbc2440_leds_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg)
{
switch(cmd){
unsignedtmp;
case0:
case1:
if(arg>4){
return-EINVAL;
}
tmp=readl(S3C64XX_GPKDAT);
tmp&=~(1<<(4+arg));
tmp|=((!
cmd)<<(4+arg));
writel(tmp,S3C64XX_GPKDAT);
//printk(DEVICE_NAME":
%d%d\n",arg,cmd);
return0;
default:
return-EINVAL;
}
}
staticstructfile_operationsdev_fops={
.owner=THIS_MODULE,
.unlocked_ioctl=sbc2440_leds_ioctl,
};
staticstructmiscdevicemisc={
.minor=MISC_DYNAMIC_MINOR,
.name=DEVICE_NAME,
.fops=&dev_fops,
};
staticint__initdev_init(void)
{
intret;
{
unsignedtmp;
tmp=readl(S3C64XX_GPKCON);
tmp=(tmp&~(0xffffU<<16))|(0x1111U<<16);
writel(tmp,S3C64XX_GPKCON);
tmp=readl(S3C64XX_GPKDAT);
tmp|=(0xF<<4);
writel(tmp,S3C64XX_GPKDAT);
}
ret=misc_register(&misc);
printk(DEVICE_NAME"\tinitialized\n");
returnret;
}
staticvoid__exitdev_exit(void)
{
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("FriendlyARMInc.");
(1)把Hello,Module加入内核代码树,并编译
一般编译2.6版本的驱动模块需要把驱动代码加入内核代码树,并做相应的配置,如
下步骤(注意:
实际上以下步骤均已经做好,你只需要打开检查一下直接编译就可以了):
Step1:
编辑配置文件Kconfig,加入驱动选项,使之在makemenuconfig的时候出现
打开linux-2.6.38/drivers/char/Kconfig文件,添加如图所示:
#====================cgfadd=====================================
configMINI6410_LEDS
tristate"LEDSupportforMini6410GPIOLEDs"
dependsonCPU_S3C6410
defaulty
help
ThisoptionenablessupportforLEDsconnectedtoGPIOlines
onMini6410boards.
#==================================================================
保存退出,这时在linux-2.6.38目录位置运行一下makemenuconfig就可以在Device
DriversCharacterdevices菜单中看到刚才所添加的选项了,按下空格键将会选择为,
此意为要把该选项编译为模块方式;再按下空格会变为<*>,意为要把该选项编译到内核中,
在此我们选择,如图,如果没有出现,请检查你是否已经装载了缺省的内核配置文件,
(2)Makefile文件
Step2:
通过上一步,我们虽然可以在配置内核的时候进行选择,但实际上此时执行
编译内核还是不能把mini6410_leds.c编译进去的,还需要在Makefile中把内核配置
选项和真正的源代码联系起来,打开linux-2.6.38-cgf/drivers/char/Makefile,
obj-$(CONFIG_MINI6410_LEDS)+=mini6410_leds.o
添加并保存退出
Step3:
这时回到linux-2.6.38源代码根目录位置,执行makemodules,就可以生成我
们所需要的内核模块文件drivers/char/mini6410_leds.ko了,注意:
执行makemodules之前,必
须先执行makezImage,只需一次就可以了。
至此,我们已经完成了模块驱动的编译。
注意:
在编译过程中会出现
drivers/char/mini6410_leds.c:
31:
30:
fatalerror:
mach/gpio-bank-k.h:
Nosuchfileordirectory
compilationterminated.
则表明自己的内核里缺相关的头文件,只要把光盘里的头文件复制到相关的目录下则可以
一般头文件路径会在arch/arm/mach-s3c64xx/include
cplinux-2.6.38/arch/arm/mach-s3c64xx/include/mach/gpio-bank-k.h/root/mywork/linux-2.6.38-cgf/arch/arm/mach-s3c64xx/include/mach/gpio-bank-k.h
(3)把Module下载到开发板并安装使用
在此使用ftp命令把编译出的mini6410_hello_module.ko下载到板子中,并把它移动
到/lib/modules/2.6.38-FriendlyARM目录然后在板子中现在执行
insmodmini6410_leds.ko
出现如下结果:
ledsinitialized
可以看到该模块已经被装载了(注意:
使用modprobe命令加载模块不需要加“ko”尾
缀)
再执行以下命令,可以看到该模块被卸载
#rmmodmini6410_hello_module
注意:
要能够正常卸载模块,必须把模块放入开发板的
/lib/modules/2.6.38-FriendlyARM目录
2、编写测试程序
光盘中的样例测试程序:
mini6410_leds.c
#include
#include
#include
#include
intmain(intargc,char**argv)
{
inton;
intled_no;
intfd;
/*检查led控制的两个参数,如果没有参数输入则退出。
*/
if(argc!
=3||sscanf(argv[1],"%d",&led_no)!
=1||sscanf(argv[2],"%d",&on)!
=1||
on<0||on>1||led_no<0||led_no>3){
fprintf(stder