6410led驱动模块及测试程序(独立控制四个led)

6410LED驱动及测试程序

LED驱动模块编译:(led.c)

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define DEVICE_NAME "leds0" //设备名(/dev/leds)

#define UGPMCON (*(volatile unsigned long *)S3C64XX_GPMCON)
#define UGPMDAT (*(volatile unsigned long *)S3C64XX_GPMDAT)
#define UGPMPUD (*(volatile unsigned long *)S3C64XX_GPMPUD)

static long S3C64XX_GPMCON=0xF4500820;
static long S3C64XX_GPMDAT=0xF4500824;

#define LED_MAJOR 240

static int led_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
//      printk(KERN_ALERT"\ncmd = %d  arg = %d \n", cmd, arg);

    switch(cmd)
    {
        case 0:
            printk(KERN_ALERT"led%d off\n", arg);
            switch(arg)
            {
            case 0:
                UGPMDAT |= 0x01;
                break;
            case 1:
                UGPMDAT |= 0x02;
                break;
            case 2:
                UGPMDAT |= 0x04;
                break;
            case 3:
                UGPMDAT |= 0x08;
                break;

            default:
                break;
            }
            break;
        case 1:
            printk(KERN_ALERT"led%d on\n", arg);
            switch(arg)
            {
            case 0:
                UGPMDAT &= 0xfe;
                break;
            case 1:
                UGPMDAT &= 0xfd;
                break;
            case 2:
                UGPMDAT &= 0xfb;
                break;
            case 3:
                UGPMDAT &= 0xf7;
                break;

            default:
                break;
            }

            break;
        case 11:
            printk(KERN_ALERT"led all on\n");
                UGPMDAT &= 0xe0;
            break;
        case 10:
            printk(KERN_ALERT"led all off\n");
                UGPMDAT |= 0xff;
            break;

        default:
            break;
        }

    return 0;
}

struct file_operations led_fops={
    .owner = THIS_MODULE,
    .unlocked_ioctl = led_ioctl,
};

static struct miscdevice misc = {

    .minor = MISC_DYNAMIC_MINOR, //动态设备号

    .name = DEVICE_NAME,

    .fops = &led_fops,

};


static int __init led_init(void)
{
    int rc;
    rc = misc_register(&misc);
    outl(0x00111111,S3C64XX_GPMCON);
    outl(0xff,S3C64XX_GPMDAT);

    if(rc<0)
    {
        printk(KERN_ALERT"register %s char dev error\n","leds");
        return -1;
    }
    printk(KERN_ALERT"OK!\n");
    return 0;
}

static void __exit led_exit(void)
{
    unregister_chrdev(LED_MAJOR, "leds");
    printk(KERN_ALERT"module exit\n");
}

module_init(led_init);
module_exit(led_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("cw");

 Makefile:

KERNELDIR :=/home/share/linux/linux3.0/kernel/linux-3.0.1
#KERNELDIR :=/home/share/linux/linux2.6.36/linux-2.6.36.2-v1.05
PWD :=$(shell pwd)
modules:
        $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

modules_install:
      $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
obj-m:=led.o

clean:
      rm -rf *.o *~core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers

编写完led.c和Makefile后,make生成led.ko模块,拷贝到开发板,注意开发板上的内核版本要和Makefile

中的内核版本一至,否则会报错.

 

 

测试程序:(编译: arm-linux-gcc test.c -o test)

#include 
#include 
#include 
#include 
int main(int argc, char **argv)
{
     int on, cmd;
     int led_no;
     int fd;

        if (argc != 3 || sscanf(argv[1], "%d", &led_no) != 1 || sscanf(argv[2],"%d", &on) != 1 || led_    no < 0 || led_no > 3) {
             fprintf(stderr, "Usage: leds led_no 0|1|2|3\n");
             exit(1);
        }
        fd = open("/dev/leds0", 0);
        if(fd < 0)
             printf("Can't open /dev/leds!\n");

        ioctl(fd, on, led_no);
        close(fd);

        return 0;
}

 

将编译好的led.kotest拷贝到6410

cp /sdcard/led.ko /etc

Insmod /etc/led.ko

./test 0 0

注:

./test 0 0 led0 灭 ./test 1 0 led1 ./test 2 0 led3 ./test 3 0 led3 

./test 0 1 led0 亮 ./test 1 1 led1 ./test 2 1 led3 ./test 3 1 led3 

./test  0  10  led0 全灭

./test  0  11  led0 全亮

开机自动加载模块:

修改开发板 /etc/init.d/rcS  添加 insmod /etc/led.ko

你可能感兴趣的:(Linux,测试,makefile,module,cmd,c,file)