exynos4412开发板LED驱动程序

本文将介绍在EXYNOS4412平台上实现对LED灯开关的控制

首先定义命令在led.h文件中

#define LED_MAGIC 'L'
#define LED_ON _IO(LED_MAGIC,1)
#define LED_OFF _IO(LED_MAGIC,0)                                 

exynos4412开发板LED驱动程序_第1张图片

LED2对应控制寄存器为GPL2
LED3对应控制寄存器为GPK1
接下来编写led控制驱动程序

#include 
#include 
#include 
#include 
#include 
#include "led.h"
#define GPL2CON 0x11000100 
//GPL2CON寄存器的物理地址
#define GPL2DAT 0x11000104         
//GPL2DAT寄存器的物理地址
#define GPK1CON 0x11000060
//GPK1CON寄存器的物理地址
#define GPK1DAT 0x11000064
//GPK1DAT寄存器的物理地址

static int *pgpl2con;
static int *pgpl2dat;

static int *pgpk1con;
static int *pgpk1dat;

struct cdev cdev;
dev_t devno;
int led_open(struct inode *node, struct file *filp)
{
    pgpl2con = ioremap(GPL2CON,4);//将物理地址转化为虚拟地址
    pgpl2dat = ioremap(GPL2DAT,4);

    pgpk1con = ioremap(GPK1CON,4);
    pgpk1dat = ioremap(GPK1DAT,4);

    writel((readl(pgpl2con)& ~(0xf<<0)) |(0x1<<0),pgpl2con);
   //led2对应GPL2寄存器的第0位,将其写0x1配置为输出模式
    writel((readl(pgpk1con)& ~(0xf<<4)) |(0x1<<4),pgpk1con);
     // led3对应GPK1寄存器的第0位,将其写0x1配置为输出模式
    return 0;
}

long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    switch (cmd)
    {
        case LED_ON:
             writel(readl(pgpl2dat) |(0x1<<0), pgpl2dat);
               //led2对应GPL2寄存器的第0位,将其写0x1配置为高电平
             writel(readl(pgpk1dat) |(0x1<<1), pgpk1dat);
             //led2对应GPk1寄存器的第0位,将其写0x1配置为高电平
            printk("OPEN is success\n");
            break;

        case LED_OFF:
            writel(readl(pgpl2dat) &(~(0x1<<0)), pgpl2dat);
             //led2对应GPL2寄存器的第0位,将其0x1取反为0配置为低电平
            writel(readl(pgpk1dat) &(~(0x1<<1)), pgpk1dat);
             //led2对应GPK1寄存器的第0位,将其0x1取反为0配置为低电平
            printk("close is success\n");
            break;
        default:
            return -EINVAL;
    }
}
/*文件操作结构体*/
static struct file_operations led_fops =
{
    .open = led_open,
    .unlocked_ioctl = led_ioctl,
};
/*设备驱动模块加载函数*/
static int led_init()
{
    cdev_init(&cdev,&led_fops);*初始化cdev结构*/

    alloc_chrdev_region(&devno, 0 , 1 , "myled"); /* 注册字符设备 */
    cdev_add(&cdev, devno, 1);

    return 0;
}

static void led_exit()
{
    cdev_del(&cdev); /*注销设备*/
    unregister_chrdev_region(devno,1);/*释放设备号*/
}
module_init(led_init);
module_exit(led_exit);

应用程序

led_app.c
#include
#include
#include
#include
#include "led.h"
#include

int main(int argc,char *argv[])
{
    int fd;
    int cmd;
    if(argc<2)
    {
        printf("please input second para\n");
        return 0;

    }
    cmd = atoi(argv[1]);
    fd = open("/dev/myled0",O_RDWR);
    if(cmd ==1)
    ioctl(fd,LED_ON);
    if(cmd==0)
    ioctl(fd,LED_OFF);

    return 0;

}

编写Makefile,通过make编译该驱动程序生成led.ko文件。
使用arm-none-linux-gnueabi-gcc led_app.c -o led_app -static编译应用程序文件,使用
tftp将led.ko ,led_app下载到开发板中
[root@iTOP-4412]# insmod led.ko
[root@iTOP-4412]# mknod /dev/myled0 c 249 0
[root@iTOP-4412]# ./led_app 0
[ 26.834348] close is success
[root@iTOP-4412]# ./led_app 1
[ 31.561757] OPEN is success

你可能感兴趣的:(LINUX设备驱动实战)