Archive for 八月, 2009

mini2440 LED驱动详解

从最简单的LED驱动入手,彻底细致的分析一遍mini2440的LED驱动。

官方手册上写,mini2440的四个LED与CPU的GPIO相连,LED1, LED2, LED3, LED4分别对应的
是GPB5, GPB6, GPB7, GPB8。那什么是GPIO呢?

GPIO是通用输入输出口的简称,只需要设置相应的CPU寄存器,就可以改变引脚的用途。
控制硬件,其实就是控制对应的寄存器。

四个LED的采用GPBCON寄存器上的4组2bit位来配置对应引脚的状态。4组2bit位的功能都
一样:00表示输入,01表示输出,10为特殊功能,11是保留的。
LED1对应的是GPB5, GPB5使用[11:10]位
LED2对应的是GPB6, GPB6使用[12:13]位
LED3对应的是GPB7, GPB7使用[14:15]位
LED4对应的是GPB8, GPB8使用[16:17]位
驱动需要先设置LED为输出状态,也就是要把对应的GPBX设置为01。

四个LED采用CPBDAT寄存器来对应4个LED的数值状态,GPBDAT5就对应GPB5,GPBDAT6就对
应GPB6,以此类推。手册上写低电平有效,就是说当GPBDAT寄存器位置为0时,LED就发光。

在三星官方的手册S3C2440.pdf中描述的寄存器状态如下:
GPB8 [17:16] 00 = Input 01 = Output
10 = nXDREQ1 11 = Reserved
GPB7 [15:14] 00 = Input 01 = Output
10 = nXDACK1 11 = Reserved
GPB6 [13:12] 00 = Input 01 = Output
10 = nXBREQ 11 = reserved
GPB5 [11:10] 00 = Input 01 = Output
10 = nXBACK 11 = reserved

GPBDAT Bit Description
GPB[10:0] [10:0] When the port is configured as input port, the corresponding
bit is the pin state. When the port is configured as output port, the pin state is the same
as the corresponding bit. When the port is configured as functional pin, the
undefined value will be read.

贴出添加注释后的代码,非常简单的驱动。

#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/irq.h>
#include <mach/regs-gpio.h>
#include <mach/hardware.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/delay.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/string.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <asm/unistd.h>
 
#define DEVICE_NAME "leds" /* /dev目录下的设备名 */
 
/* GPBX */
static unsigned long led_table [] = {
	S3C2410_GPB5,
	S3C2410_GPB6,
	S3C2410_GPB7,
	S3C2410_GPB8,
};
/* GPBX的输出状态 */
static unsigned int led_cfg_table [] = {
	S3C2410_GPB5_OUTP,
	S3C2410_GPB6_OUTP,
	S3C2410_GPB7_OUTP,
	S3C2410_GPB8_OUTP,
};
 
/* 驱动接口函数
* ioctl的内核空间版本和用户控件的版本不同
* 内核版为:
* int (*ioctl)( struct inode *inode, struct file *file, unsigned int
* cmd, unsigned long arg);
* */
static int sbc2440_leds_ioctl(
	struct inode *inode,
	struct file *file,
	unsigned int cmd,
	unsigned long arg)
{
	switch(cmd) {
	case 0:
	case 1:
		if (arg &gt; 4) {
			return -EINVAL; /* Invalid argument,非法参数 */
		}
       /* 设置数据寄存器GPBDAT
		* 低电平有效,用户程序传来的cmd取反
		* */
		s3c2410_gpio_setpin(led_table[arg], !cmd);
		return 0;
	default:
		return -EINVAL;
	}
}
 
/* 接口对象 */
static struct file_operations dev_fops = {
	.owner	=	THIS_MODULE,
	.ioctl	=	sbc2440_leds_ioctl,
};
 
/* 设备对象 */
static struct miscdevice misc = {
	.minor = MISC_DYNAMIC_MINOR, /* 动态设备号 */
	.name = DEVICE_NAME, /* 将在/dev目录生成led设备 */
	.fops = &amp;dev_fops, /* 驱动接口 */
};
 
static int __init dev_init(void)
{
	int ret;
 
	int i;
 
	for (i = 0; i &lt; 4; i++) {
		/*设置GPIO对应的配置寄存器GPIOCON为输出状态*/
		s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i]);
 
		/*设置GPIO对应的数据寄存器GPIODAT为低电平
		 *在模块加载结束后,四个LED应该是全部都是发光状态*/
		s3c2410_gpio_setpin(led_table[i], 0);
	}
 
	ret = misc_register(&amp;misc); /* 注册设备 */
 
	printk (DEVICE_NAME"\tinitialized\n"); /* dmesg */
 
	return ret;
}
 
