基本驱动的概念和开发调试方法
ARMLINUX因为启动了MMU,所以应用程序不能直接读写物理地址(包括CPU寄存器<含GPIO端口、中断等CPU内部资源>、MEMORY、外设芯片内部寄存器等),而必须借助与驱动的形式,切入内核用ioremap来实现对这些物理地址的访问。
下面以一个最常见的GPIO操作为例来说明:
就是选择S3C2410的GPIO_C6口作为一个输出口线,用户通过一个应用程序调用驱动程序来控制这个口线输出1或者0,即高低电平。
例子由两部分构成:“驱动(gpio_driv.c)+应用程序(gpio_test.c)”
LINUX下的驱动有两种形式:
..MODULES形式的可动态加载的驱动(这是LINUX内核一个非常重要
的特点),我们测试用建议都用这种形式的,因为它调试就和普通应用
程序一样,可以通过NFS mount的方式来调试,非常方便。
..静态编译到内核里面的驱动
基本驱动的概念和开发调试方法
样例modules形式驱动的测试用法如下:
NFS mount宿主机后,
insmod gpio_driv.o #在板上嵌入式LINUX内核已经跑起来之后动态加载驱动module
mknod/dev/gpiotest c 220 0
./gpio_test#执行测试用的应用程序来调用驱动,来驱动IO输出高低电平
0:set ,1:clear,2: quit :
用户输入0,则C6口输出3.3V高电平;用户输入1,则C6口输出0低电平。
应用程序如何调用驱动以及驱动要注意的一些细节在下面的详细代码中通过注释
的形式一一说明。
驱动MODULE源代码
#include <linux/fs.h> //FILE: gpio_driv.c
#include <linux/iobuf.h>
#include <linux/major.h>
#include <linux/blkdev.h>
#include <linux/capability.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
#include <asm/arch/cpu_s3c2410.h>
#include <asm/io.h>
#include <linux/vmalloc.h>
#define IOPORT_MAJOR 220 //定义主设备号,和前面的mknod/dev/gpiotestc 220 0匹配
typedefchar ioport_device_t; long port_addr;
static ioport_device_t gpio_devices[257];
int gpio_open(struct inode*, structfile *);
int gpio_release(struct inode*, structfile *);
int gpio_ctl_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
驱动MODULE源代码
..±..ò: static struct file_operations gpio_ctl_fops = {
ioctl: gpio_ctl_ioctl,
open: gpio_o
驱动MODULE源代码
int gpio_open(struct inode*inode, structfile *filp)
{
intminor;
minor = MINOR(inode->i_rdev);
#if 0 //这里是通常的做法,因为S3C2410的LINUX内核提供了set_gpio_ctrl专用函数,所以不要下面
这样做了
(void *)(port_addr) = ioremap(0x56000020,0x8);
*(volatile unsigned int*)(port_addr)|=0x00008000;
#endif
//驱动里面在open这个设备的时候设置这个口为输出(因为GPIO必须设置方向,做输入还是输出)
set_gpio_ctrl(GPIO_MODE_OUT | GPIO_C6);
gpio_devices[minor]++;
return 0;
}
驱动MODULE源代码
int gpio_release(struct inode*inode, structfile *filp)
{ intminor;
minor = MINOR(inode->i_rdev);
if (gpio_devices[minor])
gpio_devices[minor]--;
return 0;
}
int gpio_ctl_ioctl(struct inode*inode,structfile *flip,unsigned intcommand,unsigned long arg)
{
interr = 0;
intminor = MINOR(inode->i_rdev);
switch (command) {
case IOWRITE:
write_gpio_bit(GPIO_MODE_OUT | GPIO_C6,1); //输出3.3V电平
return 0;
case IOCLEAR:
write_gpio_bit(GPIO_MODE_OUT | GPIO_C6,0); //输出0电平
return 0;
}
return err;
}
基本驱动MODULE的Makefile
CC = /opt/host/armv4l/bin/armv4l-unknown-linux-gcc
LD = /opt/host/armv4l/bin/armv4l-unknown-linux-ld
CFLAGS = -D__KERNEL__ -I/HHARM2410-R3/kernel/include/linux-I/HHARM2410-R3/kernel/include -Wall -Wstrict-prototypes -Wno-trigraphs-
Os -mapcs-fno-strict-aliasing-fno-common -fno-common -pipe -mapcs-32
-march=armv4 -mtune=arm9tdmi -mshort-load-bytes -msoft-float
-DKBUILD_BASENAME= gpio_driv
-I/opt/host/armv4l/src/linux/include -DMODULE
gpio_driv.o: gpio_driv.c
$(CC) $(CFLAGS) -c $^ -o $@
cp gpio_driv.o / -f
clean:
-rm-f *.o
注意!驱动程序的Makefile和应用程序的参数不同!
测试驱动的应用程序
#include <stdio.h> //FILE: gpio_test.c
#include <stdlib.h>
#include <sys/ioctl.h> …//省略一些头文件
#include <unistd.h>
#define DEVICE_GPIOTEST "/dev/gpiotest"
intmain()
{
int fd; int val=-1;
if((fd=open(DEVICE_ GPIOTEST,O_RDONLY | O_NONBLOCK))<0)//应用程序就是这样调用驱动的
{ perror("can not open device"); exit(1); }
while(1){
printf("0:set ,1:clear,2: quit :");
scanf("%d",&val);
if(val==0)
ioctl(fd,IOWRITE,0);//应用程序就是这样调用驱动的
else if(val==1)
ioctl(fd,IOCLEAR,0);//应用程序就是这样调用驱动的
else if(val==2){
close(fd); …
}
}
最后可试试烧写FLASH了
完成自己的小驱动和测试用应用程序后,您可以将自己的初步成就烧写到板子里去了
如何加入到板子的文件系统里?
文件系统就是用来存放用户应用程序的集合。
我这里根文件系统采用的是ramdisk。
下面举例说明如何把自己的hello程序烧写到板子上去:
先把ramdisk.image.gz解压后mount -o loop 到一个目录上,这样就可以看到ramdisk里面的文
件及目录内容,这时再把你编译号的hello这个可执行文件复制到这个目录的bin目录下面,再
umount这个目录,再gzip压缩,这样你所作的改动就被带到这个新生成的ramdisk.image.gz文件
里面了,然后你烧写这个文件就可以在板子上看到你的hello了。
简单命令序列:注意要自己调整目录路径,所有操作均在REDHAT LINUX PC机上完成:
gunzip ramdisk.image.gz
mkdir tmnt
mount -o loop ramdisk.image tmnt
cp -f busybox tmnt/bin
umount tmnt
gzip ramdisk.image
cp -f ramdisk.image.gz /tftpboot ;再后面的烧写步骤这里就不再赘述
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
arm9的linux基本驱动的概念和开发调试方法.rar (1个子文件)
基于arm9的linux基本驱动的概念和开发调试方法.txt 5KB
共 1 条
- 1
资源评论
yxlorange
- 粉丝: 2
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功