原创 【博客大赛】(原创)OK6410的第一个驱动程序--点灯

2012-4-2 15:55 5241 21 23 分类: MCU/ 嵌入式

开始自己的嵌入式之旅了。一切神秘的面纱均可以由闪亮的LED揭开。

贴上自己的驱动程序:

#include<linux/kernel.h>
#include<linux/module.h>
#include<linux/init.h>
#include<linux/fs.h>
#include<linux/pci.h>
#include<linux/ioctl.h>
#include<linux/types.h>
#include<linux/cdev.h>
#include<linux/device.h>
#include<linux/gpio.h>
#include<mach/hardware.h>
#include<mach/regs-gpio.h>
#include<plat/gpio-cfg.h>
#include <mach/map.h>

#define DEVICE_NAME "s3c6410leds"
#define LED_ON 1
#define LED_OFF 0
dev_t devid;


static int leds_open(struct inode *inode , struct file *file)
{
  unsigned tmp;

  for(tmp=0;tmp<4;tmp++)
  s3c_gpio_cfgpin(S3C64XX_GPM(tmp),S3C_GPIO_SFN(1));
 
  return 0;
}

static long leds_ioctl( struct file *filp,unsigned int cmd,
                        unsigned long arg)
                      
{

  if(arg>4) return -EINVAL;
  //tmp = __raw_readl(S3C64XX_GPMDAT);

  switch(cmd)
  {
    case LED_ON:  //tmp &= ~(1<                   gpio_set_value(S3C64XX_GPM(arg),0);
                  return 0;
    case LED_OFF: //tmp |= 1<                   gpio_set_value(S3C64XX_GPM(arg),1);
                  return 0;
    default: return -EINVAL;
  }
}

static struct file_operations leds_ops = {
    .owner = THIS_MODULE,
    .open = leds_open,
    .unlocked_ioctl = leds_ioctl,
};

static struct cdev *cdev_led;
static struct class *led_class;

static int __init s3c6410_leds_init(void)
{
  int val;
  unsigned tmp;
 
  tmp = readl(S3C64XX_GPMPUD); //pull up gpiom0~3
  tmp &= ~(0xffff);
  tmp |= 0xaa;
  writel(tmp,S3C64XX_GPMPUD);

//  devid = MKDEV(LED_MAJOR,0);
//  val = register_chrdev_region(devid,1,DEVICE_NAME);
  val = alloc_chrdev_region(&devid,0,1,DEVICE_NAME);
  if(val) return -1;

  cdev_led = cdev_alloc();
  cdev_init(cdev_led,&leds_ops);
  val = cdev_add(cdev_led,devid,1);
  if(val)
  {
 //   printk(KERN_INFO "Add device led error!\n");
    return -1;
  }
 
  led_class = class_create(THIS_MODULE,DEVICE_NAME);
  device_create(led_class,NULL,devid,NULL,"%s",DEVICE_NAME);

 // printk(KERN_INFO "LED Initilized I'm in! ^_^ \n");
  return 0;
}

static void __exit s3c6410_leds_exit(void)
{
  cdev_del(cdev_led);
  device_destroy(led_class,devid);
  class_destroy(led_class);  
  unregister_chrdev_region(devid, 1);
}

module_init(s3c6410_leds_init);
module_exit(s3c6410_leds_exit);
 

MODULE_AUTHOR("embedded lover");
MODULE_DESCRIPTION("s3c6410 led test");
MODULE_LICENSE("GPL");;>);>


在linux2.6版本之后我们是可以让驱动程序自动建立设备节点文件的,注意下这点。

下面是自己的测试程序:

#include
#include
#include
#include

#define LED_ON 1
#define LED_OFF 0

int main(int argc, char **argv)
{
  int fd = -1;
  unsigned int led_no;
 
  fd = open("/dev/s3c6410leds",0);
  if(fd<0)
  {
    printf("Can not open device leds\n");
    return -1;
  }
 
  led_no = strtoul(argv[1],0,0) - 1;
  if(!strcmp(argv[2],"on"))
  {
    ioctl(fd,LED_ON,led_no);
  }

  else if(!strcmp(argv[2],"off"))
  {
    ioctl(fd,LED_OFF,led_no);
  }
 
  else goto err;

  close(fd);
  return 0;
 


err:
  if(fd>0) close(fd);
  return -1;

}



在写完驱动程序后有两个方法可以编译成可加载的.ko模块文件,一个是将驱动放到内核原码的driver/char目录下,再在Makefile下新增一个obj-m += name.o。再在顶层文件夹下执行make modules ,然后就可以在driver/char下找到对应的.ko文件。另外一个方法就是自己写makefile了,这样也方便。事实上无论哪种方法最终的目的其实都是要进入到内核目录下使用他的Makefie编译相关的东西。

Makefile如下:
---------------------------------------------
KDIR = /home/xu/Documents/linux-3.0.1
PWD = $(shell pwd)

obj-m := led6410.o

default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

clean:
rm -rf *.o *~ *.mod.o

最后将模块文件加载到目标板上:insmod,移除模块用:rmmod。



 

PARTNER CONTENT

文章评论2条评论)

登录后参与讨论

用户1627263 2012-9-21 10:40

请推荐几本关于ok6410学习的书

用户422688 2012-4-1 21:32

威哥,支持你

相关推荐阅读
用户1600457 2012-04-13 15:53
BOA WEB服务器移植
BOA WEB服务器的移植: 下载源码:最新的为0.94.13,之后再没有更新过 解压后进入文件夹的src/下 ./configure产生Makefile 修改Makefil...
用户1600457 2012-04-09 10:52
【博客大赛】(原创) linux进程间通信之有名管道(FIFO)的简单应用
之前写了无名管道方式的通信,这里就验证下有名管道的通信方式。 有名管道他和普通文件一样可以被读写,而且实际存在于存储设备中,一般也即磁盘,但是有名管道在进程结束后通信的信息就自动消失了,而一般...
用户1600457 2012-04-09 10:51
【博客大赛】(原创)linux进程间通信之无名管道(pipe)的简单应用
最近开始学了linux应用编程,懂了点多进程的基础知识,便跃跃欲试,想立即应用起来,以加深印象,学任何东西重在实践,技术尤为如此。 在linux中创建新的进程的函数为fork(),如果成功返回...
用户1600457 2012-04-08 11:02
【博客大赛】(原创)OK6410按键中断实现
这里本人使用中断形式实现按键的驱动,首先还是先呈上源程序: #include <linux/kernel.h> #include <linux/module.h> ...
用户1600457 2012-03-23 14:03
nor flash 与 nand flash的比较(转)
NOR和NAND是现在市场上两种主要的非易失闪存技术。Intel于1988年首先开发出NOR Flash技术,彻底改变了原先由EPROM和EEPROM一统天下的局面。紧接着,19***,东芝公司发...
EE直播间
更多
我要评论
2
21
关闭 站长推荐上一条 /3 下一条