linux-2.6.36.4移植到TQ2440

QQ:809205580

Email:[email protected]

目  录

1 内核配制和编译-- 4

1.1修改顶层Makefile- 4

1.2修改arch/arm/boot/Makefile 增加一行,方便操作-- 5

1.3匹配机器码-- 5

1.4修改系统时钟-- 5

1.5执行默认配制-- 5

1.6配制内核-- 5

1.7编译内核-- 6

1.8启动u-boot执行如下操作-- 6

2 DM91000网卡驱动-- 7

2.1 在arch/arm/mach-s3c2440/mach-smdk2440.c,构建DM9000平台设备-- 7

2.2 修改drivers/net/dm9000.c第44行加入如下代码-- 8

2.3 配置内核支持DM9000- 9

2.4 重新编译内核并设置u-boot启动参数,通过NFS挂载根文件系统-- 9

2.5 下载内核并启动-- 9

3 LED子系统(LED)-- 9

3.1 修改arch/arm/plat-s3c24xx/common-smdk.c中的LED platform_device- 9

3.2 配置内核-- 11

3.4 重新编译内核,下载到开发板运行-- 11

4 输入子系统(按键)-- 12

4.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中构建按键platform device- 12

4.2配置内核-- 13

4.3 重新编译内核,下载到开发板重启,内核输出如下信息-- 13

4.4 用户空间测试程序-- 14

5 LCD驱动-- 16

5.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中修改LCD参数-- 16

5.2配置内核-- 16

5.3重新编译内核,下载到开发板运行,将看到企鹅log- 17

5.4 解决10分钟后黑屏:修改drivers/char/vt.c- 17

5.5关闭光标:修改/drivers/video/console/softcursor.c- 17

6 触摸屏驱动-- 18

6.1在arch/arm/mach-s3c2440/mach-smdk2440.c构造触摸屏平台设备数据-- 18

6.2 添加触摸屏和ADC平台设备列表,ADC一定要在TS前面-- 18

6.3设置触摸屏平台设备数据-- 18

6.4 5.         修改arch/arm/plat-s3c24xx/Kconfig- 19

6.5配置内核-- 19

6.6重新编译内核,下载到开发板运行,内核输出如下信息-- 19

6.7用户空间测试程序-- 19

7 ADC驱动-- 20

7.1 在arch/arm/mach-s3c2440/mach-smdk2440.c中构建HWMON设备平台数据-- 20

7.2 在smdk2440_machine_init函数中设置hwmon平台数据-- 20

7.3 在smdk2440_devices[]数组中加入-- 20

7.4 5.         修改arch/arm/plat-samsung/目录下的Kconfig文件:在S3C_DEV_HWMON选项下加入default y,这样是为了编译dev-hwmon.c这个文件-- 21

7.5修改drivers/hwmon/s3c-hwmon.c,添加头文件-- 21

7.6 屏蔽drivers/hwmon/s3c-hwmon.c:238、256行-- 21

7.7配置内核-- 21

7.8重新编译,下载到开发板运行-- 21

8 SD卡驱动-- 22

8.1在arch/arm/mach-s3c2440/mach-smdk2440.c中构造SD卡平台设备数据-- 22

8.2设置SD卡平台设备数据-- 22

8.3 在arch/arm/mach-s3c2440/mach-smdk2440.c  smdk2440_devices 结构体数组中加入SD卡平台设备     22

8.4 配置内核支持SD卡-- 22

8.5重新编译内核,下载到开发板运行-- 23

8.6 实现自动挂载SD卡-- 23

9 USB主控制器驱动-- 23

9.1 SMDK2440 开发板已经添加了USB主控制器平台设备s3c2410-ohci23

9.2 配置内核-- 24

9.3重新编译内核,下载到开发板运行-- 24

9.4 实现U盘自动挂载:修改rootfs/etc/mdev.conf,添加如下内容-- 24

10 USB摄像头驱动-- 24

10.1直接配置内核-- 24

10.2重新编译内核,下载到开发板运行-- 25

11 移植开源的移动图像监控软件motion- 25

11.1到http://www.lavrsen.dk/foswiki/bin/view/Motion/WebHome下载源码-- 25

11.2解压,配置,编译,安装-- 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

11.5修改配置文件etc/motion.conf26

11.6插上USB摄像头-- 26

12 PWM-BEEPER驱动-- 27

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.5配置内核-- 28

12.6重新编译,下载到开发板运行,内核输出如下信息,同时蜂鸣器响一声-- 28

12.7用户空间测试程序-- 28

13 RTC驱动-- 29

13.1 在arch/arm/mach-s3c2440/mach-smdk2440.c的smdk2440_devices[]结构体数组添加rtc平台设备     29

13.2配置内核-- 29

13.3重新编译内核并下载到开发板运行,内核输出如下信息-- 29

14 看门狗驱动-- 29

14.1在arch/arm/mach-s3c2440/mach-smdk2440.c已经添加了wdt平台设备-- 29

14.2配置内核-- 29

14.3编写喂狗程序feed_wdt.c- 30

14.4交叉编译feed_wdt.c- 30

15 1-wire- 30

15.1在arch/arm/mach-s3c2440/mach-smdk2440.c中构造1-wire平台设备-- 30

15.2配置内核支持w1-gpioMasters和Slaves- 31

15.3重新编译,下载到开发板运行-- 31

16 I2C- 32

16.1 arch/arm/mach-s3c2440/mach-smdk2440.c中已经添加了I2C平台设备-- 32

16.2两种方法操作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 Nand Flash- 37

17.1 修改NandFlash分区信息-- 37

17.2 修改NandFlash时序参数(参考NandFlash芯片手册)-- 37

17.3 配置内核-- 38

17.4 重新编译内核,并下载到开发板运行-- 38

18 Yaffs2文件系统-- 38

18.1到http://www.aleph1.co.uk/gitweb?p=yaffs2.git;a=summary下载源码-- 38

18.2 配置内核-- 38

18.3 重新编译内核并烧写到NandFlash- 39

18.4 设置u-boot启动参数-- 39

18.5 重启-- 39

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

#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

#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/

led1 led2  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

#include

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

#include

#include

#include

#include

#include

 

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

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

#include

#include

#include

#include

#include

#include

#include

#include

 

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

/* 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

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_raw     adc4_raw      bus           in2_label     uevent

adc1_raw     adc5_raw      driver        modalias

adc2_raw     adc6_raw      hwmon:hwmon0  power

adc3_raw     adc7_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

#include

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:0    0660        @(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

#include

#include

#include

#include

#include

#include

 

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

#include

#include

#include

#include

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

#include

/* 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

bus       id         power      uevent

driver    name       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

#include

#include

#include

#include "i2c-dev.h"

 

/* i2c_usr_test r addr

 * i2c_usr_test w addr val

 */

 

void print_usage(char *file)

{

       printf("%s r addr\n", file);

       printf("%s 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

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

#include

#include

#include

 

/* i2c_usr_test r addr

 *i2c_usr_test w addr val

 */

 

void print_usage(char *file)

{

       printf("%s  r addr\n", file);

       printf("%s  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  #blocks name

 

 31        0        256 mtdblock0

 31        1        128 mtdblock1

 31        2       3072 mtdblock2

 31        3    258688 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 /]#

你可能感兴趣的:(linux,内核移植,嵌入式,arm,2440,linux)