DAVINCI DM365-DM368開發攻略——linux-2.6.32的移植

火星人 @ 2014-03-08 , reply:0


2012年的春節就這樣過了,假期期間,在接到的大項目沒有進展的情況下(團隊的人都回家過年了),利用這三天深圳最冷的時間(5°C):1月25~27號,趕緊完成這篇文章的稿子,畢竟很長時間沒有更新博客了,後面一上班就得忙幾個客戶的大項目;在這裡也順便紀念一下去年故去的C語言之父——丹尼斯·里奇,也是操作系統Unix之父,是他讓嵌入式發展如此迅猛,科技發展如此飛速,C語言是如此美麗,簡潔,大大提高軟體跨主晶元平台的移植,他勞苦功高,本人決定本篇文章不使用“.”,直接使用“;”,和很多網友一樣,用“;”代表C語言的一行指令的結束,以表達對他的緬懷; 一、介紹linux-2.6.32: Linux-2.6.32的網上介紹:增添了虛擬化內存 de-duplicacion、重寫了 writeback 代碼、改進了 Btrfs 文件系統、添加了 ATI R600/R700 3D 和 KMS 支持、CFQ 低傳輸延遲時間模式、perf timechart 工具、內存控制器支持 soft limits、支持 S Core 架構、支持 英特爾 Moorestown 及其新的固件介面、支持運行時電源管理、以及新的驅動;這些本人不懂,但是本人只注意到常用的LINUX操作系統RADHAT Enterprise 6,ubuntu-10.04,debian 6.0穩定版本,這些都是使用linux-2.6.32這個版本,智能手機就更多了,android手機(經典版本HTC-G7手機使用linux-2.6.32.15和android 2.2版本結合),因為只有從linux-2.6.32以後,才能發揮android系統的優勢;不過單核的DM368無論是432MHz還是新出的500多MHz,跑android系統非常困難,只能跑QT,這裡不討論; 本人寫內核的環境和路徑都是基於前兩篇文章的基礎上進行的,先從dvsdk_dm368_4_02_00_06\下的Rules.make和Makefile開始,見Rules.make第45行, LINUXKERNEL_INSTALL_DIR=$(DVSDK_INSTALL_DIR)/psp/linux-2.6.32.17 很明顯我們把內核名字改成linux-2.6.32.17,原來解壓安裝出來的名字太長了,要在Rules.make第45行改一下;Makefile是編譯的腳本,TI把整個DVSDK4.02的開發環境統一整合在一起,體現在這個Makefile,看完這個Makefile,就應該知道如何編譯整個DVSDK里所有的軟體包,內核編譯的命令見143行開始;在dvsdk_dm368_4_02_00_06\目錄下使用make linux,make linux_config, make linux_clean等命令編譯內核; 二、開始移植:從刪除多餘的文件夾和文件開始: 1、dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/configs 只保留davinci_dm365_defconfig

圖-1 然後按上圖-1,先使用默認的config文件進行內核配置, cp arch/arm/configs/davinci_dm365_defconfig .config 注意路徑; 2、刪除非ARM晶元平台的處理器 進入dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch,保留arm,um,x86三個文件夾,其他文件刪除掉; 然後進入dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/um文件夾,只保留scripts文件夾,其他刪除掉,包括那幾個文件Kconfig等文件也刪除掉; 繼續進入dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/x86文件夾,只保留include和mm文件夾,和幾個文件,其他文件夾刪除掉見下圖-2:

圖-2 繼續進入dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm文件夾,保留mach-davinci文件夾和保留下圖的文件夾和文件,其他帶mach-刪除吧,占空間,又占備份時壓縮的時間,

圖-3 上圖-3就是dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm目錄下刪除后的結果顯示; 3、修改dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/Makefile, 從第120行開始,#machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 一直到172行, #machine-$(CONFIG_ARCH_MXC91231) := mxc91231 只保留machine-$(CONFIG_ARCH_DAVINCI) := davinci,其他全部使用”#”給屏蔽掉,我們只要machine-$(CONFIG_ARCH_DAVINCI) := davinci 第176行到第184統統使用”#”給屏蔽掉,不要這些晶元平台; 4、修改dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/Kconfig 從第707行開始,一直到793行,這些全部使用“#”給屏蔽掉,保留第795行的source "arch/arm/mach-davinci/Kconfig",然後繼續把第797到805行使用“#”給屏蔽掉; 經過上面的刪除,使用tar jcf 或 tar zcf壓縮的linux-2.6.32.17降到51M,比沒有刪除的減小近一半的大小;我們追求簡潔,思路清晰;其實還有很多地方可以刪除的,大家慢慢體會,包括include,driver裡邊的老掉牙的設備,這裡就不啰嗦了;刪除後記得把對應的Kconfig和Makefile給屏蔽掉; 三、開始從內核配置

