1、JZ2440 LED驱动

 驱动代码

  1 /* 
  2     led驱动 同时开关所有的LED
  3     GPF4、5、6控制LED
  4 
  5     寄存器      地址            R/W        描述                         复位值
  6     GPFCON      0x56000050      R/W         配置端口 F 的引脚           0x0
  7     GPFDAT      0x56000054      R/W         端口 F 的数据寄存器         –
  8     GPFUP       0x56000058      R/W         端口 F 的上拉使能寄存器     0x00
  9     保留        0x5600005C      –           保留                        –
 10 **/
 11 #include <linux/module.h>
 12 #include <linux/kernel.h>
 13 #include <linux/fs.h>
 14 #include <linux/init.h>
 15 #include <linux/delay.h>
 16 #include <asm/uaccess.h>
 17 #include <asm/irq.h>
 18 #include <asm/io.h>
 19 #include <asm/arch/regs-gpio.h>
 20 #include <asm/hardware.h>
 21 
 22 
 23 volatile unsigned long *gpfcon = NULL;
 24 volatile unsigned long *gpfdat = NULL;
 25 
 26 struct class * led_dev1_class;
 27 struct class_device * led_dev1_class_device;
 28 
 29 static int led_dev1_open(struct inode *inode, struct file *file)
 30 {
 31     /* 配置GPF4,5,6为输出 */
 32     *gpfcon &= ~((0x03<<(4*2)) | (0x03<<(5*2)) | (0x03<<(6*2)));
 33     *gpfcon |= ((0x01<<(4*2)) | (0x01<<(5*2)) | (0x01<<(6*2)));
 34 
 35     return 0;
 36 }
 37 
 38 static ssize_t led_dev1_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
 39 {
 40     int val;
 41 
 42     //从用户空间拷贝数据到内核空间
 43     copy_from_user(&val, buf, count); //    copy_to_user();
 44 
 45     if(val == 1)
 46     {
 47         /* 点灯 低电平 */
 48         *gpfdat &= ~((0x01 << 4)|(0x01 << 5)|(0x01 << 6));
 49     }
 50     else
 51     {
 52         /* 灭灯 高电平*/
 53         *gpfdat |= ((0x01 << 4)|(0x01 << 5)|(0x01 << 6));
 54     }
 55     
 56     return 0;
 57 }
 58 
 59 /* 定义一个文件操作的结构体 */
 60 static struct file_operations led_dev1_fops = 
 61 {
 62     .owner = THIS_MODULE,
 63     .open = led_dev1_open,
 64     .write = led_dev1_write,
 65 };
 66 
 67 
 68 int major;  //存储设备号
 69 /* 
 70     驱动入口函数
 71 **/
 72 static int __init led_dev1_init(void)
 73 {
 74     /* 注册设备 */
 75     major = register_chrdev(0,"led_dev1",&led_dev1_fops);
 76 
 77     //创建一个 struct class 结构体
 78     led_dev1_class = class_create(THIS_MODULE,"led_dev1");
 79     //在加载模块是自动创建一个设备节点
 80     led_dev1_class_device = class_device_create(led_dev1_class,NULL,MKDEV(major,0),NULL,"led_dev1");
 81 
 82     //地址映射
 83     gpfcon = ioremap(0x56000050,16);
 84     gpfdat = gpfcon + 1;
 85 
 86     /**/
 87     return 0;
 88 }
 89 
 90 /*
 91     驱动出口函数
 92 **/
 93 static void __exit led_dev1_exit(void)
 94 {
 95     /* 卸载设备 */
 96     unregister_chrdev(major,"led_dev1");
 97     //删除设备节点
 98     class_device_unregister(led_dev1_class_device);
 99     //销毁 struct class 结构体
100     class_destroy(led_dev1_class);
101     //取消地址映射
102     iounmap(gpfcon);
103 
104 }
105 
106 /* 将函数指定为驱动的入口和出口函数 */
107 module_init(led_dev1_init);
108 module_exit(led_dev1_exit);
109 /* 模块的许可证声明 */
110 MODULE_LICENSE("GPL");  
View Code

  测试代码

/*
    led_dev1 驱动测试函数
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>

int main(int argc,char **argv)
{
    int fd;
    int val;

    fd = open("/dev/led_dev1",O_RDWR);

    if(fd < 0)
    {
        printf("can't open\n");
    }
    if(argc != 2)
    {
        printf("Usage:\n");
        printf("%s <on/off>\n",argv[0]);
        return 0;
    }
    if (strcmp(argv[1], "on") == 0)
    {
        val = 1;
    }
    else
    {
        val = 0;
    }

    write(fd,&val,4);

    return 0;
}
View Code

 Makefile

1 KERN_DIR = /work/system/linux-2.6.22.6
2 
3 all:
4     make -C $(KERN_DIR) M=`pwd` modules 
5 
6 clean:
7     make -C $(KERN_DIR) M=`pwd` modules clean
8     rm -rf modules.order
9 obj-m    += led_dev1.o
View Code

 

posted @ 2020-08-01 16:31  季风的杜萨  阅读(111)  评论(0编辑  收藏  举报