OK6410的linux的LED驱动,GPIO驱动

Ok6410开发板LED连接:

4个LED分别连接到核心板上的GPM端:

目前4个LED对应的端口:

GPM0->LED1  GPM1->LED2 GPM2->LED3  GPM3->LED4

查看s3c6410芯片手册,端口M对应的三个寄存器地址:


对应控制寄存器GPMCON设置相应的位,将端口设置为输出:

再对寄存器GPMDAT对应的位写入0/1即可控制LED的点亮与熄灭:

以上是原理部分,下面开工写代码,。

驱动代码可以在linux的源代码树里添加编写也可以另外在单独的目录里编写,第一种方法比较直观,并可以用内核的图形配置界面进行配置,但是需要修改相应的Mkaefile和Kconfig文件,这里为了尽量不破坏源代码的结构,也为了更好的移植采用第二种办法,另起炉灶,但是仍需要借助内核的源代码。


 

#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>  //此文件是GPM对应的寄存器地址等的定义
#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 = (tmp &~(0x7U<<1))|(0x1U);  
         writel(tmp,S3C64XX_GPMCON);
         printk("#########open######\n");
         return 0;
}
 
ssize_t led_read (struct file *filp, char __user *buf, size_t count,loff_t*f_pos)
{
         printk("#########read######\n");
         return count;
}
 
 
ssize_t led_write (struct file *filp, const char __user *buf, size_tcount,loff_t *f_pos)
{
         char wbuf[10];
         unsigned tmp;  
         printk("#########write######\n");
         copy_from_user(wbuf,buf,count);
         switch(wbuf[0])
         {
                   case 0:  //off
                            tmp =readl(S3C64XX_GPMDAT);  
                                     tmp |= (0x1U);  
                                     writel(tmp, S3C64XX_GPMDAT);
                            break;
                   case 1:  //on
                            tmp =readl(S3C64XX_GPMDAT);  
                                     tmp &= ~(0x1U);  
                                     writel(tmp, S3C64XX_GPMDAT);
                            break;
                   default :
                            break;
         }
         return count;
}
 
int led_release (struct inode *inode, struct file *filp)
{
         printk("#########release######\n");
         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 ("Test leddev\n");
         rc =register_chrdev(LED_MAJOR,"led",&led_fops);
         if (rc <0)
         {
                   printk ("register%s char dev error\n","led");
                   return -1;
         }
         printk("ok!\n");
         return 0;
}
 
void __exit led_exit (void)
{
         unregister_chrdev(LED_MAJOR,"led");
         printk ("moduleexit\n");
         return ;
}
 
module_init(led_init);
module_exit(led_exit);

 

gpio-bank-m.h文件代码树中没有该文件,众里寻他千百度啊,终于在WRT的一个补丁文件中找到了该文件:

在\home\linux-2.6\arch\arm\mach-s3c64xx\include\mach可以自己新建一个gpio-bank-m.h

编写Makefile文件 KDIR为linux内核所在目录


obj-m := driver_led.o
KDIR :=/home/linux-2.6/
all:
        make -C $(KDIR) M=$(shellpwd) modules
install:
        cp driver_led.ko/nfsroot/
clean:
        make -C $(KDIR) M=$(shellpwd) clean



编写测试程序:


#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int main (void)
{
         int fd;
         char buf[10]={0,1};
         fd = open("/dev/my_led",O_RDWR);
         if (fd < 0)
         {
                   printf("Open /dev/my_led file error\n");
                   return -1;
         }       
         while(1)
         {
                   write(fd,&buf[0],1);
                   sleep(1);
                   write(fd,&buf[1],1);
                   sleep(1);
         }
         close (fd);
         return 0;
 
}
 



Make生成.ko文件:

arm-linux-gcc  test.c -o  test

    

将以上生成的两个文件拷贝到NFS目录,连接开发板,进行实验

模块儿文件拷贝到/lib/modules/3.2.0-rc7-00022-gd0c9386/目录下,3.2.0-是对应的版本号:

程序可以拷贝到任意目录:

创建设备文件:

mknod  /dev/my_led  c  240  0

加载模块

运行测试程序:

可以看到开发板上第一个LED状态不断变化。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值