圖-4 因為前面已經做了cp arch/arm/configs/davinci_dm365_defconfig .config我們按上圖指定的路徑使用make linux_config,這樣就看到熟悉的內核配置界面,見下圖-5:

圖-5 我們按順序一個一個配置,當然,很多配置選項都是使用TI davinci_dm365_defconfig配置好的,我們對它們進行分析、裁剪、修改, 進入“General setup”配置

圖-6 上圖是我們多選了RAM disk文件系統支持的壓縮方式,默認是使用gzip生產RAM DISK文件系統,你也可以使用bzip2和LZMA(壓縮率比前面兩個高);

圖-7 進入“System Type”配置,上面按TI 原來的配置,

圖-8 然後直接進入“TI Davinci Implementations”,按上面的選擇,面的27000000表示你的主晶元晶振是27MHz還是24MHz,本公司的是24MHz晶振,我們就把27000000改成24000000;

圖-9 返回圖-5,進入“Networking support”,你的系統如果沒有WIFI等無線模塊,這個無線的“wireless”協議可以不選;

圖-10 主要對“Networking options”進行配置,這裡基本上就是IPV4和IPV6的協議配置,我們按TI原來的選擇,帶“M”選項也可以使用“*”編譯進內核,而不是模塊;

圖-11

圖-12 返回圖-5進入“Device Drivers”,這是配置內核的重點,見圖-11和圖-12,

圖-13 按順序先對NAND FLASH分區MTD進行配置,直接參考TI 默認的配置;

圖-14 圖-14 RAM/ROM/FLASH及下面3個使用TI默認的配置,

圖-15 進入“NAND device Support”的配置,一定要選擇“Support NAND on Davinci SoC”,

圖-16 這是2.6.32新的特性,開始支持UBI文件系統,UBI文件系統的出現,可以讓JFFS2,YAFFS2退出市場,跑android系統,用到,這裡我們可以不選,也可以選,根據你的板子要使用什麼樣的文件系統;

圖-17 返回圖-11進入“Block devices”配置,我們直接使用TI的配置,

圖-18 返回圖-11進入“SCSI device support”的配置,選擇這個來支持U盤,否則你的U盤無法被DM368板子識別,我們一般把DM368 USB設置HOST模式;

圖-19 返回圖-11進入“Network device support”的配置,一般的RJ45網口選擇“10M or 100Mbit”,DM368不支持1000Mbit,無線“Wireless LAN”你不需要的話可以不選;“PPP”這個可以不選,而有時要支持3G的模塊的時候,PPP協議(見圖-10的配置)和設備支持要選擇;

圖-20 進入“10M or 100Mbit”,選擇“TI Davinci EMAC Support;

圖-21 返回圖-11進入“Input device support”,這選擇是否支持滑鼠鍵盤觸摸屏等輸入,我們這邊用不上,直接不選;

圖-22 返回圖-11進入“Char device”,一定要選擇DM365 IPIPE,IMP Previewer,IMP Resizer,這個到時候調試視頻採集程序需要用到Previewer、Resizer等DAVINCI技術;

圖-23 在圖-22中,選擇進入“Serial driver”,這裡就是DM368的串口配置了,DM368支持UART0 和UART1,UART1和其他GPIO復用,小心分配使用硬體資源,和DM6446一樣,都是8250的驅動,而DM6446可以配置3個UART;

圖-24 返回圖-11進入“I2C Support”,這個沒得說,肯定使用選上的,

圖-25 TI開發板使用的I2C擴展晶元,我們不需要,External就不要了,只選上“Davinci I2C driver”;

圖-26 返回圖-11進入“SPI Support”,如果你的板子沒有外接SPI介面的晶元,這裡可以不選;

