|
本帖最后由 天下无伤 于 2013-4-11 19:55 编辑
环境及工具:
linux-2.6.36内核 硬件平台ok6410
测试基本流程:
pc与ok6410通过nfs文件系统成功连接后,编译驱动和app程序即可测试
1://建立nfs文件系统,让板子能和pc机建立通信。
2:#make //编译驱动程序
3:#arm-linux-gcc LED_APP.c -o LED_APP //编译app程序
4:将测试程序拷贝到的是nfs下的文件系统中的/home/yufeng/nfs
5:板子连接好NFS文件系统,并打开PC机下的串口终端, 启动后加载驱动模块
#insmod LED.ko
6:创建设备文件 #mknod /dev/my_led c 240 0
7:测试 ./LED_APP
遇到的问题:
提示ioctl错误,原因是2.6.3以后的内核file_opretione 将ioctl改为了Ulockl_ioctl,
提示KELLOC 错误,原因添加LINUX_TBLS.H
提示arm-linux-gcc 找不到,原因交叉编译环境及超级用户权限问题
以上导致make编译不过,
提示MODULE LICENSE错误,原因是要定义MODULE_LICENSE("GPL" ); ,看了OK6410内核驱动模块是GPL
这里就改为GPL,如果不是,加载时会提示错误。
先粘贴代码
1驱动程序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 <mach/regs-gpio.h>
#include <mach/gpio-bank-m.h>
#include <plat/gpio-cfg.h>
MODULE_LICENSE("GPL" );
#define LED_MAJOR 240
int led_open (struct inode *inode,struct file *filp)
{
unsigned tmp;
tmp = readl(S3C64XX_GPMCON);
tmp = (tmp & ~(0x7U<<1))|(0x1U);
writel(tmp, S3C64XX_GPMCON);
printk("#########open######\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;
printk("#########write######\n");
copy_from_user(wbuf,buf,count);
switch(wbuf[0])
{
case 0: //off
tmp = readl(S3C64XX_GPMDAT);
tmp |= (0x1U);
writel(tmp, S3C64XX_GPMDAT);
break;
case 1: //on
tmp = readl(S3C64XX_GPMDAT);
tmp &= ~(0x1U);
writel(tmp, S3C64XX_GPMDAT);
break;
default :
break;
}
return count;
}
int led_release (struct inode *inode, struct file *filp)
{
printk("#########release######\n");
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);
LED_APP.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;
}
makefile 文件
ifneq ($(KERNELRELEASE),)
obj-m := LED.o
else
KDIR := /home/share/source/linux-3.0.1/
all:
make -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers modul*
endif |
|