QQ:809205580
Email:zjhsucceed_329@163.com
目 录
1.2修改arch/arm/boot/Makefile 增加一行,方便操作-- 5
2.1 在arch/arm/mach-s3c2440/mach-smdk2440.c,构建DM9000平台设备-- 7
2.2 修改drivers/net/dm9000.c第44行加入如下代码-- 8
2.4 重新编译内核并设置u-boot启动参数,通过NFS挂载根文件系统-- 9
3.1 修改arch/arm/plat-s3c24xx/common-smdk.c中的LED platform_device- 9
4.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中构建按键platform device- 12
4.3 重新编译内核,下载到开发板重启,内核输出如下信息-- 13
5.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中修改LCD参数-- 16
5.3重新编译内核,下载到开发板运行,将看到企鹅log- 17
5.4 解决10分钟后黑屏:修改drivers/char/vt.c- 17
5.5关闭光标:修改/drivers/video/console/softcursor.c- 17
6.1在arch/arm/mach-s3c2440/mach-smdk2440.c构造触摸屏平台设备数据-- 18
6.2 添加触摸屏和ADC平台设备列表,ADC一定要在TS前面-- 18
6.4 5. 修改arch/arm/plat-s3c24xx/Kconfig- 19
6.6重新编译内核,下载到开发板运行,内核输出如下信息-- 19
7.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中构建HWMON设备平台数据-- 20
7.2 在smdk2440_machine_init函数中设置hwmon平台数据-- 20
7.3 在smdk2440_devices[]数组中加入-- 20
7.5修改drivers/hwmon/s3c-hwmon.c,添加头文件-- 21
7.6 屏蔽drivers/hwmon/s3c-hwmon.c:238、256行-- 21
8.1在arch/arm/mach-s3c2440/mach-smdk2440.c中构造SD卡平台设备数据-- 22
8.3 在arch/arm/mach-s3c2440/mach-smdk2440.c smdk2440_devices 结构体数组中加入SD卡平台设备 22
9.1 SMDK2440 开发板已经添加了USB主控制器平台设备s3c2410-ohci23
9.4 实现U盘自动挂载:修改rootfs/etc/mdev.conf,添加如下内容-- 24
11.1到http://www.lavrsen.dk/foswiki/bin/view/Motion/WebHome下载源码-- 25
11.3拷贝motion-3.2.12/install/bin/motion到开发板根文件系统bin目录-- 26
11.4拷贝配置文件motion-3.2.12/install/etc/motion-dist.conf到开发板根文件系统etc/motion.conf 26
12.1在arch/arm/mach-s3c2440/mach-smdk2440.c构造pwm-beeper平台设备-- 27
12.2在smdk2440_devices中添加s3c_device_timer和pwm_beeper_device- 27
12.3在arch/arm/plat-s3c24xx/common-smdk.c中的smdk_machine_init中设置蜂鸣器IO口为TOUT0 27
12.4修改arch/arm/plat-samsung/pwm.c中的pwm_config函数-- 27
12.6重新编译,下载到开发板运行,内核输出如下信息,同时蜂鸣器响一声-- 28
13.1 在arch/arm/mach-s3c2440/mach-smdk2440.c的smdk2440_devices[]结构体数组添加rtc平台设备 29
13.3重新编译内核并下载到开发板运行,内核输出如下信息-- 29
14.1在arch/arm/mach-s3c2440/mach-smdk2440.c已经添加了wdt平台设备-- 29
15.1在arch/arm/mach-s3c2440/mach-smdk2440.c中构造1-wire平台设备-- 30
15.2配置内核支持w1-gpioMasters和Slaves- 31
16.1 arch/arm/mach-s3c2440/mach-smdk2440.c中已经添加了I2C平台设备-- 32
16.2.1 使用i2c-dev.c产生的字符设备节点/dev/i2c-0- 32
16.2.2 使用at24.c产生sys/bus/i2c/devices/i2c-0/0-0050/eeprom,直接操作eeprom-- 34
17.2 修改NandFlash时序参数(参考NandFlash芯片手册)-- 37
18.1到http://www.aleph1.co.uk/gitweb?p=yaffs2.git;a=summary下载源码-- 38
1 内核配制和编译
1.1修改顶层Makefile
ARCH ?= arm
CROSS_COMPILE ?= arm-linux- 根据自己的环境修改交叉编译器前缀
我的交叉编译器版本为4.4.3
1.2修改arch/arm/boot/Makefile 增加一行,方便操作
$(obj)/uImage: $(obj)/zImage FORCE
$(callif_changed,uimage)
@echo ' Image $@ is ready'
cp $@ /home/tftpboot 根据自己的ftp服务器目录修改
1.3匹配机器码
启动u-boot执行bdinfo将输出开发板的相关信息,包括机器码
TQ2440 # bd
arch_number= 0x0000016A 机器码362
boot_params =0x30000100
DRAM bank = 0x00000000
-> start = 0x30000000
-> size = 0x04000000
ethaddr = 00:01:02:03:04:05
ip_addr = 192.168.1.100
baudrate = 115200 bps
TLB addr = 0x33FF0000
relocaddr = 0x33F40000
reloc off = 0x33F40000
irq_sp = 0x33B2FF68
sp start = 0x33B2FF58
FB base = 0x00000000
TQ2440 #
新版u-boot(u-boot-2012)可以设置环境变量machid来更改机器码
TQ2440 # setmachid 0x16A
内核机器码:arch/arm/mach-s3c2440/mach-smdk2440.c
MACHINE_START(S3C2440, "SMDK2440")
其中的S3C2440即为机器类型
再查看arch/arm/tools/mach-types 第379行即为S3C2440所对应的机器码362,必须和u-boot的机器码相同,否则没法启动内核
1.4修改系统时钟
arch/arm/mach-s3c2440/mach-smdk2440.c 我们的开发板使用12MHZ
s3c24xx_init_clocks(12000000);
1.5执行默认配制
root@zjh:/home/work/linux-2.6.36.4#make s3c2410_defconfig
1.6配制内核
root@zjh:/home/work/linux-2.6.36.4#make menuconfig
Kernel Features --->
[*] Use the ARM EABI to compile the kernel
[*] Allow old ABI binaries torun with this kernel (EXPERIMENTAL)
注:使用4.X.X 版本的交叉编译器一定要选中以上两项,否则会出现Kernel panic - not syncing:Attempted to kill init! 这样的错误以致没法启动内核
System Type --->
S3C2440 and S3C2442 Machines --->
[*]SMDK2440
[*]SMDK2440 with S3C2440 CPU module
只选中这两项即可,其他的Machine都取消
1.7编译内核
root@zjh:/home/work/linux-2.6.36.4#make uImage
……
Kernel: arch/arm/boot/zImage is ready
UIMAGE arch/arm/boot/uImage
Image Name: Linux-2.6.36.4
Created: SatJul 13 22:53:31 2013
Image Type: ARM Linux Kernel Image (uncompressed)
Data Size: 2280396 Bytes = 2226.95 kB = 2.17 MB
Load Address: 0x30008000
Entry Point: 0x30008000
Image arch/arm/boot/uImage is ready
cp arch/arm/boot/uImage/home/tftpboot
1.8启动u-boot执行如下操作
TQ2440 # tftp 32000000 uImage
dm9000 i/o: 0x20000000, id:0x90000a46
DM9000: running in 16 bit mode
MAC: 00:11:22:33:44:aa
operating at 100M full duplex mode
Using dm9000 device
TFTP from server 192.168.1.100; ourIP address is 192.168.1.250
Filename 'uImage'.
Load address: 0x32000000
Loading: T#################################################################
#################################################################
##########################
328.1 KiB/s
done
Bytes transferred = 2280460 (22cc0chex)
TQ2440 # bootm 32000000
## Booting kernel from Legacy Imageat 32000000 ...
Image Name: Linux-2.6.36.4
Created: 2013-07-13 14:53:31 UTC
Image Type: ARM Linux KernelImage (uncompressed)
Data Size: 2280396 Bytes = 2.2MiB
Load Address: 30008000
Entry Point: 30008000
Verifying Checksum ... OK
Loading Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, bootingthe kernel.
Linux version 2.6.36.4 (root@zjh)(gcc version 4.4.3 (ctng-1.6.1) ) #12 Sat Jul 13 11:35:56 CST 2013
CPU: ARM920T [41129200] revision 0(ARMv4T), cr=c0007177
CPU: VIVT data cache, VIVTinstruction cache
Machine: SMDK2440
Memory policy: ECC disabled, Datacache writeback
CPU S3C2440A (id 0x32440001)
2 DM91000网卡驱动
2.1 在arch/arm/mach-s3c2440/mach-smdk2440.c,构建DM9000平台设备
#include <linux/dm9000.h>
#define MACH_TQ2440_DM9K_BASE (S3C2410_CS4 + 0x300)
/* support DM9000 */
static struct resource TQ2440_dm9k_resource[] = {
[0] = {
.start =MACH_TQ2440_DM9K_BASE,
.end = MACH_TQ2440_DM9K_BASE + 3,
.flags =IORESOURCE_MEM
},
[1] = {
.start =MACH_TQ2440_DM9K_BASE + 4,
.end = MACH_TQ2440_DM9K_BASE + 7,
.flags =IORESOURCE_MEM
},
[2] = {
.start =IRQ_EINT7,
.end = IRQ_EINT7,
.flags = IORESOURCE_IRQ |IORESOURCE_IRQ_HIGHEDGE,
}
};
/*
* The DM9000 has noeeprom, and set it's MAC address
*/
static struct dm9000_plat_data TQ2440_dm9k_pdata = {
.flags = (DM9000_PLATF_16BITONLY |DM9000_PLATF_NO_EEPROM),
.dev_addr = "\x00\x11\x22\x33\x44\x66",
};
static struct platform_device TQ2440_device_eth = {
.name = "dm9000",
.id = -1,
.num_resources = ARRAY_SIZE(TQ2440_dm9k_resource),
.resource = TQ2440_dm9k_resource,
.dev = {
.platform_data = &TQ2440_dm9k_pdata,
},
};
smdk2440_devices[]结构体数组添加如下代码
&TQ2440_device_eth
2.2 修改drivers/net/dm9000.c第44行加入如下代码
#include"dm9000.h"
#ifdefined(CONFIG_ARCH_S3C2440)
#include<mach/regs-mem.h>
#endif
第1375行加入如下代码
u32 id_val;
#ifdefined(CONFIG_ARCH_S3C2440)
unsigned int oldval_bwscon = *(volatileunsigned int *)S3C2410_BWSCON;
unsigned int oldval_bankcon4 =*(volatile unsigned int *)S3C2410_BANKCON4;
#endif
/* Init network device */
第1387行加入如下代码
dev_dbg(&pdev->dev,"dm9000_probe()\n");
#ifdefined(CONFIG_ARCH_S3C2440)
/* 设置Bank4:总线宽度为16,使能nWAIT */
*((volatile unsigned int *)S3C2410_BWSCON) =(oldval_bwscon & ~(3<<16)) |
S3C2410_BWSCON_DW4_16| S3C2410_BWSCON_WS4 | S3C2410_BWSCON_ST4;
/* 设置Bandk4的时间参数 */
*((volatile unsigned int *)S3C2410_BANKCON4)= 0x1f7c;
#endif
/* setup board info structure */
第1615行
out:
/* 恢复寄存器原来的值 */
#ifdefined(CONFIG_ARCH_S3C2440)
*(volatile unsigned int *)S3C2410_BWSCON =oldval_bwscon;
*(volatile unsigned int *)S3C2410_BANKCON4 =oldval_bankcon4;
#endif
2.3 配置内核支持DM9000
root@zjh:/home/work/linux-2.6.36.4# make menuconfig
[*] Networking support --->
Networking options --->
<*> Packet socket
<*> Unix domain socket
[*] TCP/IP networking
[*] IP: multicasting
[*] IP: kernel levelautoconfiguration
[*] IP: BOOTP support
DeviceDrivers --->
[*] Networkdevice support --->
[*] Ethernet (10 or 100Mbit) --->
<*> DM9000 support
File systems --->
[*] Network FileSystems (NEW) --->
<*> NFS client support
[*] NFS client support for NFS version 3 (NEW)
[*] NFS client support for the NFSv3 ACLprotocol extension
[*] Root file system on NFS
2.4 重新编译内核并设置u-boot启动参数,通过NFS挂载根文件系统
TQ2440 # set bootargs root=/dev/nfs nfsroot=192.168.1.8:/home/work/rootfsip=192.168.1.100 init=/linuxrc console=ttySAC0,115200
TQ2440 # save
2.5 下载内核并启动
TQ2440 # tftp 32000000 uImage
TQ2440 # bootm 32000000
………………
[root@tq2440 /]#
3 LED子系统(LED)
内核自带的LED驱动在drivers/leds/leds-s3c24xx.c
3.1 修改arch/arm/plat-s3c24xx/common-smdk.c中的LED platform_device
/* LED devices */
static struct s3c24xx_led_platdatasmdk_pdata_led1 = {
.gpio = S3C2410_GPB(5),
.flags = S3C24XX_LEDF_ACTLOW |S3C24XX_LEDF_TRISTATE,
.name = "led1",
.def_trigger = "timer",
};
static struct s3c24xx_led_platdatasmdk_pdata_led2 = {
.gpio = S3C2410_GPB(6),
.flags = S3C24XX_LEDF_ACTLOW |S3C24XX_LEDF_TRISTATE,
.name = "led2",
.def_trigger = "nand-disk",
};
static struct s3c24xx_led_platdatasmdk_pdata_led3 = {
.gpio = S3C2410_GPB(7),
.flags = S3C24XX_LEDF_ACTLOW |S3C24XX_LEDF_TRISTATE,
.name = "led3",
};
static struct s3c24xx_led_platdatasmdk_pdata_led4 = {
.gpio = S3C2410_GPB(8),
.flags = S3C24XX_LEDF_ACTLOW |S3C24XX_LEDF_TRISTATE,
.name = "led4",
};
static struct platform_device smdk_led1 = {
.name = "s3c24xx_led",
.id = 0,
.dev = {
.platform_data= &smdk_pdata_led1,
},
};
static struct platform_device smdk_led2 = {
.name = "s3c24xx_led",
.id = 1,
.dev = {
.platform_data= &smdk_pdata_led2,
},
};
static struct platform_device smdk_led3 = {
.name = "s3c24xx_led",
.id = 2,
.dev = {
.platform_data= &smdk_pdata_led3,
},
};
static struct platform_device smdk_led4 = {
.name = "s3c24xx_led",
.id = 3,
.dev = {
.platform_data= &smdk_pdata_led4,
},
};
/* devices we initialise */
static struct platform_device __initdata*smdk_devs[] = {
&s3c_device_nand,
&smdk_led1,
&smdk_led2,
&smdk_led3,
&smdk_led4,
};
/*Configure the LEDs (even if we have no LED support)*/
s3c_gpio_cfgpin(S3C2410_GPB(5), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPB(6), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPB(7), S3C2410_GPIO_OUTPUT);
s3c_gpio_cfgpin(S3C2410_GPB(8), S3C2410_GPIO_OUTPUT);
s3c2410_gpio_setpin(S3C2410_GPB(5), 1);
s3c2410_gpio_setpin(S3C2410_GPB(6), 1);
s3c2410_gpio_setpin(S3C2410_GPB(7), 1);
s3c2410_gpio_setpin(S3C2410_GPB(8), 1);
3.2 配置内核
Device Drivers --->
-*-LED Support --->
<*> LED Class Support
<*> LED Support for Samsung S3C24XX GPIO LEDs
3.4 重新编译内核,下载到开发板运行
[root@tq2440 /]# ls /sys/class/leds/
led1led2 led3 led4
[root@tq2440 /]# ls/sys/class/leds/led1/
brightness max_brightness subsystem uevent
device power trigger
[root@tq2440 /]# echo 1 >/sys/class/leds/led1/brightness 点亮LED1
[root@tq2440 /]# echo 0 >/sys/class/leds/led1/brightness 熄灭LED1
4 输入子系统(按键)
4.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中构建按键platformdevice
#include<linux/gpio_keys.h>
#include<linux/input.h>
staticstruct gpio_keys_button tq2440_buttons[] = {
{
.gpio = S3C2410_GPF(1),
.code = KEY_UP,
.desc = "Up",
.active_low = 1,
.wakeup = 0,
},
{
.gpio = S3C2410_GPF(4),
.code = KEY_DOWN,
.desc = "Down",
.active_low = 1,
.wakeup = 0,
},
{
.gpio = S3C2410_GPF(2),
.code = KEY_LEFT,
.desc = "Left",
.active_low = 1,
.wakeup = 0,
},
{
.gpio = S3C2410_GPF(0),
.code = KEY_RIGHT,
.desc = "Right",
.active_low = 1,
.wakeup = 0,
}
};
staticstruct gpio_keys_platform_data tq2440_button_data = {
.buttons= tq2440_buttons,
.nbuttons= ARRAY_SIZE(tq2440_buttons),
};
staticstruct platform_device tq2440_device_button= {
.name ="gpio-keys",
.id =-1,
.dev ={
.platform_data=&tq2440_button_data,
},
};
在smdk2440_devices[]中加入platform设备
&tq2440_device_button,
4.2配置内核
DeviceDrivers --->
Input devicesupport --->
[*] Keyboards--->
<*> GPIO Buttons
4.3 重新编译内核,下载到开发板重启,内核输出如下信息
input: gpio-keys as/class/input/input0
当输入子系统多了,可通过如下命令查看哪个event对应哪个驱动
[root@tq2440 /]# cat/proc/bus/input/devices
I: Bus=0019 Vendor=0001 Product=0001Version=0100
N: Name="gpio-keys"
P: Phys=gpio-keys/input0
S: Sysfs=/class/input/input0
U: Uniq=
H: Handlers=kbd event0
B: EV=3
B: KEY=1680 0 0 0
I: Bus=0019 Vendor=dead Product=beefVersion=0102
N: Name="S3C24XXTouchScreen"
P: Phys=
S: Sysfs=/class/input/input1
U: Uniq=
H: Handlers=mouse0 event1
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=3
I: Bus=0019 Vendor=001f Product=0001Version=0100
N: Name="pwm-beeper"
P: Phys=pwm/input0
S: Sysfs=/class/input/input2
U: Uniq=
H: Handlers=kbd event2
B: EV=40001
B: SND=6
4.4 用户空间测试程序
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <linux/input.h>
#include <sys/fcntl.h>
#include <string.h>
char *key_code_to_a(unsigned shortcode)
{
staticchar str[20];
switch(code)
{
caseKEY_UP:
strcpy(str,"KEY_UP");
break;
caseKEY_DOWN:
strcpy(str,"KEY_DOWN");
break;
caseKEY_LEFT:
strcpy(str,"KEY_LEFT");
break;
caseKEY_RIGHT:
strcpy(str,"KEY_RIGHT");
break;
default:
returnNULL;
}
returnstr;
}
int main(int argc, char *argv[])
{
intfd = -1;
size_trb;
intversion;
charname[20];
structinput_event ev;
if((fd = open("/dev/event0", O_RDONLY)) < 0)
{
perror("openerror");
exit(1);
}
if(ioctl(fd, EVIOCGNAME(sizeof(name)-1), name) < 0)
{
perror("getnameerror");
exit(1);
}
printf("name=%s\n",name);
if(ioctl(fd, EVIOCGVERSION, &version) < 0)
{
perror("getversionerror");
exit(1);
}
printf("version=0x%x\n",version);
while(1)
{
rb= read(fd, &ev, sizeof(struct input_event));
if(rb < (int)sizeof(struct input_event))
{
perror("readerror");
exit(1);
}
if(EV_KEY == ev.type)
{
if(1 == ev.value)
printf("%sis pressed\n", key_code_to_a(ev.code));
else
printf("%sis releassed\n", key_code_to_a(ev.code));
}
}
close(fd);
return0;
}
交叉编译,在开发板执行
[root@tq2440 /]# ./key
name=gpio-keys
version=0x10000
KEY_DOWN is pressed
KEY_DOWN is releassed
KEY_UP is pressed
KEY_UP is releassed
KEY_LEFT is pressed
KEY_LEFT is releassed
5 LCD驱动
5.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中修改LCD参数
.width = 480,
.height =272,
.pixclock =(1000000000000LL)/9000000,
.xres =480,
.yres =272,
.bpp =16,
.left_margin = 2,
.right_margin = 2,
.hsync_len = 41,
.upper_margin = 2,
.lower_margin = 2,
.vsync_len = 10,
将下面这行注释掉,否则显示会出问题
//.lpcsel =((0xCE6) & ~7) | 1<<4, /* lpc3600 control register */
注:pixclock = 10^12/DOTCLK=10^12/(fframe x(X +HBP + HFP+HSPW)x(Y + VBP + VFP+VSPW))
(单位:皮秒)
由LCD手册查得DOTCLk=9MHZ
在arch/arm/mach-s3c2440/mach-smdk2440.c的smdk2440_devices[]结构体数组中已经有lcd设备
&s3c_device_lcd,
5.2配置内核
DeviceDrivers --->
Graphicssupport --->
<*> Supportfor frame buffer devices --->
<*>S3C2410 LCD framebuffer support
[*] Bootup logo --->
[ ]Standard black and white Linux logo
[ ]Standard 16-color Linux logo
[*]Standard 224-color Linux logo (NEW)
5.3重新编译内核,下载到开发板运行,将看到企鹅log
5.4 解决10分钟后黑屏:修改drivers/char/vt.c
可修改static int blankinterval = 10*60;
默认为10分钟后LCD背光就自动关闭,当发生中断就会开启,改为0,LCD就常亮。可修改static int blankinterval = 10*60;
默认为10分钟后LCD背光就自动关闭,当发生中断就会开启,改为0,LCD就常亮。
5.5关闭光标:修改/drivers/video/console/softcursor.c
intsoft_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
#if 0
struct fbcon_ops *ops =info->fbcon_par;
unsigned int scan_align =info->pixmap.scan_align - 1;
unsigned int buf_align =info->pixmap.buf_align - 1;
unsigned int i, size, dsize, s_pitch,d_pitch;
struct fb_image *image;
u8 *src, *dst;
if (info->state !=FBINFO_STATE_RUNNING)
return 0;
s_pitch = (cursor->image.width + 7)>> 3;
dsize = s_pitch *cursor->image.height;
if (dsize + sizeof(struct fb_image) !=ops->cursor_size) {
if (ops->cursor_src != NULL)
kfree(ops->cursor_src);
ops->cursor_size = dsize +sizeof(struct fb_image);
ops->cursor_src =kmalloc(ops->cursor_size, GFP_ATOMIC);
if (!ops->cursor_src) {
ops->cursor_size = 0;
return -ENOMEM;
}
}
src = ops->cursor_src + sizeof(structfb_image);
image = (struct fb_image*)ops->cursor_src;
*image = cursor->image;
d_pitch = (s_pitch + scan_align) &~scan_align;
size = d_pitch * image->height +buf_align;
size &= ~buf_align;
dst = fb_get_buffer_offset(info,&info->pixmap, size);
if (cursor->enable) {
switch (cursor->rop) {
case ROP_XOR:
for (i = 0; i < dsize;i++)
src[i] =image->data[i] ^ cursor->mask[i];
break;
case ROP_COPY:
default:
for(i = 0; i < dsize; i++)
src[i] =image->data[i] & cursor->mask[i];
break;
}
} else
memcpy(src, image->data,dsize);
fb_pad_aligned_buffer(dst, d_pitch, src,s_pitch, image->height);
image->data = dst;
info->fbops->fb_imageblit(info, image);
#endif
return 0;
}
6 触摸屏驱动
6.1在arch/arm/mach-s3c2440/mach-smdk2440.c构造触摸屏平台设备数据
#include<plat/ts.h>
staticstruct s3c2410_ts_mach_info hard_s3c2410ts_info = {
.delay = 0xffff, //保存ADC的延迟时间
.oversampling_shift = 2, //保存采样次数log2值
.cfg_gpio = s3c24xx_ts_cfg_gpio, //用于设置gpio
};
6.2 添加触摸屏和ADC平台设备列表,ADC一定要在TS前面
&s3c_device_adc,
&s3c_device_ts,
6.3设置触摸屏平台设备数据
static void__init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
s3c24xx_mci_set_platdata(&sd_cfg);
s3c24xx_ts_set_platdata(&hard_s3c2410ts_info);
platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
6.4 5. 修改arch/arm/plat-s3c24xx/Kconfig
configS3C2410_SETUP_TS
bool "Touchscreensetup"
6.5配置内核
System Type --->
[*] Touchscreensetup
Device Drivers --->
Input device support --->
[*]Touchscreens --->
<*>Samsung S3C2410/generic touchscreen input driver
6.6重新编译内核,下载到开发板运行,内核输出如下信息
samsung-tss3c2440-ts: driver attached, registering input device
input: S3C24XXTouchScreen as /class/input/input1
6.7用户空间测试程序
#include<sys/types.h>
#include<sys/stat.h>
#include<stdio.h>
#include<fcntl.h>
#include<signal.h>
#include<unistd.h>
#include<linux/input.h>
#include<stdlib.h>
#include<string.h>
int fd;
struct input_eventevent;
voidinput_handle(int signum)
{
if (read(fd, &event, sizeof(structinput_event))< 0) {
perror("read");
}
printf("tv_sec:%d\n",event.time.tv_sec);
printf("tv_usec:%d\n",event.time.tv_usec);
printf("type:%d\n",event.type);
printf("code:%d\n",event.code);
printf("value:%d\n",event.value);
}
int main()
{
int oflags;
fd = open("/dev/event1",O_RDWR, S_IRUSR|S_IWUSR);
if (fd != -1) {
signal(SIGIO, input_handle);
fcntl(fd, F_SETOWN, getpid());
oflags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, oflags|FASYNC);
while (1) {
sleep(100);
}
}
else
printf("err\n");
}
7 ADC驱动
7.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中构建HWMON设备平台数据
#include <plat/hwmon.h>
/* ADC */
struct s3c_hwmon_chcfg ch2 = {
.name= "adc-ch2",
.mult= 3300,
.div =1024,
};
static struct s3c_hwmon_pdata tq2440_hwmon_pdata= {
.in[2]= &ch2,
};
TQ2440开发板用到了第2通道
7.2 在smdk2440_machine_init函数中设置hwmon平台数据
s3c_hwmon_set_platdata(&tq2440_hwmon_pdata);
7.3 在smdk2440_devices[]数组中加入
&s3c_device_adc,
&s3c_device_hwmon,
其中s3c_device_adc是在arch/arm/plat-s3c24xx/devs.c文件中实现的,s3c_device_hwmon是在arch/arm/plat-samsung/dev-hwmon.c文件中实现的
7.4 5. 修改arch/arm/plat-samsung/目录下的Kconfig文件:在S3C_DEV_HWMON选项下加入default y,这样是为了编译dev-hwmon.c这个文件
configS3C_DEV_HWMON
bool "S3C_DEV_HWMON"
default y
help
Compile in platform device definitions for HWMON
7.5修改drivers/hwmon/s3c-hwmon.c,添加头文件
#include <linux/semaphore.h>
7.6 屏蔽drivers/hwmon/s3c-hwmon.c:238、256行
//attr->dev_attr.attr.owner = THIS_MODULE;
//attr->dev_attr.attr.owner = THIS_MODULE;
7.7配置内核
System Type --->
-*- ADC common driver support
[*] S3C_DEV_HWMON
Device Drivers --->
<*>Hardware Monitoring support --->
<*> S3C24XX/S3C64XX Inbuilt ADC
[*] Include raw channel attributes in sysfs
7.8重新编译,下载到开发板运行
[root@tq2440 /]# ls /sys/class/hwmon/hwmon0/device/
adc0_rawadc4_raw bus in2_label uevent
adc1_rawadc5_raw driver modalias
adc2_rawadc6_raw hwmon:hwmon0 power
adc3_rawadc7_raw in2_input subsystem
这个目录下有8个名为adcx_raw的文件,分别对应S3C2440的8路ADC
cat /sys/class/hwmon/hwmon0/device/adc2_raw查看通道的AD转换的原始值,in2_label查看ADC通道2的标题,in2_input查看ADC2的转换真是电压值(mV)
查看arch\arm\plat-samsung\include\plat\hwmon.h
/**
*s3c_hwmon_chcfg - channel configuration
* @name: Thename to give this channel.
* @mult:Multiply the ADC value read by this.
* @div: Dividethe value from the ADC by this.
*
* The valueread from the ADC is converted to a value that
* hwmon expects (mV) by result = (value_read * @mult) / @div.
*/
struct s3c_hwmon_chcfg {
const char *name;
unsigned int mult;
unsigned int div;
};
[root@tq2440 /]# cat/sys/class/hwmon/hwmon0/device/in2_label
adc-ch2
[root@tq2440 /]# cat/sys/class/hwmon/hwmon0/device/in2_input
148
8 SD卡驱动
8.1在arch/arm/mach-s3c2440/mach-smdk2440.c中构造SD卡平台设备数据
#include<linux/mmc/host.h>
#include<plat/mci.h>
staticstruct s3c24xx_mci_pdata sd_cfg = {
.no_wprotect = true,
.gpio_detect = S3C2410_GPG(8),
.set_power = NULL,
.ocr_avail = MMC_VDD_32_33 |MMC_VDD_33_34,
};
8.2设置SD卡平台设备数据
static void__init smdk2440_machine_init(void)
{
s3c24xx_fb_set_platdata(&smdk2440_fb_info);
s3c_i2c0_set_platdata(NULL);
s3c24xx_mci_set_platdata(&sd_cfg);
platform_add_devices(smdk2440_devices,ARRAY_SIZE(smdk2440_devices));
smdk_machine_init();
}
8.3 在arch/arm/mach-s3c2440/mach-smdk2440.c smdk2440_devices 结构体数组中加入SD卡平台设备
&s3c_device_sdi,
8.4 配置内核支持SD卡
DeviceDrivers --->
<*>MMC/SD/SDIO card support --->
<*> MMC block device driver
[*] Use bounce buffer for simple hosts
<*> Samsung S3C SD/MMC Card Interface support
8.5重新编译内核,下载到开发板运行
插入SD卡
[root@tq2440 /]# s3c-sdi s3c2440-sdi: running at 0kHz(requested: 0kHz).
s3c-sdi s3c2440-sdi: running at 400kHz (requested:400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz (requested:400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz (requested:400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz (requested:400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz (requested:400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz (requested:400kHz).
s3c-sdi s3c2440-sdi: running at 400kHz (requested:400kHz).
s3c-sdi s3c2440-sdi: running at 25000kHz (requested:25000kHz).
s3c-sdi s3c2440-sdi: running at 25000kHz (requested:25000kHz).
mmc0: new SDHC card at address e624
mmcblk0: mmc0:e624 SU04G 3.69 GiB
mmcblk0: p1
[root@tq2440 /]# mount /dev/mmcblk0p1 /mnt/ 手动挂载SD卡
[root@tq2440 /]# ls /mnt/ 列出SD内容
z.txt
[root@tq2440 /]# umount /mnt/ 卸载SD卡
8.6 实现自动挂载SD卡
在根文件系统根目录下创建用于挂载SD卡的目录
root@zjh:/home/rootfs# mkdir sddisk
在etc/下创建配置文件mdev.conf
root@zjh:/home/work/rootfs# vi etc/mdev.conf
内容如下
mmcblk[0-9]*p[0-9] 0:0 0660 @(mount -t vfat /dev/$MDEV /sddisk)
mmcblk[0-9]*p[0-9] 0:0 0660 $(umount/sddisk)
更多mdev.conf的设置可参考busybox的docs/mdev.txt文件
9 USB主控制器驱动
9.1 SMDK2440 开发板已经添加了USB 主控制器平台设备s3c2410-ohci
static structplatform_device *smdk2440_devices[] __initdata = {
&s3c_device_ohci,
&s3c_device_lcd,
&s3c_device_wdt,
&s3c_device_i2c0,
&s3c_device_iis,
&s3c_device_dm9000,
&s3c_device_rtc,
&s3c_device_sdi,
};
9.2 配置内核
因为优盘用到了SCSI命令,所以首先增加 SCSI支持:
Device Drivers --->
SCSI devicesupport --->
<*> SCSIdisk support
添加U盘支持
[*] USB support --->
<*>USB Mass Storage support
9.3重新编译内核,下载到开发板运行
插入U盘
[root@tq2440 /]# usb 1-1: new full speedUSB device using s3c2410-ohci and address 3
scsi1 : usb-storage 1-1:1.0
scsi 1:0:0:0: Direct-Access Kingston DT 101 G2 PMAP PQ: 0 ANSI: 0 CCS
sd 1:0:0:0: Attached scsi generic sg0 type 0
sd 1:0:0:0: [sda] 15646720 512-byte logical blocks:(8.01 GB/7.46 GiB)
sd 1:0:0:0: [sda] Write Protect is off
sd 1:0:0:0: [sda] Assuming drive cache: write through
sd 1:0:0:0: [sda] Assuming drive cache: write through
sda: sda1
sd 1:0:0:0: [sda] Assuming drive cache: write through
sd 1:0:0:0: [sda] Attached SCSI removable disk
[root@tq2440 /]# mount /dev/sda1 /mnt/ 手动挂载U盘
[root@tq2440 /]# ls /mnt/ 列出U盘内容
?? ?????????.doc Image2Lcd.rar
?? ????.txt ?????????20110101.pdf TQ2440_Test_20100607.rar
[root@tq2440 /]# umount /mnt/ 卸载U盘
9.4 实现U盘自动挂载:修改rootfs/etc/mdev.conf,添加如下内容
sd[a-z]*[0-9] 0:00660 @(mount -t vfat/dev/$MDEV /udisk)
sd[a-z]*[0-9]0:0 0660 $(umount /udisk)
10 USB摄像头驱动
10.1直接配置内核
DeviceDrivers --->
<*>Multimedia support --->
<*> Video For Linux
[*] Enable Video For Linux API 1 (DEPRECATED)(NEW)
[*] Video capture adapters (NEW) --->
[*] V4L USB devices (NEW) --->
<*> USB Video Class (UVC)
[*] UVC input events device support (NEW)
<*> GSPCA based webcams --->
在GSPCA based webcams中选中你要的驱动或全选
10.2重新编译内核,下载到开发板运行
插上USB摄像头
[root@tq2440 /]# usb 1-1: new full speedUSB device using s3c2410-ohci and address 3
uvcvideo: Found UVC 1.00 device Vimicro USBCamera (Altair) (0ac8:3450)
input: Vimicro USB Camera (Altair) as/class/input/input3
[root@tq2440 /]# ll /dev/video0
crw-rw---- 1root root 81,0 Jan 1 00:00 /dev/video0
11 移植开源的移动图像监控软件motion
11.1到http://www.lavrsen.dk/foswiki/bin/view/Motion/WebHome下载源码
11.2解压,配置,编译,安装
root@zjh:/home/work# tar -zxvfmotion-3.2.12.tar.gz
root@zjh:/home/work# tar -zxvfmotion-3.2.12.tar.gz
root@zjh:/home/work/motion-3.2.12#./configure --prefix=`pwd`/install --host=arm-linux --without-ffmpeg
……
*******************************
Configure status
motion 3.2.12
*******************************
OS : Linux
pthread Support: Yes
jpeg Support: Yes
V4L included: Yes
V4L2 supported: Yes
FFmpeg Support: No
MYSQL Support: No
PostgreSQL Support: No
CFLAGS: -g -O2 -D_REENTRANT -DMOTION_V4L2-DTYPE_32BIT="int" -DHAVE_BSWAP
LIBS: -lm -lpthread -ljpeg
LDFLAGS:
Install prefix: /home/work/motion-3.2.12/install
make
make install
11.3拷贝motion-3.2.12/install/bin/motion到开发板根文件系统bin目录
11.4拷贝配置文件motion-3.2.12/install/etc/motion-dist.conf到开发板根文件系统etc/motion.conf
11.5修改配置文件etc/motion.conf
daemon off
videodevice /dev/video0 #设置加载usb摄像头的设备文件
v4l2_palette 6 #设置摄像头的像素格式(根据你的摄像头设置)
locate on #图像中有运动对象时,是否画框将对象框住
width 320 #指定采集图像的宽度,依赖于摄像头
height 240 #指定采集图像的高度,依赖于摄像头
framerate 5 #每秒采集帧数
quality 75 #图像压缩质量
threshold 1500 #比较闸值
gap 2 #过多少秒物体没动表示物体结束运动
snapshot_interval 0 #设置自动采集图片的周期,0不自动采集
target_dir /motion/save #设置视频和图片保存位置
webcam_localhost off #设置为off可通过浏览器访问
on_event_start echo 1>/sys/class/leds/led1/brightness #当探测到图像运动时需要执行的命令或脚本
on_event_end echo 0>/sys/class/leds/led1/brightness #当图像结束运动时需要执行的命令或脚本
control_port 8080 #控制端口
webcam_port 8081 #http服务器监听端口
11.6插上USB摄像头
[root@tq2440 /]# usb 1-1: new fullspeed USB device using s3c2410-ohci and address 2
uvcvideo: Found UVC 1.00 deviceUSB2.0 Camera (1e4e:0102)
input: USB2.0 Camera as/class/input/input2
[root@tq2440 /]# ls /dev/video0
/dev/video0
运行motion
[root@tq2440 /]# motion -c/etc/motion.conf
打开浏览器,输入地址http://192.168.1.250:8081/
12 PWM-BEEPER驱动
12.1在arch/arm/mach-s3c2440/mach-smdk2440.c构造pwm-beeper平台设备
static structplatform_device pwm_beeper_device = {
.name ="pwm-beeper",
.dev ={
.platform_data =(void *)0, // Timer0
},
.id =-1,
};
12.2在smdk2440_devices中添加s3c_device_timer和pwm_beeper_device
&s3c_device_timer[0],
&pwm_beeper_device,
12.3在arch/arm/plat-s3c24xx/common-smdk.c中的smdk_machine_init中设置蜂鸣器IO口为TOUT0
s3c_gpio_cfgpin(S3C2410_GPB(0),S3C2410_GPB0_TOUT0);
12.4修改arch/arm/plat-samsung/pwm.c中的pwm_config函数
tcmp= __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
tcnt= __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
if (period_ns == 0)
period = 0;
else
period= NS_IN_HZ / period_ns;
12.5配置内核
System Type --->
[*]PWM device support
Device Drivers --->
Inputdevice support --->
[*] Miscellaneous devices --->
<*> PWM beeper support
12.6重新编译,下载到开发板运行,内核输出如下信息,同时蜂鸣器响一声
input: pwm-beeper as/class/input/input2
12.7用户空间测试程序
#include<stdint.h>
#include<string.h>
#include<fcntl.h>
#include<unistd.h>
#include<stdio.h>
#include<linux/input.h>
#include<unistd.h>
int main(int argc, char *argv[])
{
intfd, ret, freq;
structinput_event event;
if((fd = open("/dev/event2", O_RDWR)) < 0)
{
perror("open");
return1;
}
event.type= EV_SND;
event.code= SND_TONE;
while(1)
{
printf("Pleaseinput frequency(<0 quit):\n");
scanf("%d",&freq);
if(freq < 0)
break;
event.value= freq;
ret= write(fd, &event, sizeof(struct input_event));
if(ret < 0)
perror("write");
}
close(fd);
return 0;
}
13 RTC驱动
13.1 在arch/arm/mach-s3c2440/mach-smdk2440.c的smdk2440_devices[]结构体数组添加rtc平台设备
&s3c_device_rtc,
13.2配置内核
Device Drivers--->
[*] Real Time Clock --->
[*]Set system time from RTC on startup and resume (NEW)
(rtc0)RTC used to set the system time
[*]/sys/class/rtc/rtcN (sysfs) (NEW)
[*]/proc/driver/rtc (procfs for rtc0) (NEW)
[*]/dev/rtcN (character devices) (NEW)
<*>Samsung S3C series SoC RTC
13.3重新编译内核并下载到开发板运行,内核输出如下信息
s3c-rtc s3c2410-rtc: setting systemclock to 2000-03-25 03:24:25 UTC (953954665)
[root@tq2440 /]# date
Sat Mar 25 03:25:44 UTC 2000
[root@tq2440 /]# date -s2013.7.14-20:35:0 设置时间
Sun Jul 14 20:35:00 UTC 2013
[root@tq2440 /]# hwclock -w 将当前系统时间写入硬件
这样系统重启后会自动更新到硬件时间
14 看门狗驱动
14.1在arch/arm/mach-s3c2440/mach-smdk2440.c已经添加了wdt平台设备
&s3c_device_wdt,
14.2配置内核
Device Drivers --->
[*]Watchdog Timer Support --->
[*] Disable watchdog shutdown on close
<*> S3C2410 Watchdog
14.3编写喂狗程序feed_wdt.c
#include<stdlib.h>
#include<sys/types.h>
#include <sys/stat.h>
#include<fcntl.h>
#include<linux/watchdog.h>
int main()
{
int fd;
if ((fd = open("/dev/watchdog",O_RDONLY))< 0)
{
perror("open");
exit(1);
}
for (;;)
{
ioctl(fd, WDIOC_KEEPALIVE);
sleep(3);
}
close(fd);
return 0;
}
14.4交叉编译feed_wdt.c
root@zjh://home/work# arm-linux-gcc -static feed_wdt.c-o feed_wdt
将生成的可执行文件feed_wdt拷贝到根文件系统/bin目录下
执行
[root@tq2440 /]# feed_wdt&
用kill命令将feed_wdt进程杀死,过一会系统就会重启。
15 1-wire
由于TQ2440开发板没有板载1-wire设备,我外接了DS18B20温度传感器,接在S3C2440的GPG14。
15.1在arch/arm/mach-s3c2440/mach-smdk2440.c中构造1-wire平台设备
#include <linux/w1-gpio.h>
#include <plat/gpio-cfg.h>
/* DS18B20 */
static voidw1_enable_external_pullup(int enable)
{
if (enable)
s3c_gpio_setpull(S3C2410_GPG(14),S3C_GPIO_PULL_UP);
else
s3c_gpio_setpull(S3C2410_GPG(14),S3C_GPIO_PULL_NONE);
}
static structw1_gpio_platform_data ds18b20_w1_gpio = {
.pin = S3C2410_GPG(14),
.is_open_drain = 0,
.enable_external_pullup =w1_enable_external_pullup,
};
static structplatform_device tq2440_ds18b20_device = {
.name = "w1-gpio",
.id = -1,
.dev = {
.platform_data = &ds18b20_w1_gpio,
},
};
在smdk2440_devices[]中加入
&tq2440_ds18b20_device
15.2配置内核支持w1-gpio Masters和Slaves
Device Drivers--->
{*}Dallas's 1-wire support --->
1-wireBus Masters --->
<*>GPIO 1-wire busmaster
1- wire Slaves--->
<*> Thermal family implementation
15.3重新编译,下载到开发板运行
[root@tq2440 /]# ls sys/devices/w1\ bus\ master/
28-0000032121a3 w1_master_name
bus w1_master_pointer
driver w1_master_pullup
power w1_master_remove
subsystem w1_master_search
uevent w1_master_slave_count
w1_master_add w1_master_slaves
w1_master_attempts w1_master_timeout
w1_master_max_slave_count
这个目录下有一个以“28-”开头的目录,这个就是你的DS18B20设备的目录,28代表你使用的温度传感器是DS18B20,后面接的一串数字和字母是它的ID号(用来识别不同设备,也是独一无二的)
进入这个目录,里面的w1_slave文件就是它的设备文件:
[root@tq2440 28-0000032121a3]# ls
busid power uevent
drivername subsystem w1_slave
获取温度值:
查看w1_slave设备文件中的内容,便可得到温度值,执行命令cat w1_slave
[root@tq2440 28-0000032121a3]# cat w1_slave
fe 00 4b 46 7f ff 02 10 8a : crc=8a YES
fe 00 4b 46 7f ff 02 10 8a t=15875
“t=”后面的数字就是温度值,要在千位的后面加上小数点,此时温度为:15.875摄氏度
16 I2C
16.1 arch/arm/mach-s3c2440/mach-smdk2440.c中已经添加了I2C平台设备
&s3c_device_i2c0,
16.2两种方法操作I2C
16.2.1 使用i2c-dev.c产生的字符设备节点/dev/i2c-0
配置内核
Device Drivers--->
<*>I2C support --->
[*] Enable compatibility bits for old user-space
<*> I2C deviceinterface
[*] Autoselect pertinent helper modules
I2CHardware Bus support --->
<*>S3C2410 I2C Driver
重新编译内核并下载到开发板运行
查看设备文件
[root@tq2440 /]# ls /dev/i2c-0
/dev/i2c-0
读写测试
i2c-dev.h:
到http://linux.softpedia.com/get/System/Hardware/I2C-Tools-31650.shtml下载i2c-tools,里面有i2c-dev.h。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "i2c-dev.h"
/* i2c_usr_test </dev/i2c-0><dev_addr> r addr
* i2c_usr_test </dev/i2c-0><dev_addr> w addr val
*/
void print_usage(char *file)
{
printf("%s</dev/i2c-0> <dev_addr> r addr\n", file);
printf("%s</dev/i2c-0> <dev_addr> w addr val\n", file);
}
int main(int argc, char **argv)
{
intfd;
unsignedchar addr, data;
intdev_addr;
if((argc != 5) && (argc != 6))
{
print_usage(argv[0]);
return-1;
}
fd= open(argv[1], O_RDWR);
if(fd < 0)
{
perror("open");
return-1;
}
dev_addr= strtoul(argv[2], NULL, 0);
if(ioctl(fd, I2C_SLAVE, dev_addr) < 0)
{
perror("ioctl");
return-1;
}
addr= strtoul(argv[4], NULL, 0);
if(strcmp(argv[3], "r") == 0)
{
data= i2c_smbus_read_word_data(fd, addr);
printf("data:%#x\n",data);
}
elseif ((strcmp(argv[3], "w") == 0) && (argc == 6))
{
data= strtoul(argv[5], NULL, 0);
i2c_smbus_write_byte_data(fd,addr, data);
}
else
{
print_usage(argv[0]);
return-1;
}
return0;
}
[root@tq2440 /]# ./i2c_test/dev/i2c-0 0x50 r 0
data:0x60
[root@tq2440 /]# ./i2c_test/dev/i2c-0 0x50 w 0 0x10
[root@tq2440 /]# ./i2c_test/dev/i2c-0 0x50 r 0
data:0x10
16.2.2 使用at24.c产生sys/bus/i2c/devices/i2c-0/0-0050/eeprom,直接操作eeprom
修改arch/arm/mach-s3c2440/mach-smdk2440.c
#include <linux/i2c.h>
static struct i2c_board_infotq2440_i2c_devs[] __initdata = {
{
I2C_BOARD_INFO("24c02",0x50),
},
};
在smdk2440_machine_init中注册
i2c_register_board_info(0, tq2440_i2c_devs,
ARRAY_SIZE(tq2440_i2c_devs));
配置内核
Device Drivers --->
[*]Misc devices --->
EEPROMsupport --->
<*>I2C EEPROMs from most vendors
也可以不用进行上面的arch/arm/mach-s3c2440/mach-smdk2440.c修改和配置内核,手动注册设备
[root@tq2440 /]# echo 24c02 0x50 >/sys/bus/i2c/devices/i2c-0/new_device
i2c i2c-0: The new_device interface isstill experimental and may change in a near future
at24 0-0050: 256 byte 24c02 EEPROM (writable)
i2c i2c-0: new_device: Instantiated device24c02 at 0x50
[root@tq2440 /]# ls/sys/bus/i2c/devices/0-0050/eeprom
/sys/bus/i2c/devices/0-0050/eeprom
卸载
[root@tq2440 /]# echo 0x50 >/sys/bus/i2c/devices/i2c-0/delete_device
i2c i2c-0: delete_device: Deleting device24c02 at 0x50
注:上面所用到的名字”24c02”参见at24.c中的
static const struct i2c_device_idat24_ids[] = {
/*needs 8 addresses as A0-A2 are ignored */
{"24c00", AT24_DEVICE_MAGIC(128 / 8, AT24_FLAG_TAKE8ADDR) },
/*old variants can't be handled with this generic entry! */
{"24c01", AT24_DEVICE_MAGIC(1024 / 8, 0) },
{"24c02", AT24_DEVICE_MAGIC(2048 / 8, 0) },
/*spd is a 24c02 in memory DIMMs */
{"spd", AT24_DEVICE_MAGIC(2048 / 8,
AT24_FLAG_READONLY| AT24_FLAG_IRUGO) },
{"24c04", AT24_DEVICE_MAGIC(4096 / 8, 0) },
/*24rf08 quirk is handled at i2c-core */
{"24c08", AT24_DEVICE_MAGIC(8192 / 8, 0) },
{"24c16", AT24_DEVICE_MAGIC(16384 / 8, 0) },
{"24c32", AT24_DEVICE_MAGIC(32768 / 8, AT24_FLAG_ADDR16) },
{"24c64", AT24_DEVICE_MAGIC(65536 / 8, AT24_FLAG_ADDR16) },
{"24c128", AT24_DEVICE_MAGIC(131072 / 8, AT24_FLAG_ADDR16) },
{"24c256", AT24_DEVICE_MAGIC(262144 / 8, AT24_FLAG_ADDR16) },
{"24c512", AT24_DEVICE_MAGIC(524288 / 8, AT24_FLAG_ADDR16) },
{"24c1024", AT24_DEVICE_MAGIC(1048576 / 8, AT24_FLAG_ADDR16) },
{"at24", 0 },
{/* END OF LIST */ }
};
重新编译并下载到开发板运行
[root@tq2440 /]# lssys/bus/i2c/devices/i2c-0/0-0050/eeprom
sys/bus/i2c/devices/i2c-0/0-0050/eeprom
测试
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
/* i2c_usr_test <i2c-0> r addr
*i2c_usr_test <i2c-0> w addr val
*/
void print_usage(char *file)
{
printf("%s<i2c-0> r addr\n", file);
printf("%s<i2c-0> w addr val\n", file);
}
int main(int argc, char **argv)
{
intfd;
unsignedchar addr, data;
intdev_addr;
charbin_file_name[128];
if((argc != 4) && (argc != 5))
{
print_usage(argv[0]);
return-1;
}
sprintf(bin_file_name,"/sys/bus/i2c/devices/%s/0-0050/eeprom", argv[1]);
fd= open(bin_file_name, O_RDWR);
if(fd < 0)
{
perror("open");
return-1;
}
addr= strtoul(argv[3], NULL, 0);
lseek(fd,addr, SEEK_SET);
if(strcmp(argv[2], "r") == 0)
{
read(fd,&data, 1);
printf("data:%#x\n",data);
}
elseif ((strcmp(argv[2], "w") == 0) && (argc == 5))
{
data= strtoul(argv[4], NULL, 0);
write(fd,&data, 1);
}
else
{
print_usage(argv[0]);
return-1;
}
return0;
}
[root@tq2440 /]# ./i2c_test i2c-0 r 0
data:0x10
[root@tq2440 /]# ./i2c_test i2c-0 w 0 0x20
[root@tq2440 /]# ./i2c_test i2c-0 r 0
data:0x20
17 Nand Flash
17.1 修改Nand Flash分区信息
arch/arm/plat-s3c24xx/common-smdk.c
static struct mtd_partitionsmdk_default_nand_part[] = {
[0]={
.name = "u-boot",
.size = SZ_256K,
.offset = 0,
},
[1]={
.name = "params",
.size = SZ_128K,
.offset = MTDPART_OFS_NXTBLK,
},
[2]={
.name = "kernel",
.size = SZ_1M + SZ_2M,
.offset = MTDPART_OFS_NXTBLK,
},
[3]={
.name = "rootfs",
.size = MTDPART_SIZ_FULL,
.offset = MTDPART_OFS_NXTBLK
}
};
17.2 修改Nand Flash时序参数(参考NandFlash芯片手册)
static struct s3c2410_platform_nandsmdk_nand_info = {
//3.3V
//CLE Setup TimeMin = 12ns
//ALE Setup TimeMin = 12ns
.tacls = 20,
//WE Pulse WidthMin = 12ns
.twrph0 = 20,
//CLE Hold Time Min= 5ns
//ALE Hold Time Min= 5ns
.twrph1 = 10,
.nr_sets = ARRAY_SIZE(smdk_nand_sets),
.sets = smdk_nand_sets,
};
17.3 配置内核
Device Drivers --->
<*>Memory Technology Device (MTD) support--->
[*] MTD partitioning support
<*> Direct char device access to MTD devices
<*> NAND Device Support --->
<*> NAND Flash support for Samsung S3C SoCs
17.4 重新编译内核,并下载到开发板运行
S3C24XX NAND Driver, (c) 2004 SimtecElectronics
s3c24xx-nand s3c2440-nand: Tacls=2,20ns Twrph0=2 20ns, Twrph1=1 10ns
s3c24xx-nand s3c2440-nand: NAND softECC
NAND device: Manufacturer ID: 0xec,Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 1043 at 0x000008260000
Creating 4 MTD partitions on"NAND":
0x000000000000-0x000000040000 :"u-boot"
0x000000040000-0x000000060000 :"params"
0x000000060000-0x000000360000 :"kernel"
0x000000360000-0x000010000000 :"rootfs"
通过命令查看分区信息
[root@tq2440 /]# cat /proc/partitions
major minor #blocksname
31 0 256 mtdblock0
31 1 128 mtdblock1
31 2 3072 mtdblock2
31 3258688 mtdblock3
18 Yaffs2文件系统
18.1到http://www.aleph1.co.uk/gitweb?p=yaffs2.git;a=summary下载源码
root@zjh:/home/work# tar -zxvfyaffs2-34292b4.tar.gz
root@zjh:/home/work# cd yaffs2-34292b4
root@zjh:/home/work/yaffs2-34292b4#./patch-ker.sh c m ../linux-2.6.36.4
18.2 配置内核
File systems--->
[*]Miscellaneous filesystems --->
[*] yaffs2 file system support
18.3 重新编译内核并烧写到NandFlash
18.4 设置u-boot启动参数
set bootargsroot=/dev/mtdblock3 rootfstype=yaffs2 init=/linuxrc console=ttySAC0,115200
set bootcmd nandread 30000000 kernel\;bootm 30000000
save
18.5 重启
yaffs: dev is 32505859 name is "mtdblock3"rw
yaffs: passed flags ""
VFS: Mounted root (yaffs2 filesystem) on device 31:3.
Freeing init memory: 120K
Please press Enter to activate this console.
Processing /etc/profile...
Done
[root@tq2440 /]#