zoukankan      html  css  js  c++  java
  • [国嵌攻略][117][LED驱动程序设计]

    LED程序设计

    1.编写内核模块

    2.搭建字符驱动框架

    3.实现设备方法

    头文件

    <linux/io.h>

    writel()

    1.编译/安装驱动

    make

    cp leddev.ko .../rootfs

    insmod leddev.ko

    2.创建设备文件

    mknod /dev/myled0 c 253 0

    3.编译/运行应用程序

    arm-linux-gcc -static ledapp.c -o ledapp

    cp ledapp .../rootfs

    ./ledadd 0

    ./ledadd 1

    leddev.h

    /********************************************************************
    *设备命令
    *********************************************************************/
    #define LED_MAGIC 'L'               //LED幻数
    #define LED_ON  _IO(LED_MAGIC, 0)   //LED打开
    #define LED_OFF _IO(LED_MAGIC, 1)   //LED关闭

    leddev.c

    /********************************************************************
    *头文件
    *********************************************************************/
    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/cdev.h>
    #include <linux/fs.h>
    #include <linux/io.h>
    #include "leddev.h"
    
    /********************************************************************
    *宏定义
    *********************************************************************/
    #define GPBCON 0x56000010   //控制寄存器物理地址
    #define GPBDAT 0x56000014   //数据寄存器物理地址
    
    /********************************************************************
    *全局变量
    *********************************************************************/
    struct cdev chrdev;   //字符设备
    dev_t devnum;         //主设备号
    
    unsigned int *ledCon;   //控制寄存器指针
    unsigned int *ledDat;   //数据寄存器指针
    
    /********************************************************************
    *设备方法
    *********************************************************************/
    //控制设备
    long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){
        //处理命令
        switch(cmd){
            case LED_ON:    //打开LED
                writel(0x00000000, ledDat);   //GPBDAT[8:5]:0000
                break;
                
            case LED_OFF:   //关闭LED
                writel(0x000001E0, ledDat);   //GPBDAT[8:5]:1111
                break;
                
            default:
                return -EINVAL;
        }
        
        return 0;
    }
    
    //打开设备
    int led_open(struct inode *node, struct file *filp){
        //配置LED引脚
        ledCon = ioremap(GPBCON, 4);   //虚拟地址转换
        writel(0x00015400, ledCon);    //GPBCON[17:10]:01010101
        
        //设置LED状态
        ledDat = ioremap(GPBDAT, 4);   //虚拟地址转换
        writel(0x00000140, ledDat);    //GPBDAT[8:5]:1010
        
        return 0;
    }
    
    //关闭设备
    int led_close(struct inode *node, struct file *filp){
        return 0;
    }
    
    //设备方法
    struct file_operations led_fops = {
        .unlocked_ioctl = led_ioctl,
        .open           = led_open,
        .release        = led_close
    };
    
    /********************************************************************
    *模块安装
    *********************************************************************/
    //安装模块
    static int led_init(){
        //注册设备标识
        cdev_init(&chrdev, &led_fops);
        
        //注册主设备号
        alloc_chrdev_region(&devnum, 0, 1, "myled");
        
        //添加设备标识
        cdev_add(&chrdev, devnum, 1);
        
        return 0;
    }
    
    //卸载模块
    static void led_exit(){
        //注销设备标识
        cdev_del(&chrdev);
        
        //注销主设备号
        unregister_chrdev_region(devnum, 1);
    }
    
    /********************************************************************
    *模块声明
    *********************************************************************/
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("D");
    MODULE_DESCRIPTION("");
    MODULE_VERSION("v1.0");
    
    module_init(led_init);
    module_exit(led_exit);

    ledapp.c

    #include <stdio.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/ioctl.h>
    #include <unistd.h>
    #include "leddev.h"
    
    int main(int argc, char **argv){
        //参数检测
        if(argc != 2){
            printf("Usage:
    	%s <state>
    ", argv[0]);
            return -1;
        }
        
        //打开设备
        int fd;
        
        fd = open("/dev/myled0", O_RDWR);
        
        //控制设备
        int state;
        
        state = atoi(argv[1]);
        if(state){   //打开LED
            ioctl(fd, LED_ON);
        }else{       //关闭LED
            ioctl(fd, LED_OFF);
        }
        
        //关闭设备
        close(fd);
        
        return 0;
    }
  • 相关阅读:
    Windows Phone7 开发工具简介
    peration not supported. Unknown error: 0x8973190e
    C/C++学习建议(摘抄自:程序员2010年8月P61页)
    OpenOffice/LibreOffice的行距问题
    Finder打开剪切功能
    设备资源管理系统-用户管理
    设备资源管理系统-数据字典
    设备资源管理系统-代办事宜
    设备资源管理系统-首页显示
    设备资源管理系统-DAO底层方法-查询
  • 原文地址:https://www.cnblogs.com/d442130165/p/5251917.html
Copyright © 2011-2022 走看看