fl2440的字符驱动,LED驱动实验

  • 格式:doc
  • 大小:36.50 KB
  • 文档页数:4

FL2440的字符驱动,LED驱动实验(详细步骤)

LED灯只有两种状态,亮与不亮。查看用户手册可以知道,当GPIO被赋予低电平的时候,LED灯被点亮,否则将处于熄灭的状态,因此,只要设置好管脚高低电平两个状态就可以完成驱动程序连接底层硬件和应用程序的功能了。该程序是我在飞凌实验手册基础上改了一点,大家有空把这些程序和实验手册上的程序对比一下,会学到很多的!源码s3c2440_leds.c 如下 :(以下程序只适用飞凌2440,内核为2.6.28.7!内核为2.6.12的驱动程序在飞凌的linux实验手册有,这我不多说了!)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define DEVICE_NAME "leds"

#define LED_MAJOR 231

static unsigned long led_table [] = {

S3C2410_GPB5,

S3C2410_GPB6,

S3C2410_GPB8,

S3C2410_GPB10,

};

static unsigned int led_cfg_table [] = {

S3C2410_GPB5_OUTP, //0x01<<10 defined in refg-gpio.h

S3C2410_GPB6_OUTP,

S3C2410_GPB8_OUTP,

S3C2410_GPB10_OUTP,

};

static int s3c2440_leds_ioctl(

struct inode *inode,

struct file *file,

unsigned int cmd, unsigned long arg)

{

switch(cmd) {

case 0:

case 1:

if (arg > 4) {

return -EINVAL;

}

s3c2410_gpio_setpin(led_table[arg], !cmd);

return 0;

default:

return -EINVAL;

}

}

static struct file_operations s3c2440_leds_fops = {

.owner = THIS_MODULE,

.ioctl = s3c2440_leds_ioctl,

};

static int __init s3c2440_leds_init(void)

{

int ret;

int i;

ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &s3c2440_leds_fops);

if (ret < 0) {

printk(DEVICE_NAME " can't register major number\n");

return ret;

}

//devfs_mk_cdev(MKDEV(LED_MAJOR, 0), S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,

DEVICE_NAME);

for (i = 0; i < 4 ; i++) {

s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);

s3c2410_gpio_setpin(led_table[i], 1);

}

printk(DEVICE_NAME " initialized\n");

return 0;

}

static void __exit s3c2440_leds_exit(void) {

//devfs_remove(DEVICE_NAME);

unregister_chrdev(LED_MAJOR, DEVICE_NAME);

}

module_init(s3c2440_leds_init);

module_exit(s3c2440_leds_exit);

编写一个Makefile 文件。提醒一下小白们,(大虾别笑,我也是小白,我刚开始也不知道什么是vi,请体谅我们这些小白。)在linux同s3c2440_ledsc目录下#vi Makefile 就可以编写了其内容如下 :(注意空格喔,不然就冬瓜豆腐咯)

#Makefile for s3c2440_leds.c

obj-m :=s3c2440_leds.o

KERNELDIR ?= /linux-2.6.28.7

PWD := $(shell pwd)

default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

把驱动程序和Makefile 放同一目录,在终端进行#make,如果不出问题,将会产生一些中间文件,但是,只有.ko文件才是我们想要的,你知道,那是我们在超级终端的主角。make以后在终端输入#file mini2440_leds.ko,就可以看见驱动模块的详细信息啦。

[root@winux 7-led-qd]# file s3c2440_leds.ko

s3c2440_leds.ko: ELF 32-bit LSB relocatable, ARM, version 1, not strippe

如果make的时候出现下面两个或者一个问题:

include/linux/mmzone.h:18:26: error: linux/bounds.h: No such file or directory

include/linux/mmzone.h:197:5: warning: "MAX_NR_ZONES" is not defined

就在内核的根目录下(/linux2.6.28.7/)#make prepare 一下,然后再回到s3c2440_leds.c的目录里再make一下!OK!

到这里,你就可以把.ko文件送到板子的超级终端上直接insmod s3c440_leds(加载驱动)和(不要加载别的驱动,这个可以忽略rmmod(卸载驱动)),你在超级终端下:

# insmod s3c2440_leds.ko(加载驱动)

s3c2440_leds: module license 'unspecified' taints kernel.

leds initialized

# lsmod(查看驱动)

Module Size Used by Tainted: P

s3c2440_leds 1792 0

然后建立设备接点:mknod /dev/leds c 231 0

这样就完事啦!别怪我唠叨啊,(*^__^*) 嘻嘻!

最后弄个led程序到开发板验证一下,先建一个ledshow.c文件:

#include "sys/ioctl.h"

#include "stdlib.h"

#include "termios.h"

#include "sys/stat.h" #include "fcntl.h"

#include "sys/time.h"

int main(void)

{

int on=1;

int led;

int fd;

fd=open("/dev/leds",0);

if(fd<0)

{

perror("open device leds");

exit(1);

}

printf("leds test show,press ctrl+c to exit \n");

while(1)

{

for(led=0;led<4;led++)

{

ioctl(fd,on,led);

usleep(50000);

}

on=!on;

}

close(fd);

return 0;

然后#arm-linux-gcc ledshow.c 会得到一个led或者a.out文件,把它送到开发板上,然后

#chmod 777 led(解权限)

#./led

可以看看自己的成果啦!O(∩_∩)o 哈哈!我灰常感谢延帅师兄,他帮了我很多很多!大有什么问题可以留言给我,咱们一起探讨探讨一下!