圖-27 返回圖-11進入“GPIO Support”,TI使用晶元擴展更多的GPIO腳,我們不需要,可以不選;

圖-28 返回圖-11進入“Watchdog Timer Support”,凡是使用軟體看門狗的,都需要選上這個,DM368和DM6446這些晶元都支持軟體看門狗,注意選擇是“Davinci watchdog”;

圖-29 返回圖-11進入 “Multimedia support”,多媒體支持,這個就是Davinci的重點,

圖-30 按TI默認的選擇,MT9P031 500萬像素的SERSEOR可以選上,你有其他公司的SENSOR,也可以參考MT9P031的方法加入你SENSOR的驅動,然後修改linux-2.6.32.17\drivers\media\video裡邊的Makefile和Kconfig文件就OK了;

圖-31 然後從圖-30的“encoders/decoders and xxxx”進去選擇TVP5146,高清Ypbpr輸出THS7303,TH7353晶元的選擇支持,我們公司使用TVP5158,本人把它加入內核編譯,這裡顯示TVP5158,TVP7002我們沒有使用,不用選;

圖-32 返回圖-11進入“Graphics Suppor”,這個就是選擇支持TFT3.5, TFT4.3寸LCD屏的驅動,也就是通過RGB介面支持屏的輸出,我板子不支持,可以選擇也可以按TI默認的設置;

圖-33 返回圖-11進入“Sound card Suppor”,音效卡選擇,

圖-34 DM368主晶元上帶有音頻功能的模塊,直接按TI的設置,

圖-35 返回圖-11進入“USB Suppor”,我們把DM368跑的LINUX系統當作HOST來使用,“HID Support”是支持滑鼠鍵盤之類的東西,可以選也可以不要;基本上採用TI的默認配置

圖-36 這裡選擇支持U盤,這個和前面說過的SCSI Spport是對應的;

圖-37 返回圖-11進入“MMC/SD/SDIO Suppor”,linux-2.6.32的SD卡驅動完全支持32G的容量,DM368支持兩個SD卡介面0和1,使用SD0基本不需要什麼移植,使用SD1內核驅動注意使用SD1卡時,復用的GPIO腳就不需要了;

圖-38 返回圖-11進入“Real Time Clock”,DM368支持片上的RTC時鐘,即“TI Davinci RTC”,我們自己的板子支持外部RTC時鐘晶元PCF8563,根據外設選擇;

圖-39 返回圖-5進入“File systems”,對需要支持的文件系統進行選擇,選擇EXT2/EXT3/EXT4文件系統是在斷電對存儲設備保護和日誌恢復的情況下,比FAT32好多了,比如把SD卡格式化成EXT3/EXT4比FAT32更好用;

圖-40 其他保留TI的配置,

圖-41 進入“DOS/FAT/NT”文件系統的支持,按上面的選擇,NTFS沒有用過,不知在嵌入式是否好用,這裡選擇的目的是能夠使用U盤等等存儲設備;

圖-42 進入“Pseudo filesystems”,保留TI的默認配置;

圖-43

圖-44 進入“Miscellaneous filesystems”,配置NAND FLASH支持的文件系統,YAFFS2的文件系統是本人下載然後按patch就行移植的,TI原來沒有,選擇YAFF2,JFFS2,還有cramfs,SquashFS,UBI文件系統目前沒有驗證,有時間再試試,剛才提到的都是最常用的嵌入式NAND文件系統,就是要燒進NAND FLASH的;

圖-45 圖-45就是NFS文件系統的設置,我們在板子上運行的是NFS client模式,即客戶端,而開發環境是NFS SERVER端;裡邊的SMB(SAMBA)在板子上不需要支持,我們去掉不選;

圖-46 圖-46就是選擇內核支持的語言; 然後備份配置:在dvsdk_dm368_4_02_00_06目錄下 #cp psp/linux-2.6.32.17/.config psp/linux-2.6.32.17/dm368_20111227.config 注意路徑,凡是使用make distclean和make linux_clean命令后,.config不存在,這時我們就使用: #cp psp/linux-2.6.32.17/dm368_20111227.config psp/linux-2.6.32.17/.config注意.config的“.”,這樣整個內核配置基本結束; 四、分析和修改代碼: 1、mach-davinci\board-dm365-evm.c 這個是DM368內核移植重點的地方,系統初始化函數都在這裡,而外部設備初始化在各自的驅動文件里;打開第156行 #define NAND_BLOCK_SIZE

