开发板自动启动的LED闪烁实验

开发板自动启动的LED闪烁实验

平台S3C2440A  TQ2440开发板  虚拟机安装的ubuntu10.04  linux-2.6.32.60

  这几天一直在思考该找工作了,自己虽然学习linux一段时间了,而且也可以写一写驱动程序,但都是编译成模块的,需要在终端加载模块再运行测试程序才行,如果能让程序自动运行的话 找工作就可以带上自己的板子,演示自己的程序给工程师看,这样把握更大,但是怎么自动启动呢?


因为是第一次尝试开机自动启动程序,我选择最简单的LED闪烁驱动,
第一步当然是编写驱动和测试程序啦,先以模块的方法是用驱动程序和测试程序都OK ,然后是如何自动启动了,驱动程序如下

驱动程序my_gpio.c

#include <linux/device.h> 

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/fs.h>

#include <linux/init.h>

#include <linux/delay.h>

#include <asm/uaccess.h>

#include <asm/irq.h>

#include <asm/io.h>

#include <mach/regs-gpio.h>

#include <mach/hardware.h>

#define DEVICE_NAME "LEDS" 

int MAJOR;

//使用mdev机制自动创建设备节点

static struct class *led_class;

static struct device *led_class_devs;

volatile unsigned long *gpfcon = NULL;

volatile unsigned long *gpfdat = NULL;

static int led_open(struct inode *inode,struct file *file)

  {

  

     *gpfcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(7*2))| (0x3<<(8*2)));

   *gpfcon |= ((0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(7*2))| (0x1<<(8*2)));

    return 0;

  }

static ssize_t led_write(struct file *file,const char __user *buf,size_t count, loff_t *ppos)

{

 int val;

  

copy_from_user(&val, buf, count); // 实现用户空间到内核空间的传递

 printk("valllll= %d \n",val);                                  // copy_to_user();  实现内核空间向用户空间传递数据,,如果完全复制成功,返回值为 0

  if (val == 0)

{

// 点灯

*gpfdat &= ~((1<<5) | (1<<6) |(1<<7) |(1<<8));

printk("LED ON\n");

}

else

{

// 灭灯

*gpfdat |= ((1<<5) | (1<<6) |(1<<7) |(1<<8));

printk("LED OFF\n");

}

  return 0;

/* 这个结构是字符设备驱动程序的核心

 * 当应用程序操作设备文件时所调用的openreadwrite等函数,

 * 最终会调用这个结构中指定的对应函数

 */

static struct file_operations led_fops={

.owner = THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */

.open = led_open,

.write = led_write,

};

static int __init led_init(void)

{

      

   MAJOR = register_chrdev(0,DEVICE_NAME,&led_fops );//注册程序

  //自动创建设备节点

     led_class = class_create(THIS_MODULE,"led");

     led_class_devs = device_create(led_class, NULL,MKDEV(MAJOR,0),NULL,"XYZ");

   

   

gpfcon = (volatile unsigned long *)ioremap(0x56000010, 16);  //物理地址到虚拟地址的映射

gpfdat = gpfcon + 1;

   if(MAJOR < 0)

   {

     printk(DEVICE_NAME "canot register major number");

     return MAJOR;

   }

   

   printk(DEVICE_NAME"init yes \n"); 

   return 0;

}

static void __exit led_exit(void)

{

  unregister_chrdev(MAJOR,DEVICE_NAME);  //注销程序

  //注销设备节点,注销的顺序一般和注册顺序相反

  device_unregister(led_class_devs);

  class_destroy(led_class);

  iounmap(gpfcon);//程序结束释放虚拟地址

  

}

module_init(led_init);

module_exit(led_exit);

MODULE_LICENSE("GPL");

测试程序Ledtest.c如下

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

int main(int argc,char **argv)

 {

   int fd ;

   volatile int val;

   fd = open("/dev/XYZ",O_RDWR);//系统调用open函数已经被内核处理了,在驱动程序中看不出来

   if(fd < 0)

    printf("can't open \n");

   else

    printf("open OK\n");

while(1)

{

    val=1;

   write(fd,&val,4);//这里第三个参数最小为sizeof(val)

   sleep(5);

   val=0;

   write(fd,&val,4);

 

    sleep(5);

}

   return 0;

}

把写好的驱动程序移动到linux-2.6.32.60/drivers/char目录下

 

 

 

并修改linux-2.6.32.60/drivers/char/Kconfig添加如下

 

 

 

 

 

其中config MYLEDS 将在,Makefile里使用 对应里面的CONFIG_MYLEDS

"WANG ZHI GUO LEDS 对应

 

并修改linux-2.6.32.60/drivers/char$目录下Makefile

添加如下一行

obj-$(CONFIG_MYLEDS)            += my_gpio.o

让后重新配置内核 并编译 生成zImage  下载到开发板

然后再把编译好的测试程序通过rz命令上传到开发板,我是上传到自己新建的目录 modules里,然后 vi etc/init.d/rcS  新增modules/Ledtest &   其中&使程序在后台运行,

重启开发板即可

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值