mini2440开发板-led驱动学习

mini2440烧录进自己配置的内核镜像,commandlines,文件系统,superboot,启动开发板后led一直在按照顺序闪灭,怀疑是led的程序自启动了。

[root@FriendlyARM bin]# cat /etc/init.d/rcS 
打开脚本后发现有段代码启动led脚本
sleep 1
/etc/rc.d/init.d/leds start
echo "                        " > /dev/tty1
echo "Starting leds service..." > /dev/tty1
echo "                        "
sleep 1

打开led的sh脚本:

[root@FriendlyARM bin]# cat /etc/rc.d/init.d/leds
#!/bin/sh

base=led-player

# See how we were called.
case "$1" in
  start)
                /usr/bin/$base &
        ;;
  stop)
        pid=`/bin/pidof $base`
        if [ -n "$pid" ]; then
                kill -9 $pid
        fi
        ;;
esac

exit 0

led-player这个文件是二进制文件。我并不想让LED开机就走跑马灯,所以在/etc/init.d/rcS 中leds start那句注释掉,重新启动开发板就可以了。

测试例程:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

#define IOCTL_LED_ON 0
#define IOCTL_LED_OFF 1

void usage(char* exename)
{
  printf("Usage:\n");
  printf("  %s <led_no> <on/off>\n",exename);
  printf(" led_no = 1,2,3,4\n ");
}

int main(int argc,char** argv)
{
  unsigned int led_no;
  int fd = -1;

  if(argc != 3)
    {
      goto err;
    }
  fd = open("/dev/leds",0);
  if(fd<0)
    {
      printf("can't open /dev/leds\n");
      return -1;
    }
  led_no = strtoul(argv[1],0,0)-1;
  if(led_no > 3)
    {
      goto err;
    }
  if(strcmp(argv[2],"on"))
    {
      ioctl(fd,IOCTL_LED_ON,led_no);
    }else if(strcmp(argv[2],"off")){
	ioctl(fd,IOCTL_LED_OFF,led_no);
	}else{
   	 goto err;
  	}
  close(fd);
  return 0;

err:
if(fd > 0)
  {
    close(fd);
  }
usage(argv[0]);
return -1;
}

LED驱动代码:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>

#define DEVICE_NAME "leds"
#define LED_MAJOR 231

#define IOCTL_LED_ON 0
#define IOCTL_LED_OFF 1

static unsigned long led_table[] = {
	S3C2410_GPB5,
	S3C2410_GPB6,
	S3C2410_GPB7,
	S3C2410_GPB8,
};

static unsigned int led_cfg_table[] = {
	S3C2410_GPB5_OUTP,
	S3C2410_GPB6_OUTP,
	S3C2410_GPB7_OUTP,
	S3C2410_GPB8_OUTP,
};

static int s3c24xx_leds_open(struct inode* inode,
	struct file* file)
{
	int i;
	
	for(i=0;i<4;i++)
	{
		s3c2410_gpio_cfgpin(led_table[i],led_cfg_table[i]);
	}
	return 0;
}

static int s3c24xx_leds_ioctl(
	struct inode* inode,
	struct file* file,
	unsigned int cmd,
	unsigned long arg)
{
	if(arg > 4)
	{
		return -EINVAL;	
	}
	switch(cmd)
	{
	case IOCTL_LED_ON:
	  s3c2410_gpio_setpin(led_table[arg],0);
	case IOCTL_LED_OFF:
	  s3c2410_gpio_setpin(led_table[arg],1);
	default:
	  return -EINVAL;
	}
}

static struct file_operations s3c24xx_led_fops ={
  .owner=THIS_MODULE,
  .open = s3c24xx_leds_open,
  .ioctl = s3c4xx_leds_ioctl;
};

static int __init s3c24xx_leds_init(void)
{
  int ret;

  ret = register_chrdev(LED_MAJOR,DEVICE_NAME,&s3c24xx_leds_fops);
  if(ret < 0)
    {
      printk(DEVICE_NAME "can't register major number\n");
    }
  printk(DEVICE_NAME " initilizaed\n");
  return 0;
}

static void __exit s3c24xx_leds_exit(void)
{
  unregister_chrdev(LED_MAJOR, DEVICE_NAME);
}

module_init(s3c24xx_leds_init);
module_exit(s3c24xx_leds_exit);

MODULE_AUTHOR("Nobody");
MODULE_DESCRIPTION("S3C2440 LED Driver");
MODULE_LISCENSE("GPL");

LED属于字符设备,下一篇博文准备总结下字符驱动代码的编写。

PS:在sourceinsight下相应内核源代码建立的工程中编写驱动可能会好点,还因为源码下有s3c2440的led源码驱动,值得参考上述代码为嵌入式完全应用手册中的代码修改可用。

PS1:我的方法是在sourceinsight下编写完成后放入共享文件夹中,我的是D:\SharedDir,在虚拟机中进入/mnt/hgfs/SharedDir中将代码复制到ubuntu目录中,比如我内核源码放在.opt/kernel下,所以讲s3c24xx_leds.c放到kernel下/drivers/char/下,修改此目录下的Makefile(加句 obj+= s3c24xx_leds.o),回到源码目录make modules即可生成相应模块文件,将例程文件和makefile放到/usr/bin中,make后生成二进制可执行文件,打开设备节点文件,传递相关参数实现驱动的调用。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值