[国嵌攻略][117][LED驱动程序设计]

Posted 盛夏夜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[国嵌攻略][117][LED驱动程序设计]相关的知识,希望对你有一定的参考价值。

LED程序设计

1.编写内核模块

2.搭建字符驱动框架

3.实现设备方法

 

头文件

<linux/io.h>

writel()

 

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;   //数据寄存器

/********************************************************************
*设备方法
*********************************************************************/
//打开LED
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;
}

//关闭LED
int led_close(struct inode *node, struct file *filp){
    return 0;
}

//控制LED
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;
}

//LED方法
struct file_operations led_fops = {
    .open           = led_open,
    .release        = led_close,
    .unlocked_ioctl = led_ioctl
};

/********************************************************************
*模块安装
*********************************************************************/
//加载模块
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("myled");
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:\n\t%s <state>\n", 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;
}

 

以上是关于[国嵌攻略][117][LED驱动程序设计]的主要内容,如果未能解决你的问题,请参考以下文章

[国嵌攻略][155][I2C用户态驱动设计]

[国嵌攻略][151][nandflash驱动程序设计]

[国嵌攻略][147][简单块设备驱动设计]

[国嵌攻略][087][多线程程序设计]

[国嵌攻略][164][USB驱动程序设计]

[国嵌攻略][091][TCP网络程序设计]