SZ_128K 同時屏蔽/*#define NAND_BLOCK_SIZE SZ_512K*/ 這個是4K-PAGE NAND FLASH 因為我們公司的板子都是使用2K-PAGE的NAND FLASH,512位元組的NAND不適合新的文件系統,慢慢會被淘汰; 修改NAND FLASH的分區, static struct mtd_partition davinci_nand_partitions[] = { { /* UBL (a few copies) plus U-Boot */ .name = "bootloader", .offset = 0x80000, .size = 3 * NAND_BLOCK_SIZE, .mask_flags =0, /* tongye:.mask_flags = MTD_WRITEABLE, *//* force read-only */ }, { /* U-Boot environment */ .name = "params", .offset = 0xe0000, .size = 1 * NAND_BLOCK_SIZE, .mask_flags = 0, }, { .name = "kernel", .offset = 0x100000, .size = SZ_4M SZ_512K, .mask_flags = 0, }, { .name = "basefs", .offset = 0x100000 SZ_4M SZ_512K, .size = SZ_32M-SZ_4M, .mask_flags = 0, /* tongye:28M-byte for ramdisk,cramfs,squashfs rootfs*/ }, { .name = "userfs", .offset = 0x100000 SZ_32M SZ_512K, .size = SZ_64M SZ_16M, .mask_flags = 0,

/*tongye:80M-byte for jffs2,yaffs2 rootfs*/ }, { .name = "userdata", .offset = SZ_64M SZ_32M SZ_16M SZ_1M SZ_512K, .size = 0x8000000-SZ_64M-SZ_32M-SZ_16M-SZ_1M-SZ_512K, .mask_flags = 0, } /* two blocks with bad block table (and mirror) at the end */ }; UBL的代碼放在0x20000~0x40000的位置,一般NAND FLASH前面5個BLOCK出現壞塊的幾率非常小,在產品中一般很少去維護更新UBL,沒有把UBL單獨分一個分區;而其他空間出現壞塊的幾率比較大,給U-BOOT分3~4個BLOCK夠用了,內核分5M-BYTE也夠用,而U-BOOT參數分1~2個BLOCK,本公司直接放到0x60000~0x80000的空間也可以,沒有規定;後面的文件系統分區就根據你裁剪的文件系統、文件系統的類型進行大小分區; static struct i2c_board_info i2c_info[] = { /* { I2C_BOARD_INFO("dm365evm_keys", 0x25), }, { I2C_BOARD_INFO("24c256", 0x50), .platform_data = &eeprom_info, }, */ { I2C_BOARD_INFO("tlv320aic3x", 0x18), }, { I2C_BOARD_INFO("ths7303", 0x2c), }, /*{ I2C_BOARD_INFO("PCA9543A", 0x73), },*/ { I2C_BOARD_INFO("pcf8563", 0x51), }, }; 上面這個結構就是看看你的I2C匯流排帶什麼樣的設備,根據你的I2C設備地址,添加到這裡,這樣才能調用到設備初始化函數;從上面的修改看出,我們的板子不需要AT24C256這些EEPROM晶元,可以幹掉; static void dm365evm_reset_imager(int rst) {

u8 val; //tongye #if 0 val = __raw_readb(cpld CPLD_POWER) | BIT(3) | BIT(11) | BIT(19) | BIT(27); __raw_writeb(val, (cpld CPLD_POWER)); val = __raw_readb(cpld CPLD_MUX) | BIT(6) | BIT(14) | BIT(22) | BIT(30); __raw_writeb(val, (cpld CPLD_MUX)); /* Reset bit6 of CPLD_IMG_DIR2 */ val = __raw_readb(cpld CPLD_IMG_DIR2) & ~BIT(6); __raw_writeb(val, (cpld CPLD_IMG_DIR2)); /* Set bit5 of CPLD_IMG_MUX5 */ val = __raw_readb(cpld CPLD_IMG_MUX5) | BIT(5); __raw_writeb(val, (cpld CPLD_IMG_MUX5)); /* Reset bit 0 of CPLD_IMG_MUX5 */ val = __raw_readb(cpld CPLD_IMG_MUX5) & ~BIT(0); __raw_writeb(val, (cpld CPLD_IMG_MUX5)); #endif /** * Configure GPIO40 to be output and high. This has dependency on MMC1 */ #if 1 davinci_cfg_reg(DM365_PWM3_G85); davinci_cfg_reg(DM365_PWM3_G86); gpio_request(85, "sensor_reset"); gpio_request(86, "sensor_standby"); gpio_direction_output(85, 0); gpio_direction_output(86, 0); gpio_set_value(85,1); gpio_set_value(86,1); mdelay(15); 頭文件要加上#include <linux/delay.h> gpio_set_value(85,0); gpio_set_value(86,0); mdelay(25); gpio_set_value(85,1); gpio_set_value(86,1); mdelay(25); #else davinci_cfg_reg(DM365_GPIO40);

gpio_request(40, "sensor_reset"); if (rst) gpio_direction_output(40, 1); else gpio_direction_output(40, 0); #endif } 上面的函數修改:我們不需要CPLD,屏蔽掉,我們直接使用GPIO控制MT9P031 SENSOR的複位和STANDBY信號; static struct vpfe_subdev_info vpfe_sub_devs[] = { { .module_name = "tvp5158", .grp_id = VPFE_SUBDEV_TVP5146, .num_inputs = ARRAY_SIZE(tvp5158_inputs), .inputs = tvp5158_inputs, .routes = tvp5158_routes, .can_route = 1, .ccdc_if_params = { .if_type = VPFE_BT656, .hdpol = VPFE_PINPOL_POSITIVE, .vdpol = VPFE_PINPOL_POSITIVE, }, .board_info = { I2C_BOARD_INFO("tvp5158", 0x5B), .platform_data = &tvp5158_pdata, }, }, { .module_name = "tvp7002", .grp_id = VPFE_SUBDEV_TVP7002, .num_inputs = ARRAY_SIZE(tvp7002_inputs), .inputs = tvp7002_inputs, .ccdc_if_params = { .if_type = VPFE_BT1120, .hdpol = VPFE_PINPOL_POSITIVE, .vdpol = VPFE_PINPOL_POSITIVE, }, .board_info = { I2C_BOARD_INFO("tvp7002", 0x5c),

.platform_data = &tvp7002_pdata, }, }, { .module_name = "ths7353", .grp_id = VPFE_SUBDEV_TVP7002, .board_info = { I2C_BOARD_INFO("ths7353", 0x2e), }, }, { .module_name = "mt9p031", .is_camera = 1, .grp_id = VPFE_SUBDEV_MT9P031, .num_inputs = ARRAY_SIZE(mt9p031_inputs), .inputs = mt9p031_inputs, .ccdc_if_params = { .if_type = VPFE_RAW_BAYER, .hdpol = VPFE_PINPOL_POSITIVE, .vdpol = VPFE_PINPOL_POSITIVE, }, .board_info = { I2C_BOARD_INFO("mt9p031", 0x48), /* this is for PCLK rising edge */ .platform_data = (void *)1, }, } }; TI的DM368開發板同時支持TVP5146、TVP7002、MT9P031;TVP5146代表標清複合視頻輸入採集晶元(D1格式),TVP7002代表複合視頻YPbPr的高清輸入採集晶元,MT9P031代表500萬像素的SENSOR採集; /* Set the input mux for TVP7002/TVP5146/MTxxxx sensors */ static int dm365evm_setup_video_input(enum vpfe_subdev_id id) { const char *label; u8 mux, resets; //Jingbo /////mux = __raw_readb(cpld CPLD_MUX); ////mux &= ~CPLD_VIDEO_INPUT_MUX_MASK; ////resets = __raw_readb(cpld CPLD_RESETS);

switch (id) { case VPFE_SUBDEV_TVP5146: mux |= CPLD_VIDEO_INPUT_MUX_TVP5146; resets &= ~BIT(0); label = "tvp5158 SD"; dm365evm_reset_imager(0); break; case VPFE_SUBDEV_MT9P031: mux |= CPLD_VIDEO_INPUT_MUX_IMAGER; resets |= BIT(0); /* Put TVP5146 in reset */ label = "HD imager"; dm365evm_reset_imager(1); /* Switch on pca9543a i2c switch */ ////if (have_imager()) ////dm365evm_enable_pca9543a(1); break; case VPFE_SUBDEV_TVP7002: resets &= ~BIT(2); mux |= CPLD_VIDEO_INPUT_MUX_TVP7002; label = "tvp7002 HD"; break; default: return 0; } ////__raw_writeb(mux, cpld CPLD_MUX); ////__raw_writeb(resets, cpld CPLD_RESETS); pr_info("EVM: switch to %s video input\n", label); return 0; } 上面的函數去掉CPLD的東西,這個視頻採集晶元的選擇是和U-BOOT的參數一一對應的,在U-BOOT bootargs的參數里,加入davinci_capture.device_type=0表示使用TVP5146採集,davinci_capture.device_type=1表示使用MT9P031採集,davinci_capture.device_type=2表示使用TVP7002採集,內核讀取U-BOOT的參數,會在初始化確定是否調用什麼樣的採集晶元驅動;我們在內核配置的時候,可以同時選上三種晶元; static void __init evm_init_i2c(void) {

davinci_init_i2c(&i2c_pdata); #if 0 if (have_imager()) i2c_add_driver(&pca9543a_driver); #endif i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info)); } 這個pca9543a I2C切換晶元我們不需要; static void __init evm_init_cpld(void) { u8 mux, resets; const char *label; struct clk *aemif_clk; struct davinci_soc_info *soc_info = &davinci_soc_info; /* Make sure we can configure the CPLD through CS1. Then * leave it on for later access to MMC and LED registers. */ aemif_clk = clk_get(NULL, "aemif"); if (IS_ERR(aemif_clk)) return; clk_enable(aemif_clk); #if 0 if (request_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE, "cpld") == NULL) goto fail; cpld = ioremap(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE); if (!cpld) { release_mem_region(DM365_ASYNC_EMIF_DATA_CE1_BASE, SECTION_SIZE); fail: pr_err("ERROR: can't map CPLD\n"); clk_disable(aemif_clk); return; } /* External muxing for some signals */ mux = 0; /* Read CPLD version number */ soc_info->cpld_version = __raw_readb(cpld CPLD_VERSION); /* Read SW5 to set up NAND keypad _or_ OneNAND (sync read). * NOTE: SW4 bus width setting must match!

*/ if ((__raw_readb(cpld CPLD_SWITCH) & BIT(5)) == 0) { /* external keypad mux */ mux |= BIT(7); platform_add_devices(dm365_evm_nand_devices, ARRAY_SIZE(dm365_evm_nand_devices)); } else { /* no OneNAND support yet */ } /* Leave external chips in reset when unused. */ resets = BIT(3) | BIT(2) | BIT(1) | BIT(0); /* ... and ENET ... */ dm365evm_emac_configure(); soc_info->emac_pdata->phy_mask = DM365_EVM_PHY_MASK; soc_info->emac_pdata->mdio_max_freq = DM365_EVM_MDIO_FREQUENCY; resets &= ~BIT(3); /* ... and AIC33 */ resets &= ~BIT(1); /* Static video input config with SN74CBT16214 1-of-3 mux: * - port b1 == tvp7002 (mux lowbits == 1 or 6) * - port b2 == imager (mux lowbits == 2 or 7) * - port b3 == tvp5146 (mux lowbits == 5) * * Runtime switching could work too, with limitations. */ if (have_imager()) { label = "HD imager"; mux |= CPLD_VIDEO_INPUT_MUX_IMAGER; /* externally mux MMC1 to imager */ mux |= BIT(6); dm365evm_reset_imager(1); } else { /* we can use MMC1 ... */ dm365evm_mmc_configure(); davinci_setup_mmc(1, &dm365evm_mmc_config);

if (have_tvp7002()) { mux |= CPLD_VIDEO_INPUT_MUX_TVP7002; resets &= ~BIT(2); label = "tvp7002 HD"; } else { /* default to tvp5146 */ mux |= CPLD_VIDEO_INPUT_MUX_TVP5146; resets &= ~BIT(0); label = "tvp5158 SD"; dm365evm_reset_imager(0); } } __raw_writeb(mux, cpld CPLD_MUX); __raw_writeb(resets, cpld CPLD_RESETS); #else platform_add_devices(dm365_evm_nand_devices, ARRAY_SIZE(dm365_evm_nand_devices)); /* ... and ENET ... */ dm365evm_emac_configure(); soc_info->emac_pdata->phy_mask = DM365_EVM_PHY_MASK; soc_info->emac_pdata->mdio_max_freq = DM365_EVM_MDIO_FREQUENCY; //if (have_imager()) { dm365evm_reset_imager(1); //pr_info("EVM: reset mt9p031 imager\n"); } //pr_info("EVM: %s video input\n", label); #endif /* REVISIT export switches: NTSC/PAL (SW5.6), EXTRA1 (SW5.2), etc */ } 上面的函數很重要,除去掉CPLD的東西外,一定要把 platform_add_devices(dm365_evm_nand_devices, ARRAY_SIZE(dm365_evm_nand_devices)); 保留,否則你的內核啟動的時候,根本沒有NAND的驅動和分區顯示; dm365evm_emac_configure();也肯定要的,否則沒有網路驅動叫LINUX嗎?TI就是通過CPLD來控制一些外設,CPLD比較貴,不適合低成本大批量生產,我們去掉了; static __init void dm365_evm_init(void) {

dm365evm_gpio_configure(); //tongye:copy it here evm_init_i2c(); davinci_serial_init(&uart_config); dm365evm_emac_configure(); dm365evm_usb_configure(); davinci_setup_mmc(0, &dm365evm_mmc_config); /* maybe setup mmc1/etc ... _after_ mmc0 */ evm_init_cpld(); dm365_init_asp(&dm365_evm_snd_data); //dm365_init_rtc(); //dm365_init_ks(&dm365evm_ks_data); //dm365_init_spi0(BIT(0), dm365_evm_spi_info, //ARRAY_SIZE(dm365_evm_spi_info)); //dm365_init_tsc2004(); dm365evm_gpio_configure(); } 這個函數就是對MMC/SD、USB、等介面進行初始化了,tsc2004這個是觸摸屏的晶元,dm365evm_gpio_configure()裡邊我們添加了很多GPIO的初始值定義; 2、修改mach-davinci\dm365.c 這個要和arch\arm\mach-davinci\include\mach\mux.h配合看, 好好看看mux_config dm365_pins這個定義,這個DM368的管腳復用非常複雜,使能某個功能,那麼對應的另外的功能就不能用了,因此要非常小心對待,特別是和GPIO復用; 後面這些源碼介紹就是提示和分析了: drivers\char\里有dm365_ipipe.c 、imp_common.c、imp_previewer.c、imp_resizer.c、等文件; drivers\i2c\busses\里有i2c-davinci.c 重點介紹:drivers\media\video\里有V4L2的介面驅動; drivers\media\video\mt9p031.c,tvp514x.c,tvp7002.c; drivers\media\video\davinci\里東西就很多了,dm365_ccdc.c、vpfe_capture.c drivers\net\里有davinci_emac.c drivers\usb\musb\里davinci.c GPIO的使用,一直沒有搞清楚這個新內核為什麼老是隔段時間對U盤複位,和2.6.18不一樣,搞得U盤一直成功列舉設備,然後用重新複位分配新USB DEVIDE 地址; drivers\watchdog\里有davinci_wdt.c 第32行#define DEFAULT_HEARTBEAT 2

//tongye removed 60s 應用程序只有一使用open打開設備,WDG就生效,2秒鐘不喂狗就軟體複位; linux-2.6.32.17\sound\soc\codecs有tlv320aicxx.c等音頻晶元驅動; linux-2.6.32.17sound\soc\davinci里有PCM、I2S等驅動; 接顯示屏drivers\video\davincifb.c,這個要和drivers\media\video\davinci\的vpbe_encoder.c、davinci_display.c、davinci_osd.c啊等等VPBE介面的文件對應; 在dvsdk_dm368_4_02_00_06目錄下加個編譯腳本build_linux.sh: #!/bin/sh make linux chmod 777 /home/davinci/dm368/dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/boot/uImage cp -f /home/davinci/dm368/dvsdk_dm368_4_02_00_06/psp/linux-2.6.32.17/arch/arm/boot/uImage /tftpboot/dm368_kernel.bin 直接./ build_linux.sh,就可以在/tftpboot的目錄下得到dm368_kernel.bin,在板子上,通過U-BOOT燒寫內核,先調試通NFS,在上篇U-BOOT的移植文章介紹到U-BOOT的NFS參數定義,這裡不啰嗦; 好了,linux-2.6.32移植就到此結束,基本上本人目前只調試通TVP5158 單路D1(720*576)圖像採集和壓縮,驗證我們的核心板OK就行了,等軟體工程師調試通1080p才發布新的開發板,因為DM368方案不是我們的開發重點; 現在內核版本更新非常快,我們只需要挑穩定的版本來做產品,不要瘋狂跟風,雖然TI已經推出linux-2.6.37的版本,但是做產品還是選定一個穩定而又比較新的版本;Linux-2.6.18有些落後了,但在中國,目前絕大部分公司還是使用dvsdk_2_10_01_18的版本,這裡邊使用的就是Linux-2.6.18的內核;這種局面是中國的通病,因為我們國家沒有自己的主晶元(沒錯,說嚴重一點,空殼,跟那些空置率超過p的房地產一樣;將來過段時間,沒有做為的話,估計連糧食的BT基因片段(轉基因)都是人家控制的),很多東西都是被人家拖著鼻子走,人家技術發展很快,覺得這種升級很自然,而我們卻覺得這種升級是跳躍,很多公司沒精力去更新技術;就比如DM642,這個2005年就已經出來的大功耗 低擴展功能晶元,現在竟然還是TI在中國最多出貨的圖像處理晶元,很多公司根本不理你什麼雙核DM6446,OMAP3730,DM6467T,DM8168,CA8168,多核的C667X,他們覺得一個CCS3.X的版本就滿足開發做產品了,懶得更新技術,哪怕DM6446性價比更高;時間不等人,不單單軟體版本更新快,主晶元更新的速度也非常快,現在流行ARM Cortex-A8和ARM Cortex-A9,然後TI 推出ARM Cortex-A8 浮點DSP,高通公司QCOM推出更低功耗的ARM Cortex-A9 DSP(華為,中興,HTC的新智能手機使用的主晶元)等等,三星也推出ARM Cortex-A9的主晶元,低功耗 豐富功能是主流;

前面說過DM368不是我們的開發重點,我們更關心那些更強大功能的ARM DSP的晶元,因為那些晶元才適合做出創新的產品;現在國內高級一點的公司就是自己做ARM FPGA的方案,因為FPGA無外乎就是Xilinx(賽靈思,或賽玲絲,搞笑一點)為代表的SoPC;更高級的公司比如華為海思(華為是母公司,台灣海思被收購),做自己ARM方案晶元,在海思流片,現在滿大街的中低端安防產品(DVR,IP-CAMERA,DVS等等)都是華為海思Hi35XX晶元,這種晶元做不了智能圖像分析,機器視覺產品,我們也沒有去開發,等有機會和資本再去玩玩,畢竟華為海思的晶元也在不斷升級;龍芯的MIPS架構就不要提了,直接讓意法半導體流片了(本來想說流X的,算了,我們反正都被忽悠和被折騰麻木了),人家意法半導體那%5專利的MIPS指令是無法逾越的,還有,我們根本沒有高精度的機床,高級的半導體加工技術; 2012註定是不平凡的一年,因為大經濟環境更惡劣了,歐洲最先出大問題,中國的危機來了,危機時期最好用來做內功,而不是揮刀自宮,NB的人把“危”當作“機”,NC的人註定隨波逐流,沒有危機意識,沒有思想,也不敢想,更不要談去做了;而好大喜功的折騰,註定跌進深淵;科技在發展,世界在發展,而現在還出現一大批要返回過去時代的人,這真的是無藥可救了;還有更搞笑的菜刀實名制,這又是一個荒唐的極端;都是倒退; 啰嗦的話就不多說了,網友覺得linux-2.6.32移植對你有參考價值,就幫忙頂一下;還有那些轉載的朋友不要把文章開始的51cto的信息給去掉,本人發覺某個TI中文網站收錄的本人的幾篇文章放到他們論壇去,就去掉本人的博客信息,太不夠職業道德了;

本文出自 「集成系統-踏上文明的征程」 博客,請務必保留此出處http://zjbintsystem.blog.51cto.com/964211/768652





[火星人 via ] DAVINCI DM365-DM368開發攻略——linux-2.6.32的移植已經有381次圍觀

http://www.coctec.com/docs/linux/show-post-46898.html