UT-S3C6410 RAM11 Linux下LED灯驱动
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
UT-S3C6410 ARM11 Linux 下的LED驱动
在李人东老师的要求下,让我把基于Linux下ARM的初级驱动开发流程在这里演示一遍,为了不枉费李人东老师的一片心血,和对ARM还没有入门苦苦探索的亲们,给你们开启一扇窗户,少走一些弯路,废话少说,现在开始:
一、实验环境
操作系统:ubuntu 9.0 或以上
交叉编译环境:arm-Linux-gcc 4.2.2或以上,安装在/usr/local/arm/4.2.2/
6410板子内核源码路径在:/s3c6410/linux-2.6.28-v1.0/
硬件平台:UT-S3C6410开发板(其他类型的开发板也可以注意配置GPIO)
注:交叉编译环境一定要装好,一般的开发板给的配套资料中都会有,安装过程也都有详细的过程,如果没有,亲,你只有自己解决了。
也可以联系我(476695721@),泪奔支持你们。
二、实验原理
控制LED是最简单的一件事情,就像学C语言时候写的“hello world”程序一样,是一个入门的程序。
首先来了解一下相关的硬件知识:
UT-S3C6410LED原理图
UT-S3C6410LED外部引脚图
从上面的原理图可以得知,LED与CPU引脚的连接方法如下,高电平点亮。
LED1 -GPM0
LED2 -GPM1
LED3 -GPM2
LED4 -GPM3
从数据手册可以找到相应的控制方法。
这里我们以LED1为例,介绍一下LED1的操作方法,其他的类似,请大家自行分析。
通过上面可以得知,需要先将GPM0设置为输出方式。
将寄存器GPMCON低四位配置成0001。
然后将GPMDAT寄存器的第0位置1灯亮,置LED0灯亮,开发板上有四个LED所以要对GPMDAT的低四位进行操作,就可以实现对灯的亮灭操作了。
三、实验步骤
1、编写驱动程序
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 <plat/regs-gpio.h>
#include <plat/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 = (tmp & ~(0xffffU))|(0x1111U);
writel(tmp, S3C64XX_GPMCON);
printk("#########open GPMCON######\n");
return 0;
}
ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)
{
printk("#########read######\n");
return count;
}
ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos) {
char wbuf[10];
unsigned tmp;
copy_from_user(wbuf,buf,count);
switch(wbuf[0])
{
case 0: //on
tmp = readl(S3C64XX_GPMDAT);
tmp |= (0xfU);
writel(tmp, S3C64XX_GPMDAT);
break;
case 1: //off
tmp = readl(S3C64XX_GPMDAT);
tmp &= ~(0xfU);
writel(tmp, S3C64XX_GPMDAT);
break;
default :
break;
}
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 ("Test led dev\n");
rc = register_chrdev(LED_MAJOR,"led",&led_fops);
if (rc <0)
{
printk ("register %s char dev error\n","led");
return -1;
}
printk ("ok!\n");
return 0;
}
void __exit led_exit (void)
{
unregister_chrdev(LED_MAJOR,"led");
printk ("module exit\n");
return ;
}
module_init(led_init);
module_exit(led_exit);
Makefile文件
Makefile
obj-m:=driver_led.o
KDIR:=/s3c6410/urbetter-linux2.6.28-v1.0
all:
make -C $(KDIR) M=$(shell pwd) modules cp driver_led.ko /home/fusq/nfs_share clean:
make -C $(KDIR) M=$(shell pwd) clean
2、编写测试程序
test.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main (void)
{
int fd;
char buf[10]={0,1};
fd = open("/dev/my_led",O_RDWR);
if (fd < 0)
{
printf ("Open /dev/my_led file error\n");
return -1;
}
while(1)
{
write(fd,&buf[0],1);
sleep(1);
write(fd,&buf[1],1);
sleep(1);
}
close (fd);
return 0;
}
3、编译驱动程序与测试程序
3.1编译驱动程序
#make
编译成驱动文件driver_led.ko并自动拷贝到了/home/fusq/nfs_share
注:要注意Makefile要符合Linux下的文本格式,如果出现不执行,请在Linux下vi或vim 重新编辑一下。
如果出现头文件找不到,请找到该头文件的具体位置一般都在
(urbetter-linux2.6.28-v1.0)文件夹下,将该头文件最后路径的文件夹名字填到程序头文件调用中。
3.2编译测试程序
#arm-linux-gcc test.c -o test
将测试程序也放到/home/fusq/nfs_share共享文件夹下
#cp test /home/fusq/nfs_share
4、将程序下载到开发板
将开发板的IP地址修改,与主机在同一个网段,并修改PC机上Linux下/etc/exports 网络配置文件的IP与开发板的一致。
确保PC机上Linux已经安装了NFS服务器,网络共享文件夹在/home/fusq/nfs_share。
在开发板的Linux下挂载nfs网络共享文件夹:
[root@urbetter /]# mount -t nfs -o nolock 192.168.1.80:/home/fusq/nfs_share /mnt/nfs
挂载到/mnt/nfs下。
注:如果没有安装NFS服务器,为了完成实验,可以用串口将或是USB等设备将
driver_led.ko和test文件拷贝到开发板的Linux工作目录下效果是一样的。
5、测试
5.1加载驱动#insmod /mnt/nfs/driver_led.ko
网络有点小不稳定,亲们要耐心等待,不过还是成功了!
5.2 创建设备文件#mknod /dev/my_led c 240 0
5.3测试 ./test
[root@urbetter /]# ./test
注:此时可以看到UT-S3C6410板子上的LED0-3在闪烁,如果出现执行权限不过,修改一下test的用户执行权限如上图:
#chmod 777 test
5.4卸载驱动#rmmod driver_led
从上面的结果我们可以看到,当用户调用相应的文件操作函数时,驱动程序中的相应的函数也会被调用。
大家可以修改相应程序,测试一下其他的情况,如有什么错误也可以一起探讨,今生为嵌入式事业奋斗终身,谢谢!
邮箱:476695721@
sunxue0802@。