下面为自己写的ST2410开发板上LED灯的驱动程序和测试代码。
驱动源码GPIO_LED.c
/*2008-06-26*/
/*熊焱春*/
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/hardware.h>
#include <asm/arch/regs-gpio.h>
#include <asm/io.h>//for "__raw_writel()"函数,比较重要
MODULE_******("Dual BSD/GPL");
MODULE_AUTHOR("Xiong Yanchun");
MODULE_DESCRIPTION("LED driver");
#define LED_ON 0
#define LED_OFF 1
int GPIO_LED_major=200;
/***************************************OPEN***************************************/
static int GPIO_LED_open(struct inode *inode,struct file *file)
{
printk("\nIt's in GPIO_LED_open fuction!!!---in the GPIO_LED.ko!!!\n");
//MOD_INC_USE_COUNT;//听说2.6不用了。
//int try_module_get(struct module *module);//调用时模块加1
return 0;
}
/***************************************READ***************************************/
static ssize_t GPIO_LED_read(struct file *filp,char __user *buf,size_t count,loff_t *fops)
{
printk("\nIt's in GPIO_LED_read fuction!!!---in the GPIO_LED.ko!!!\n");
return count;
}
/***************************************WRITE***************************************/
static ssize_t GPIO_LED_write(struct file *filp,const char __user *buf,size_t count,loff_t *fops)
{
printk("\nIt's in GPIO_LED_write fuction!!!---in the GPIO_LED.ko!!!\n");
return count;
}
/***************************************RELEASE***************************************/
static int GPIO_LED_release(struct inode *inode,struct file *file)
{
printk("\nIt's in GPIO_LED_release fuction!!!---in the GPIO_LED.ko!!!\n");
//MOD_DEC_USE_COUNT;//听说2.6不用了。
//void module_put(struct module *module);//
return 0;
}
/***************************************IOCTL***************************************/
static int GPIO_LED_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long date)
{
switch(cmd)
{
case LED_ON:
{
__raw_writel(0x00, S3C2410_GPFDAT); //GPFDAT = 0x00,高四位为LED,为0时点亮LED;
break;
}
case LED_OFF:
{
__raw_writel(0xff, S3C2410_GPFDAT); //GPFDAT = 0xff,高四位为LED,为1时熄灭LED;
break;
}
default:
{
printk("LED control:no cmd run [--kernel--]\n");
return(-EINVAL);
}
}
return 0;
}
struct file_operations GPIO_LED_fops=
{
.read=GPIO_LED_read,
.write=GPIO_LED_write,
.open=GPIO_LED_open,
.release=GPIO_LED_release,
.ioctl=GPIO_LED_ioctl,
};
static int GPIO_LED_init(void)
{
printk("Hello ,it's a GPIO_LED!!!---in the GPIO_LED.ko!!!\n");
__raw_writel(0x5500, S3C2410_GPFCON); //GPFCON = 0x5500;
__raw_writel(0xff, S3C2410_GPFUP); //GPFUP=0xff,高四位为LED,为1关闭上拉电阻;
__raw_writel(0x00, S3C2410_GPFDAT); //GPFDAT = 0x00,高四位为LED,为0时点亮LED;(加载模块时点亮LED)
int ret;
ret=register_chrdev(GPIO_LED_major,"GPIO_LED",&GPIO_LED_fops);//注册设备
if(ret<0)
{
printk("init_module failed with %d---in the GPIO_LED.ko!!!\n",ret);
return ret;
}
else
{
printk("init_module GPIO_LED success!!!---in the GPIO_LED.ko!!!\n");
}
return ret;
}
static void GPIO_LED_exit(void)
{
unregister_chrdev(GPIO_LED_major,"GPIO_LED");
__raw_writel(0xff, S3C2410_GPFDAT);//GPFDAT = 0xff,高四位为LED,为1时熄灭LED;(卸载模块时熄灭LED)
printk("Goodbye,GPIO_LED!!!---in the GPIO_LED.ko!!!\n");
}
module_init(GPIO_LED_init);//内核模块入口,相当于main()函数
module_exit(GPIO_LED_exit);//卸载模块时调用的函数入口
测试代码GPIO_LED_test.c
/*2008-06-27*/
/*熊焱春*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define DEVICE_NAME "/dev/GPIO_LED"
//define LED STATUS
#define LED_ON 0
#define LED_OFF 1
int main(void)
{
int fd,nwrite,nread;
int ret;
int i;
printf("\nstart GPIO_LED_driver test---in the GPIO_LED_test!!!\n\n");
fd=open(DEVICE_NAME,O_RDWR);
if(fd==-1)
{
printf("open device %s error---in the GPIO_LED_test!!!\n",DEVICE_NAME);
}
else
{
//nwrite=write(fd);//调用write函数,没完成。
//nwrite=read(fd);//调用read函数,没完成。
for(i=0;i<5;i++)//循环5次
{
printf("in the ioctl function!,i=%d\nLED_OFF\n",i);
ioctl(fd,LED_OFF);
sleep(1);
printf("LED_ON\n");
ioctl(fd,LED_ON);
sleep(1);
}
ret=close(fd);
printf("ret=%d---in the GPIO_LED_test!!!\n",ret);
printf("close GPIO_LED_driver test---in the GPIO_LED_test!!!\n");
}
return 0;
}
Makefile
# Makefile2.4
ifneq ($(KERNELRELEASE),)
obj-m := GPIO_LED.o
else
PWD := $(shell pwd)
# where the kernel sources are located
//KERNEL_DIR :=/usr/local/src/gec2410-linux-2.6.8.1/
KERNEL_DIR := /yl2410/linux-2.6.8.1-zzm/
all:
#$(MAKE) -C $(KDIR) M=$(PWD)
cd $(KERNEL_DIR); make SUBDIRS=$(PWD) modules
clean:
rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions
endif