TQ2440在linux下的LED驱动程序

来源:互联网 发布:网络机柜 尺寸 编辑:程序博客网 时间:2024/06/08 07:44

简单的在linux下的led驱动程序。
TQ2440,操作系统为linux,内核版本linux-2.6.30.4

//leds.c#include <linux/module.h>#include <linux/init.h>#include <linux/fs.h>#include <linux/cdev.h>#include <linux/kdev_t.h>#include <linux/kernel.h>#include <asm/io.h>#define GPBOUT  (1<<(5*2)) |(1<<(6*2)) | (1<<(7*2)) | (1<<(8*2));               //设置GPB5/6/7/8为输出int major = 0;struct cdev* leds_cdev;volatile unsigned long *GPBCON = NULL;volatile unsigned long *GPBDAT = NULL;static int  leds_open(struct inode *inode, struct file *filp){    *GPBCON = 0;                                        //控制端口清零    *GPBCON = GPBOUT;    return 0;}static int leds_ioctl(struct inode* inode, struct file* filp, unsigned int cmd, unsigned long arg){    if (arg > 4)    {        printk("deyond the led no\n");    }        switch (cmd)    {        case 1:            *GPBDAT |= (1<<(arg + 4));                      //灭灯            break;        case 0:            *GPBDAT &= ~(1<<(arg + 4));                 //亮灯                break;        default:            printk("cmd error\n");            break;    }    return 0;}struct file_operations leds_fops = {    .owner = THIS_MODULE,    .open = leds_open,    .ioctl = leds_ioctl,};static int __init leds_init(void){    dev_t dev;    leds_cdev = cdev_alloc();        alloc_chrdev_region(&dev, 0, 1, "leds");    major = MAJOR(dev);    leds_cdev->ops = &leds_fops;    cdev_init(&leds_cdev, &leds_fops);    cdev_add(&leds_cdev, dev, 1);    *GPBCON = (volatile unsigned int *)ioremap(0x56000010, 16);                  //将物理地址映射到虚拟地址,GPBCON物理地址为0x56000010    *GPBDAT = *GPBCON + 1;                                                                          //GPBDAT物理地址为0x56000014    return 0;}static void __exit leds_exit(void){    dev_t dev;    dev = MKDEV(major, 0);    cdev_del(&leds_cdev);    unregister_chrdev_region(dev, 1);}module_init(leds_init);module_exit(leds_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("不做超哥已多年");MODULE_DESCRIPTION("leds");
测试程序:

//leds_test.c#include <stdio.h>#include <linux/types.h>#include <fcntl.h>#include <unistd.h>#include <errno.h>#define ON 0#define OFF 1int main(int argc, char* argv[]){    int led_no;    if (argc != 3)    {        printf("Usage: %s <led_no> <ON/OFF>\n", argv[0]);        exit(0);    }    int fd;    fd = open("/dev/leds", O_RDWR);    if (fd < 0)    {        printf("open error\n");        exit(0);    }    led_no = strtoul(argv[1], 0, 0);          //将字符串转换成无符号长整型数        if (!strcmp(argv[2], "ON"))        ioctl(fd, ON, led_no);    else if (!strcmp(argv[2], "OFF"))        ioctl(fd, OFF, led_no);    else         exit(0);            return 0;}
编译驱动模块,在arm板上加载,交叉编译测试程序,在板子上运行成功

命令是./leds_test led_no ON/OFF 如 ./led_test 1 ON就是点亮led1灯

点亮四个灯后效果:

看到可以控制灯亮灭了,你是否想起了当初玩单片机时点led灯时的兴奋呢......哈哈哈哈,好兴奋啊