一、在同一个文件夹中,写一个驱动模块程序(file.c文件)和一个Makefile
如:驱动模块程序:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-gpio.h>
#include <plat/clock.h>
#include <plat/cpu.h>
#include <plat/regs-timer.h>
#include <linux/device.h>
#define DEVICE_NAME "ledtest"
static struct class *led_class;
static int ledtest_open(struct inode *inode, struct file *file)
{
unsigned int tmp;
tmp = readl(S3C64XX_GPKCON);
tmp =(tmp&~(0xffffU<<4)) | (0x1111U<<4);
//(tmp & ~(0xffffU<<0)) | (0x1111U<<0);
writel(tmp, S3C64XX_GPKCON);
tmp = readl(S3C64XX_GPKDAT);
tmp |= (0x0F << 4);
writel(tmp, S3C64XX_GPKDAT);
return 0;
}
static int ledtest_close(struct inode *inode, struct file *file)
{
unsigned int tmp;
tmp = readl(S3C64XX_GPKCON);
tmp = (tmp & ~(0xffffU<<4)); //input function
writel(tmp, S3C64XX_GPKCON);
return 0;
}
static int ledtest_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
unsigned tmp;
unsigned char num;
num = *(unsigned char *)arg;
//printk (DEVICE_NAME": %d %d\n", num, cmd);
switch(cmd) {
case 0: //on
if (num > 4) {
return -EINVAL;
}
tmp = readl(S3C64XX_GPKDAT);
tmp &= ~(1 << (4 + num));
//tmp |= ( cmd << (0 + num) );
writel(tmp, S3C64XX_GPKDAT);
return 0;
case 1: //off
if (num > 4) {
return -EINVAL;
}
tmp = readl(S3C64XX_GPKDAT);
tmp &= ~(1 << (4+ num));
tmp |= ( cmd << (4 + num) );
writel(tmp, S3C64XX_GPKDAT);
return 0;
default:
return -EINVAL;
}
return 0;
}
static struct file_operations dev_fops = {
.owner = THIS_MODULE,
.open = ledtest_open,
.ioctl = ledtest_ioctl,
.release = ledtest_close,
};
static struct miscdevice misc = {
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init(void)
{
int ret;
ret = misc_register(&misc);
printk ("led driver initialized.\n");
return ret;
}
static void __exit dev_exit(void)
{
misc_deregister(&misc);
}
module_init(dev_init);
module_exit(dev_exit);
MODULE_LICENSE("GPL");
如Makefile:
ifneq ($(KERNELRELEASE),)
obj-m := s3c6410_leds.o
else
PWD := $(shell pwd)
KERNEL_DIR :=/home/ghh/linux-2.6.28.6
all:
cd $(KERNEL_DIR); make SUBDIRS=$(PWD) modules
arm-linux-gcc -o leds_tese leds_test.c
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions *.order *.symvers
endif
二、然后执行make命令(make -C /内核路径/ SUBDIRS=$(pwd) modules),执行该命令后会生成几个文件,其中有一个是.KO文件,这个文件是用来做加载驱动模块用的
三、在同一文件中,写一个应用程序和一个Makefile
如:应用程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/types.h>
#define PATH "/dev/ledtest" //device file
#define LED_ON 0
#define LED_OFF 1
int main(void)
{
int fd, count;
unsigned char num;
unsigned char led_num[4] = {0, 1, 2, 3};
fd = open("/dev/ledtest", 0);
if (fd < 0) {
printf("Failed to open leds driver\n");
exit(1);
}
count = 4;
while(1) {
ioctl(fd, LED_ON, &led_num[count%4]);
ioctl(fd, LED_OFF, &led_num[(count - 1)%4]);
usleep(500000);
count++;
ioctl(fd, LED_ON, &led_num[count%4]);
ioctl(fd, LED_OFF, &led_num[(count - 1)%4]);
usleep(500000);
}
close(fd);
return 0;
}
Makefile:
CROSS_COMPILE = /opt/FriendlyARM/toolschain/4.5.1/bin/arm-linux-
CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
ALL : leds_test
leds_test: leds_test.c
$(CC) -o leds_test leds_test.c
clean :
rm -rf leds_test *~
四、然后执行make命令,就会生成一个可执行文件
五、启动NFS在宿主机上,并把前面生成的.KO文件和可执行文件拷坝到共享目录下
六、打开开发板的终端,然后挂载共享文件目录,而挂载共享文件有两种方式:例如:
1、mount -o nolock 192.168.3.150:/home/share /mnt
2、mount -t nfs -o intr,nolock,wsize=1024,rsize=1024 192.168/3/150:/home/share /mnt
七、挂载成功后,就进入/mnt进行加载.KO文件
#cd /mnt
#insmod file.ko
#lsmod //查看是否加载成功
#lsmod | head -参数 //可查看前面的模块
#dmesg | tail -参数 //查看尾的模块,并显示模块内容
八、在开发板上加载模块成功后,就执行应用程序生成的可执行文件 ,如:
# ./led_test on或off
注:
在执行make 的命令之前,记得要更新环境变量,即
#soure /etc/profile