linux设备驱动程序jd,Linux设备驱动程序学习(基于2440的GPIO字符设备驱动)
基于2440的GPIO字符設(shè)備驅(qū)動(dòng)及應(yīng)用程序是針對(duì)2440型號(hào)的底板的驅(qū)動(dòng)及測試應(yīng)用程序,詳細(xì)情況請見底板的PCB圖。
S3C2440提供130 路復(fù)用的IO口線,分為如下端口進(jìn)行管理:
— Port A (GPA): 23路輸出口線
— Port B (GPB): 11路輸入/輸出口線
— Port C (GPC): 16路輸入/輸出口線
— Port D (GPD): 16路輸入/輸出口線
— Port E (GPE): 16路輸入/輸出口線
— Port F (GPF): 8路輸入/輸出口線
— Port G (GPG): 16路輸入/輸出口線
Port H (GPH): 11路輸入/輸出口線
Port J (GPJ): 13路輸入/輸出口線
每個(gè)端口可以通過軟件來進(jìn)行配置,從而定義每個(gè)管腳的功能。如果管腳沒有用在復(fù)用功能,可以作為通用IO口進(jìn)行操作。要對(duì)端口進(jìn)行配置,要了解各個(gè)寄存器的作用,每個(gè)寄存器的作用可以參考2440的手冊。
本實(shí)驗(yàn)主要關(guān)注的寄存器有如下三個(gè):
端口配置寄存器(GPACON-GPJCON)
主要功能:配置IO端口的功能,如輸入、輸出和其他復(fù)用功能
端口數(shù)據(jù)寄存器(GPADAT-GPJDAT)
主要功能:保存IO端口的數(shù)據(jù)
端口上拉寄存器(GPAUP-GPJUP)
主要功能:控制IO端口的上拉使能,1-禁止,0-使能(本實(shí)驗(yàn)中禁用就可以了)
本實(shí)驗(yàn)的硬件連接示意圖:
蜂鳴器的實(shí)驗(yàn):GPE-14-----------------------蜂鳴器的控制管腳:0蜂鳴器開;1蜂鳴器關(guān)
GPIO驅(qū)動(dòng)程序如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define RING_MAJOR 224 //mknod /dev/ring c 224 0
#define rGPECON (*(volatile unsigned *)(vaddr+0x40))
#define rGPEDAT (*(volatile unsigned *)(vaddr+0x44))
#define rGPEUP (*(volatile unsigned *)(vaddr+0x48))
#define GPECON_MASK ~(3<<28)
#define GPECON_OUTPUT (1<<28)
#define GPEUP_MASK ~(1<<14)
#define GPEUP_OUTPUT (1<<14)
#define GPEDAT_MASK ~(1<<14)
#define GPEDAT_OUTPUT (1<<14)
#define ring_on() rGPEDAT = rGPEDAT &
GPEDAT_MASK
char *vaddr;
static int ring_open(struct inode *,struct file *);
static int ring_release(struct inode *,struct file *);
static int ring_ioctl(struct inode *,struct file *,unsigned int
,unsigned long);
static struct file_operations ring_ctl_fops = {
owner :
THIS_MODULE,
open :
ring_open,
ioctl :
ring_ioctl,
release :
ring_release,
};
static int ring_open(struct inode *inode,struct file *file)
{
printk("open
ring device...\n");
return
0;
}
static int ring_ioctl(struct inode *inode,struct file
*fiel,unsigned int command,unsigned long arg)
{
printk("ring_ioctl called,with command=%d\n",command);
if(command
==0)
{
while(arg--)
{
printk("...");
ring_on();
}
printk("\n");
}
return
0;
}
static int ring_release(struct inode *inode,struct file
*file)
{
rGPEDAT =
(rGPEDAT & GPEDAT_MASK) | GPEDAT_OUTPUT;
printk("device close!!!\n");
return
0;
}
static int __init ring_init(void)
{
int err =
0;
vaddr =
ioremap(0x56000000,0x100);
rGPECON =
(rGPECON & GPECON_MASK) | GPECON_OUTPUT;
rGPEUP =
(rGPEUP & GPEUP_MASK) | GPEUP_OUTPUT;
printk("ring_init\n");
err =
register_chrdev(RING_MAJOR,"ring",&ring_ctl_fops);
if(err<0)
{
printk("fail
to register\n");
return
-1;
}
printk("success to register\n");
return
0;
}
static int __exit ring_exit(void)
{
printk("release this device!!!\n");
unregister_chrdev(RING_MAJOR,"ring");
return
0;
}
module_init(ring_init);
module_exit(ring_exit);
MODULE_LICENSE("GPL");
Makefile文件:
#ring module example Makefile
ifneq ($(KERNELRELEASE),)
obj-m
:=ring_driver.o
else
KERNELDIR ?=
/home/czd/mike/linux-2.6.28.7
#KERNELDIR=/lib/modules/$(shell uname -r)/build
PWD :=
$(shell pwd)
default:
$(MAKE) -C
$(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o
*~ core .depend .*.cmd *.ko *.mod.c?endifring的測試程序test.c:
#include
#include
#include
#include
#include
#include
#define DEVICE_RINGTEST
"/dev/ring"
int main(int argc ,char *
argv[])
{
int fd;
int val = -1;
fd =?open(DEVICE_RINGTEST,O_RDONLY);
printf("fd:%x\n",fd);
if(fd<0)
{
perror("can
not open device!");
exit(1);
}
while(1)
{
printf("please Select number to run
program\n");
printf("1 :
ring on\n");
printf("2 :
ring off\n");
scanf("%d",&val);
if (val ==
1)
{
ioctl(fd,0,3);
}else if(val
== 2)
{
close(fd);
break;
}
}
return 0;
}
測試程序的Makefile文件:
CC =
/opt/virt.arm/bin/armv4tl-caozhudong-linux-gnueabi-gcc
test:test.o
$(CC) -o $@ $^
test.o:test.c
$(CC) -c -o $@ $<
.PHONY : clean
clean:
rm -rf *.o
編譯、測試驅(qū)動(dòng)程序:
打開超級(jí)終端,命令:minicom
啟動(dòng)系統(tǒng)
以NFS加載網(wǎng)絡(luò)文件系統(tǒng):
vivi-->param set
linux_cmd_line "noinitrd root=/dev/nfs
nfsroot=192.168.0.25:/home/czd/nfs/,proto=tcp,nolock,nfsvers=3
ip=192.168.0.125:192.168.0.25:192.168.0.1:255.255.255.0:bamboo:eth0:off
console=ttySAC0"
vivi>boot
編譯驅(qū)動(dòng)模塊
切換目錄,命令:cd ../ring
/ring_driver 回車
編譯驅(qū)動(dòng)模塊,命令:make clean;
make 回車(生成驅(qū)動(dòng)模塊ring_driver.ko)
編譯測試程序
切換目錄,命令:cd ../ring
/test_ring 回車
編譯測試程序,命令:make clean;
make 回車(生成測試文件test_ring)
加載驅(qū)動(dòng)模塊并執(zhí)行測試程序
建立節(jié)點(diǎn):mknod /dev/ring c 224 0
切換目錄,命令,cd ../ring
/ring_driver 回車
加載驅(qū)動(dòng)模塊,命令,insmod
ring_driver.ko回車
查看模塊, 命令: lsmod 回車
切換目錄,命令:cd ../ring
/test_ring 回車
執(zhí)行測試文件,命令:./test_ring回車
總結(jié)
以上是生活随笔為你收集整理的linux设备驱动程序jd,Linux设备驱动程序学习(基于2440的GPIO字符设备驱动)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux创建多个子进程,[Linux进
- 下一篇: linux下实现作业调度程序,Linux