测试在目标机上动态加载驱动。(驱动控制GPIO4~7)
程序分为app.c , drv.c
drv.c:
-----------------
drv.c需要COPY到内核的/driver/char下,并配置内核支持字符驱动。编译内核,
drv.c对GPIO进行初始化,注册主设备号,通过对GPFDAT进行移位操作,控制LED亮、灭。
cp /driver/char/drv.ko 到目标机,在目标机上动态加载驱动,insmod drv.ko
在目标机上创建节点 mknod -m 666 /dev/GPIO c 252 0
-----------------
//#define MODULE
//#define __KERNEL__
#ifdef MODULE
#include <linux/module.h>
#include <linux/version.h>
#else
#define MOD_INC_USE_COUNT
#define MOD_DEC_USE_COUNT
#endif
//#define __KERNEL__
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/slab.h>
#include <linux/ioport.h>
#include <asm/uaccess.h>
#include <asm/io.h>
//#include <asm/arch/S3C2410.h>
#include <asm/arch-s3c2410/regs-gpio.h>
#include <linux/fcntl.h>
#define GPF4_ON 0x4800
#define GPF5_ON 0x4802
#define GPF6_ON 0x4803
#define GPF7_ON 0x4804
#define GPF4_OFF 0x4801
#define GPFDAT *(volatile unsigned int *)S3C2410_GPFDAT
#define GPFCON *(volatile unsigned int *)S3C2410_GPFCON
//static int GPIO_TEST_ioctl(struct inode *s_node,struct file *s_file,unsigned int cmd,unsigned int arg);
static int major=252;
char GPIO_TEST_name[]="GPIO_TEST";
static int GPIO_TEST_ioctl(struct inode *s_node,struct file *s_file,unsigned int cmd,unsigned long arg)
{
int retv;
unsigned int data;
switch(cmd)
{
case GPF4_ON:
GPFDAT=GPFDAT|(1<<7);
GPFDAT=GPFDAT&(~(1<<4));break;
//s3c2410_gpio_setpin(S3C2410_GPF4,0);
case GPF5_ON:
GPFDAT=GPFDAT|(1<<4);
GPFDAT=GPFDAT&(~(1<<5)); break;
case GPF6_ON:
GPFDAT=GPFDAT|(1<<5);
GPFDAT=GPFDAT&(~(1<<6)); break;
case GPF7_ON:
GPFDAT=GPFDAT|(1<<6);
GPFDAT=GPFDAT&(~(1<<7));
break;
// case GPF4_OFF:
//GPFDAT=GPFDAT|(1<<4);
//s3c2410_gpio_setpin(S3C2410_GPF4,1);
//break;
default:
break;
}
return 0;
}
static struct file_operations GPIO_TEST_fops=
{
ioctl : GPIO_TEST_ioctl
};
static int __init GPIO_TESTdrv_init_module(void)
{
int retv;
retv=register_chrdev(major,GPIO_TEST_name,&GPIO_TEST_fops);
if(retv<0)
{
printk("<1>register fail!/n");
return retv;
}
if(major==0)
major=retv;
printk("major=%d/n",major);
printk("<1>GPIO_TESTdrv!!!!!!!!!!!!!!!!!!!!!!!!!/n");
GPFDAT=(GPFDAT&(~(3<<8)))+(1<<8);
GPFDAT=GPFDAT|(1<<4);
//s3c2410_gpio_pullup(S3C2410_GPF4,1);
//s3c2410_gpio_cfgpin(S3C2410_GPF4, S3C2410_GPF4_OUTP);
//s3c2410_gpio_setpin(S3C2410_GPF4,1);
return 0;
}
static void __exit GPIO_TESTdrv_cleanup(void)
{
int retv;
retv=unregister_chrdev(major,GPIO_TEST_name);
if(retv<0)
{
printk("<1>unreginster fail!/n");
return;
}
printk("<1>GPIO_TESTdrv:good_bye!/n");
}
module_init(GPIO_TESTdrv_init_module);
module_exit(GPIO_TESTdrv_cleanup);
//lhtMODULE_LICENSE("GPL");
=======
app.c:
-----------
在主机上对app.c交叉编译,生成的可执行文件放到目标板的文件系统下
app.c实现打开设备节点,通过ioctl给设备节点发信号,并且延时,实现流水灯
启动目标机后,动态加载驱动,执行app即可实现流水灯。
-----------
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sys/ioctl.h>
#define GPF4_ON 0x4800
#define GPF5_ON 0x4802
#define GPF6_ON 0x4803
#define GPF7_ON 0x4804
#define GPF4_OFF 0x4801
int main(void)
{
int fd;
int *arginfo=(int *)malloc(4);
printf("entered main/n");
if((fd=open("/dev/GPIO_TEST",O_RDWR))==-1)
{
perror("open eror");
exit(1);
}
printf("open ok/n");
while(1)
{
// ioctl(fd,GPF4_OFF,arginfo); //GPF0 1
// sleep(1);
ioctl(fd,GPF4_ON,arginfo); //GPF0 0
sleep(1);
ioctl(fd,GPF5_ON,arginfo);
sleep(1);
ioctl(fd,GPF6_ON,arginfo);
sleep(1);
ioctl(fd,GPF7_ON,arginfo);
sleep(1);
}
close(fd);
return 0;
}
#(粗体部分修改)为新增代码,原程序实现单LED闪烁