(linux自学笔记)linux环境下GPIO字符驱动

原文:

http://www.cnblogs.com/hebaichuanyeah/

 

驱动IO口点亮一个LED。。基本上就是嵌入式领域的“helloworld”。

初识6410,裸机调试IO口。

http://www.cnblogs.com/hebaichuanyeah/p/3276735.html

linux环境下驱动包括三类:字符设备驱动,块设备驱动,网络设备驱动。

linux的驱动程序,可以编写成模块,加载到内核中。

linux的操作设备,是以文件的形式。

简单的IO口驱动,driver_led.c文件:

#include <linux/module.h>  
#include <linux/kernel.h>  
#include <linux/fs.h>  
#include <asm/uaccess.h> /* copy_to_user,copy_from_user */  
#include <linux/miscdevice.h>    
#include <linux/pci.h>    
#include <mach/map.h>    
#include <mach/regs-gpio.h>    
#include <mach/gpio-bank-m.h>    
#include <plat/gpio-cfg.h>  
  
#define LED_MAJOR 240  
  
int led_open (struct inode *inode,struct file *filp)  
  
{  
    unsigned tmp;     
    tmp = readl(S3C64XX_GPMCON);     
    tmp &= 0xffff0000;     
    tmp |= 0x00001111;
    writel(tmp, S3C64XX_GPMCON);   
    writel(0xffffffff, S3C64XX_GPMDAT);
    printk("open led
");  
    return 0;  
}  
  
ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)  
{  
    return count;  
}  
  
  
ssize_t led_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)  
{  
    char wbuf[1];  
    unsigned tmp;     

    copy_from_user(wbuf,buf,count);  
    
    tmp = readl(S3C64XX_GPMDAT);
    tmp &= 0xfffffff0;
    tmp |= wbuf[0]; 
    writel(tmp, S3C64XX_GPMDAT);
    //writel(0x02,S3C64XX_GPMDAT);
    return count;  
}  
  
int led_release (struct inode *inode, struct file *filp)  
{  
    return 0;  
}  
  
struct file_operations led_fops ={  
    .owner = THIS_MODULE,  
    .open = led_open,  
    .read = led_read,  
    .write = led_write,  
    .release = led_release,  
};  
  
int __init led_init (void)  
{   int rc;  
    printk ("led init
");  
    rc = register_chrdev(LED_MAJOR,"led",&led_fops);  
    if (rc <0)  
    {  
        printk ("register %s char dev error
","led");  
        return -1;  
    }  
    printk ("success
");  
    return 0;  
}  
  
void __exit led_exit (void)  
{  
    unregister_chrdev(LED_MAJOR,"led");  
    printk ("module exit
");  
    return ;  
}  
  
module_init(led_init);  
module_exit(led_exit);  

编写makefile文件

all: install cp clean

obj-m := driver_led.o
KDIR := /forlinux/linux-3.0.1/

install:
make -C $(KDIR) M=$(shell pwd) modules
cp:
cp driver_led.ko /mnt/share/
clean:
make -C $(KDIR) M=$(shell pwd) clean

编译生成的driver_led文件复制到 /mnt目录下(共享)。

led_test.c 简单的流水灯测试程序

#include <stdio.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
#include <fcntl.h>  
int main (void)  
{  
    int fd;  
    char buf[4]={~0x01,~0x02,~0x04,~0x08};  
    fd = open("/dev/my_led",O_RDWR);  
    if (fd < 0)  
    {  
        printf ("Open /dev/my_led file error
");  
        return -1;  
    }     
    while(1)
    {
        write(fd,&buf[0],1);  
        sleep(1);  
        write(fd,&buf[1],1);  
        sleep(1);
        write(fd,&buf[2],1);
        sleep(1);
        write(fd,&buf[3],1);
        sleep(1);
    }  
    return 0;  
  
}  

编译后,生成文件复制到目标机。

运行命令:

加载驱动模块

insmod driver_led.ko

建立驱动文件
mknod /dev/my_led c 240 0

运行调试程序
./led_test

LED流水灯。

原文地址:https://www.cnblogs.com/hebaichuanyeah/p/3460498.html