static void __exit dev_exit(void)
{
	misc_deregister(&amp;misc);                     /* 注销设备 */
}
 
module_init(dev_init); /* 声明加载模块初始化函数 */
module_exit(dev_exit); /* 声明卸载模块清除函数 */
MODULE_LICENSE("GPL"); /* 许可证声明 */
MODULE_AUTHOR("FriendlyARM Inc."); /* 作者信息 */

NFS开发环境建立

晚上在学校里转了好几个卖电脑配件的地方,都没有卖usb转串口线的,继续找,最后在老综合楼复印店找到了,只剩最后一个,35元。既然是最后一个,就肯定讲不了价,我和店家商量如果系统不能识别就退货,他同意了,咬牙拿下。

回到宿舍赶紧接上开发板,然后火速装上minicom,立即测试,太爽了,一切OK。这下就可以NFS开发了。

基本步骤如下,比较容易,后面有时间再细致的补一下笔记。

1.debian上安装nfs-kernel-server,配置好nfs-server

2.按照手册上的方法把环境配出来

3.配置好minicom,用minicom进入板子的shell

4.在板子上挂载笔记本上的开发目录

5.运行程序不用下载到板子了,在minicom中./myapp就可以了

对Linux很亲热,所以很顺手。感慨一下,Linux这个东西真的太猛了,这么多方便的方式给我选择:

a.可以在笔记本上开发,编译链接得到elf之后用U盘拷贝到板子

b.用串口下载到板子

c.用ftp上传到板子

d.用NFS方式,都不用下载到板子了,这样相当于把板子的FLASH扩大了,因为是用笔记本的硬盘当FLASH,这个是最佳方式。

上述3个方式中,windows不装linux虚拟机的情况下可以使用前三个。还是原生使用linux爽啊,以后就用最佳方式NFS了。

misc设备

手册上说LED是misc设备,我在开发板上看/dev/leds,给出的是字符设备,这就奇怪了。我以前只知道有字符设备,块设备,对misc没有一点概念。赶紧google一下:

杂项设备(misc device)
杂项设备也是在嵌入式系统中用得比较多的一种设备驱动。在 Linux 内核的include\linux目录下有Miscdevice.h文件,要把自己定义的misc device从设备定义在这里。其实是因为这些字符设备不符合预先确定的字符设备范畴,所有这些设备采用主编号10,一起归于misc device,其实misc_register就是用主标号10调用register_chrdev()的。

也就是说,misc设备其实也就是特殊的字符设备。

在mini2440上的helloworld

搭建开发环境很容易,跟着手册做,官方是在fedora上搭建的,我在debian上也非常顺利。第一个程序,拍照纪念。

img_2986

Linux目录

今天看到一份英文的,相比以前看的中文资料,可谓是言简意赅。值得收藏。

/bin   basic programs (Programs that are absolutly needed, shell and commands only)
/boot  initialization files (Required to actually boot your computer)
/dev   device files (Describe physical stuff like hard disks and partitions)
/etc   configuration files
/home  users’ home directories
/lib   basic libraries (Required by the basic programs)
/media mount points for removable media
/mnt   mount points (For system admins who need to temporarily mount a filesystem)
/opt   third-party programs
/proc  proc filesystem (Describe processes and status info, not stored on disk)
/root  system administrator’s files
/sbin  basic administration programs (Like bin, but only usable by administators)
/srv   service-specific files
/sys   sys filesystem (Similar to proc, stored in memory based filesytem: tempfs)
/tmp   temporary files (Files not kept between boots, often in tempfs)
/usr   most programs (Another bin, etc, lib, sbin, but for less important files)
/var   varible data (Similar to tmp, but preserved between reboots

/bin   basic programs (Programs that are absolutly needed, shell and commands only)

/boot  initialization files (Required to actually boot your computer)

/dev   device files (Describe physical stuff like hard disks and partitions)

/etc   configuration files

/home  users’ home directories

/lib   basic libraries (Required by the basic programs)

/media mount points for removable media

/mnt   mount points (For system admins who need to temporarily mount a filesystem)

/opt   third-party programs

/proc  proc filesystem (Describe processes and status info, not stored on disk)

/root  system administrator’s files

/sbin  basic administration programs (Like bin, but only usable by administators)

/srv   service-specific files

/sys   sys filesystem (Similar to proc, stored in memory based filesytem: tempfs)

/tmp   temporary files (Files not kept between boots, often in tempfs)

/usr   most programs (Another bin, etc, lib, sbin, but for less important files)

/var   varible data (Similar to tmp, but preserved between reboots