Chinaunix首页 | 论坛 | 博客
  • 博客访问: 383520
  • 博文数量: 69
  • 博客积分: 1992
  • 博客等级: 上尉
  • 技术积分: 1162
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-03 19:50
文章分类
文章存档

2015年(1)

2011年(55)

2010年(13)

分类: LINUX

2010-06-03 17:17:10


先贴出源代码:
led源程序:

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/cdev.h>
#include <linux/ioctl.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/gpio.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>

//自己定义的头文件

#include "led.h"

#define DEVICE_NAME "led_lwm" //设备名称

#define LED_MAJOR 106 // 主设备号


#define GPBCON    (unsigned long) (0x56000010)
#define GPBDAT    (unsigned long) (0x56000014)
#define GPBUP    (unsigned long) (0x56000018)

unsigned long _IO_GPBCON;
unsigned long _IO_GPBDAT;
unsigned long _IO_GPBUP;

#define GPB5_0 ~(1<<5)
#define GPB6_0 ~(1<<6)
#define GPB7_0 ~(1<<7)
#define GPB8_0 ~(1<<8)

#define GPB5_1 (1<<5)
#define GPB6_1 (1<<6)
#define GPB7_1 (1<<7)
#define GPB8_1 (1<<8)

void ledinit(void)
{
    _IO_GPBCON = (unsigned long)ioremap(GPBCON,0x4);
    _IO_GPBDAT = (unsigned long)ioremap(GPBDAT,0x4);
    _IO_GPBUP = (unsigned long)ioremap(GPBUP,0x4);
    *(volatile unsigned long *)_IO_GPBCON = 0x154FD;
    *(volatile unsigned long *)_IO_GPBUP = 0x7FF;
}

static int leds_open(struct inode *inode, struct file *file)
{
    return 0;
}

static int leds_ioctl(struct inode *inode, struct file *file,
                     unsigned int cmd, unsigned long arg)
{
    //检测命令的有效性

    if (_IOC_TYPE(cmd) != LED_MAGIC)    
    return -EINVAL;
    if (_IOC_NR(cmd) > LED_MAXNR)
    return -EINVAL;

    //根据命令,点亮或熄灭相应的LED灯

    switch(cmd)
    {
    
        case LED1_ON:
        {
        *(volatile unsigned long *)_IO_GPBDAT &= GPB5_0;
               break;
        }
        case LED1_OFF:
        {
        *(volatile unsigned long *)_IO_GPBDAT |= GPB5_1;
                break;
        }
        case LED2_ON:
        {    
     *(volatile unsigned long *)_IO_GPBDAT &= GPB6_0;
               break;
        }
        case LED2_OFF:
        {
        *(volatile unsigned long *)_IO_GPBDAT |= GPB6_1;
               break;
        }
        case LED3_ON:
        {
        *(volatile unsigned long *)_IO_GPBDAT &= GPB7_0;
               break;
        }
        case LED3_OFF:
        {
        *(volatile unsigned long *)_IO_GPBDAT |= GPB7_1;
               break;
        }
        case LED4_ON:
        {    
        *(volatile unsigned long *)_IO_GPBDAT &= GPB8_0;
               break;
        }
        case LED4_OFF:
        {
        *(volatile unsigned long *)_IO_GPBDAT |= GPB8_1;
               break;
        }
        default:
        {
     return -EINVAL;
        }
    }
    return 0;
}

static struct file_operations leds_fops =
{
    .owner = THIS_MODULE,
    .open = leds_open,
    .ioctl = leds_ioctl,
};

static int __init led_init(void)
{
    int ret;
 //初始化各IO口为输出模式,这里初始化为1,不让LED点亮

           ledinit();
    *(volatile unsigned long *)_IO_GPBDAT = 0x1E0;
 //注册LED设备为字符设备

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

    if(ret < 0)
    {
        printk(DEVICE_NAME " register falid!\n");
        return ret;
    }
    return 0;
}

static void __exit led_exit(void)
{
    //注销设备

    unregister_chrdev(LED_MAJOR, DEVICE_NAME);
}

module_init(led_init);
module_exit(led_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("li wei meng");
MODULE_DESCRIPTION("led driver of li wei meng");



测试程序:


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#include "led.h"

int main(void)
{
    int val,fd;
   
    //打开LED设备

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

    if(fd < 0)
    {
        printf("Open Led Device Faild!\n");
        exit(1);
    }

    //IO控制

   else
    {
    input: printf("please input 10/11/20/21/30/31/40/41:\n");
                  printf("if you want to exit,please input 886\n");
        scanf("%d",&val);
        switch (val)
        {
            case 10:
                ioctl(fd,LED1_ON,0);
                break;
            case 11:
                ioctl(fd,LED1_OFF,0);
                break;
            case 20:
                ioctl(fd,LED2_ON,0);
                break;
            case 21:
                ioctl(fd,LED2_OFF,0);
                break;
            case 30:
                ioctl(fd,LED3_ON,0);
                break;
            case 31:
                ioctl(fd,LED3_OFF,0);
                break;
            case 40:
                ioctl(fd,LED4_ON,0);
                break;
            case 41:
                ioctl(fd,LED4_OFF,0);
                break;
            default:
                break;
        }
        if(val != 886)
            goto input;
        else    
            return 0;
    }
}



头文件:led。h

#ifndef _LED_H
#define _LED_H
#include <linux/ioctl.h>

//定义幻数

#define LED_MAGIC    'l'

//定义命令

#define LED1_ON        _IO(LED_MAGIC,1)
#define LED1_OFF    _IO(LED_MAGIC,2)
#define LED2_ON        _IO(LED_MAGIC,3)
#define LED2_OFF    _IO(LED_MAGIC,4)
#define LED3_ON        _IO(LED_MAGIC,5)
#define LED3_OFF    _IO(LED_MAGIC,6)
#define LED4_ON        _IO(LED_MAGIC,7)
#define LED4_OFF    _IO(LED_MAGIC,8)

#define LED_MAXNR    8

#endif


刚开始实现的时候,ioctrl的命令直接用的是0,1,2,3,4,5,6,7结果LED2那盏灯死活不亮。

后来经过师兄的帮忙,从这个过程才第一次领会到怎么去调试,怎么去发现问题,怎么去排除问题。后来发现时ioctl的命令冲突的原因。得到这个原因是一步一步排除错误的原因,最终确定只有这么一个原因。后来又学习ioctl的命令码应该怎么定义,才不会冲突。最后就出现了上面的程序。

makefile:

KERNELDIR = /home/linux/linux-2.6.32.2
PWD := $(shell pwd)
CROSS_COMPILE = /usr/local/arm/4.3.2/bin/arm-linux-
CC = $(CROSS_COMPILE)gcc
obj-m := led.o
default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
    rm -rf *.ko *.o *.mod.o *.mod.c *.symvers *.order

.PHONY: modules modules_install clean



通过FTP下到板子上之后,首先要在/dev目录下创建节点
mknod /dev/led_lwm c 106 0
然后insmod /lib/modules/2.6.32.2/led.ko
最后去执行测试程序。

这个上传图片怎么这么麻烦?
阅读(1003) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~