4. eCos至OMAP 5912 OSK的移植方法
4.3. 系統修改
這一小節會說明系統需要修改的部份檔案。各個需要修改的檔案和該檔案的用 途,請見附錄 5。移植的過程之中,第一步驟是選定 based board,就是用來修改 的基礎,選用 Omap 1510(5910) innovator,先將所有的檔案複製一份在新的資料 夾,並將所有檔案之中含有 innovator 的字眼改成 omap 5912 OSK,牽扯到的用 途包括路徑和 package 的名稱。下面介紹修改的部份時,若只是名稱的更改將不 再贅述。CDL 的命名規則如下<arch>_<variant>_<platform>,<arch>為 arm,
<variant>為 arm9,<platform>是 omap5912。OMAP5912 為 OMAP Innovator 的進 化版本,故 register 和 interrupt vector 都有所不同,register 修改表請見附錄 2[1][20] ; interrupt vector 修 改 表 請 見 附 錄 3[1][20] 。 工 作 路 徑 c:\cygwin\opt\ecos\ecos-2.0\。移植的過程中,最好是每次測試都把電源重接,按 電源鍵只會執行 reset 程序,不一定會重設所有 register,故某些 register 仍會保 留其值,可能造成不可預期的錯誤。
4.3.1. har_arm9.cdl
加入 ARM 926EJS package:
cdl_option CYGPKG_HAL_ARM_ARM9_ARM926EJ { display "ARM ARM926EJ microprocessor"
implements CYGINT_HAL_ARM_ARM9_VARIANT default_value 0
no_define
define -file=system.h CYGPKG_HAL_ARM_ARM9_ARM926EJ
description " The ARM926EJ has 16k data cache, 16k instruction cache, 16 word write buffer and an MMU." }
4.3.2. hal_cache.c 加入 cache 設定;
#elif defined(CYGPKG_HAL_ARM_ARM9_ARM926EJ)
#define CYG_BYTEORDER CYG_MSBFIRST // big endian
#else
#define CYG_BYTEORDER CYG_LSBFIRST // little endian
#endif
4.3.4. mtl_OSK5912_rom.h
調整 memory layout 以符合平台的 layout。在 eCos-2.0 之前有工具可以使用,
但 eCos-2.0 開始就沒有這個功能,只能手動設定。
下三項是 RAM 相關的設定,依序為 address, size, 和 access 限制;
#define CYGMEM_REGION_ram (0x00000000)
#define CYGMEM_REGION_ram_SIZE (0x04000000)
#define CYGMEM_REGION_ram_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
接著三項是 RoM 相關的設定,依序為 address, size, 和 access 限制;
#define CYGMEM_REGION_rom (0x0C000000)
#define CYGMEM_REGION_rom_SIZE (0x04000000)
#define CYGMEM_REGION_rom_ATTR (CYGMEM_REGION_ATTR_R | CYGMEM_REGION_ATTR_W)
最後這三項是設定可用的 heap 大小;
extern char CYG_LABEL_NAME (__heap1) [];
#define CYGMEM_SECTION_heap1 (CYG_LABEL_NAME (__heap1))
#define CYGMEM_SECTION_heap1_SIZE (0x04000000 - (size_t) CYG_LABEL_NAME (__heap1))
4.3.5. Osk5912_misc.c
MMU 的設定在 Osk5912_misc.c 裡面的 hal_mmu_init()。以下面第一段為例 子,MMU 的 function name 為 X_ARM_MMU_SECTION(),其中參數,頭一個 為 actual base address,接著是 virtual base address,第三個是以 MB 為單位的 size,
第四個還第五個指示是否 cache 或 buffer,最後一個表明 access 的形態。第一段 是 Chip select 0 的設定,本身是屬於 External memory,actual base memory 在 0x0000 0000,virtual base address 在 0x0C00 0000,有 cache 但沒有 buffer。
X_ARM_MMU_SECTION (0x000, 0x0C0, 64, ARM_CACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // CS0
X_ARM_MMU_SECTION (0x100, 0x000, 64, ARM_CACHEABLE, ARM_BUFFERABLE, ARM_ACCESS_PERM_RW_RW); // CS3
X_ARM_MMU_SECTION (0x200, 0x200, 1, ARM_UNCACHEABLE, ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // Internal SRAM
X_ARM_MMU_SECTION (0xE00, 0xE00, 512, ARM_UNCACHEABLE,
ARM_UNBUFFERABLE, ARM_ACCESS_PERM_RW_RW); // Internal Peripherals
4.3.6. hal_arm_arm9_omap5912.cdl / hal_OSK5912.cdl
OMAP 5912OSK 的 GPP 處理器和 OMAP Innovator 不同,改成 ARM926EJ,
5912 OSK 發 展 板 需 要 更 改 requires CYGPKG_HAL_ARM_ARM9_ARM926EJ,以及新增 register 的 default vakye 設 定,形式為 cdl option,並在 CYGPKG_HAL_OSK5912 package 之中加入 require 的 限 制 。 但 是 處 理 器 编 號 延 用 innovator 即 可 ; #define HAL_PLATFORM_MACHINE_TYPOE 234。表 4 為 register default value:
Table 4. 5912 register default value
VAL_FUNC_MUX_CTRL_3_WORD 0x09249FFF VAL_FUNC_MUX_CTRL_4_WORD 0x3FE00001 VAL_FUNC_MUX_CTRL_5_WORD 0x3F4BFFFF VAL_FUNC_MUX_CTRL_6_WORD 0x00000001 VAL_FUNC_MUX_CTRL_7_WORD 0x00001000 VAL_FUNC_MUX_CTRL_8_WORD 0x00001200 VAL_FUNC_MUX_CTRL_9_WORD 0x00201008 VAL_FUNC_MUX_CTRL_A_WORD 0x00000000 VAL_FUNC_MUX_CTRL_B_WORD 0x00000000 VAL_FUNC_MUX_CTRL_C_WORD 0x09000000 VAL_FUNC_MUX_CTRL_D_WORD 0x09249438 VAL_FUNC_MUX_CTRL_E_WORD 0x09249249 VAL_FUNC_MUX_CTRL_F_WORD 0x00000049 VAL_FUNC_MUX_CTRL_10_WORD 0x00000000 VAL_FUNC_MUX_CTRL_11_WORD 0x00000000 VAL_FUNC_MUX_CTRL_12_WORD 0x00000000 VAL_PULL_DWN_CTRL_0_WORD 0x00000000 VAL_PULL_DWN_CTRL_1_WORD 0x00040000 VAL_PULL_DWN_CTRL_2_WORD 0x00000000 VAL_PULL_DWN_CTRL_3_WORD 0x00000000 VAL_PULL_DWN_CTRL_4_WORD 0x00000000 VAL_PU_PD_SEL_0_WORD 0x00000000
VAL_PU_PD_SEL_1_WORD 0x00000000 VAL_PU_PD_SEL_2_WORD 0x00000000 VAL_PU_PD_SEL_3_WORD 0x00000000 VAL_PU_PD_SEL_4_WORD 0x00000000 VAL_VOLTAGE_CTRL_0_WORD 0x00000000 VAL_MOD_CONF_CTRL_0_WORD 0x000000000 VAL_ARM_CKCTL_WORD 0x000a VAL_ARM_SYSST_WORD 0x0000 VAL_DPLL1_CTL_WORD 0x2413
4.3.7. Omap5912.h
修正更改或新增的 register address,所需要修改的 register 如附錄 2。截取一 段如下
#define GPIO1_BASE 0xFFFBE400
#define _GPIO_REVISION 0x00
#define _GPIO_SYSCONFIG 0x10
#define GPIO1_REVISION (vcyg16 *)(GPIO1_BASE + _GPIO_REVISION)
#define GPIO1_SYSCONFIG (vcyg16 *)(GPIO1_BASE + _GPIO_SYSCONFIG)
4.3.8. hal_omap5912_setup.h / hal_platform_setup.h
定 義 stack pointer base ; #define OMAP5912_PLATFORM_SP_BASE 0x10000000。Register 有新增或移除,相對它的 initial value 必須要修改。例如 GPIO 的 configuration;
ldr r0,=GPIO_BASE+_DIRECTION_CONTROL_REG ldr r1,=CYGOPT_SET_GPIO_CONF
str r1,[r0]
EMIFF 的 MRS(mode register set) EMIFF_MRS,已經不再使用,而新增 EMIFF_MRS_NEW,可以更彈性的設定,於是更改如下,前一段是 innovator
code,第二段是 5912 OSK code:
ldr r0, REG_TC_EMIFF_MRS ldr r1, VAL_TC_EMIFF_MRS str r1, [r0]
ldr r1, =VAL_TC_EMIFF_MRS_NEW_WORD ldr r0, =EMIFF_MRS_NEW
str r1, [r0]
4.3.9. hal_platform_ints.h
新增及刪除 peripheral 的因素,必須修正 interrupt vector,以及 isr 數量也需 修改。Interrupt vector 的數量由 54 個擴增到 93 個,請見附錄 3。最後再修改 ISR 相關定義:
#define CYGNUM_HAL_ISR_MIN 1
#define CYGNUM_HAL_ISR_MAX 93
4.3.10. omap5912_redboot_comds.c / OSK5912_redboot_comds.c
這兩個檔案是 redboot 的一部份,可以加入新的指令在 redboot 中使用。譬 如 5912 新增 GPIO,我們就可以新增對 GPIO pin 填值的指令,利用 HAL_API 來實作出 access 動作:
RedBoot_cmd(
"gpio",
"Read, Write, or Configure a GPIO pin",
"-p pin_num [-i|-o] [-s val] [-r] [-R] [-c] [-I] [-O] [-C]", do_gpio);
static void do_gpio(int argc, char *argv[]){
HAL_WRITE_UINT16();
HAL_READ_UINT16();)
4.3.11. omap5912_diag.c / hal_diag.h
diagnostic output support 是利用 UART 經過 serial port 傳輸,可以想像它是 在 HAL 層對 serial port 的使用,比 serial device driver 更高一個層級。所以在這 裡我們只需確定 UART 1 based address 的正確即可,其它方面不必修改。
4.3.12. OSK5912_misc.c
由於發展板上記憶體配置使用上的不同,在 hal_mmu_init()裡面如同前述 MMU 的設定做出我們欲使用的配置。在 hardware initial 部份,新增 disable watchdog timer 和 mux initial 分別是 plf_disable_wdt()和 plf_init _mux(),下列是 initial mux 的 例 子 。 若 要 使 用 LCD 功 能 FUNC_MUX_CTRL_A 到 FUNC_MUX_CTRL_12 必需保留硬體設定值。下面舉一個例子:
HAL_WRITE_UINT32(FUNC_MUX_CTRL_3, VAL_FUNC_MUX_CTRL_3_WORD);
4.3.13. Plf_io.h
設定 virtual address 與 physical address 的 mapping。5912 與 innovator 之間 Flash 的 mapping 不同,因此改成 5912 的設定,先列出 innovator 的設定,再列 出 5912 的設定:
#define HACK_FLASH_VIRT_BASE 0x10000000
#define HACK_FLASH_SIZE 0x00400000
#define HACK_FLASH_MASK 0x003fffff
#define HACK_FLASH_PHYS_BASE 0x00000000
#define HACK_FLASH_VIRT_BASE 0x0c000000
#define HACK_FLASH_SIZE 0x02000000
#define HACK_FLASH_MASK 0x01ffffff
#define HACK_FLASH_PHYS_BASE 0x00000000
4.3.14. plf_stub.h
除了 5912 命名,其他不需修改。
4.3.15. Redboot_ROM-net.ecm
這個是設定最後 redboot 的功能,要包含所須的 package:
cdl_configuration eCos { description "" ;
hardware OSK5912 ; template redboot ;
package -hardware CYGPKG_HAL_ARM current ; package -hardware CYGPKG_HAL_ARM_ARM9 current ;
package -hardware CYGPKG_HAL_ARM_ARM9_OMAP5912 current ; package -hardware CYGPKG_DEVS_FLASH_STRATA current ; package -hardware CYGPKG_DEVS_FLASH_OSK5912 current ; package -hardware CYGPKG_DEVS_ETH_SMSC_LAN91CXX current ; package -hardware CYGPKG_DEVS_ETH_ARM_OSK5912 current ; package -template CYGPKG_HAL current ;
package -template CYGPKG_INFRA current ; package -template CYGPKG_REDBOOT current ; package -template CYGPKG_ISOINFRA current ; package -template CYGPKG_LIBC_STRING current ; package -template CYGPKG_NS_DNS current ; package -template CYGPKG_CRC current ; package CYGPKG_MEMALLOC current ; package CYGPKG_IO_FLASH current ;
package CYGPKG_IO_ETH_DRIVERS current ; package CYGPKG_COMPRESS_ZLIB current ;
package -hardware CYGPKG_HAL_OSK5912 current ; };
package 之後接 hardware 代表該 package 是個硬體,若接 template 則是包含 了內部的部份設定。若有 conflict,configtool 會自動修正,但要注意的是只會修 正 一 層 , 例 如 加 入 package CYGPKG_LIBC_TIME 會 自 動 加 入 需 要 的
CYGSEM_LIBC_TIME_TIME_WORKING , 但 是
CYGSEM_LIBC_TIME_TIME_WORKING 又 需 要
CYGPKG_IO_WALLCLOCK,這就不會自動加入了。
4.3.16. ser_omap5912.cdl
由於 innovator 沒有序列埠的使用程式,於是由相同晶片的 integrator 修改。
UART 晶片型號: NS16550 (National Semiconductor)。總共有三個 UART,UART1 以 UART3 是由 ARM 來使用,UART2 是由 DSP 來使用,UART 定址如表 5。需 要設定 name, baud-rate, and buffer size:
cdl_option CYGDAT_IO_SERIAL_OMAP5912_SERIAL0_NAME: {"\"/dev/ser0\""}
cdl_option CYGNUM_IO_SERIAL_OMAP5912_SERIAL0_BAUD: 115200 cdl_option CYGNUM_IO_SERIAL_OMAP5912_SERIAL0_BUFSIZE: 128
Table 5. UART 位址
UART Address
UART 1 0xFFFB 0000
UART 2 0xFFFB 0800
UART 3 0xFFFB 9800
此外還要注意 baud-rate divisor 的設定,OMAP5912OSK 使用的設定是 26。
baud-rate divisor = RS232 時脈 / (baud-rate * 16。最後,每個 device 都要 device table 註冊才可以使用,DEVTAB_ENTRY(l, name, dep_name, handlers, init, lookup, priv),需要的資料如下:
z l: device table entry 的 C label。
z name: C string device name。
z dep_name: 下一層 device 的 device name。
z Handlers: I/O device 的 handler。
z Init: eCos 初始化時的 function call,其作用是 query the device 和設定硬 體。
z Lookup: 當 cyg_io_lookup()對該 device 執行時,回應的 function call。
z Priv: device 的 object。
4.3.17. devs_eth_OSK5912.inl
設定 5912 OSK 上 Ethernet base address,使用 CS1 bank:
static lan91cxx_priv_data lan91cxx_eth0_priv_data = { base : (unsigned short *) 0x0480 0300, …。
controller 和 5910 相 同 為 smsc 91c96 , 所 以 延 用 innovator 的 程 式 。 Controller space 定址在 CS1。為什麼不在 I/O device 區? Ethernet 與 Compact Flash Card 的彈性使用為原因:可以設定 CF card 使用 CS1,而 Ethernet 使用 CS2;或 是只有 Ethernet,其使用 CS1。
經由對 output register 填入 data,若有順利傳送出去,control status register 會 被填值,以聲名 ethernet 的連線成功。但並非一次就可以完成,於是我們得多等 幾次,甚至無限迴圈等到傳送成功為止。所以可能在 boot 過程的前面會出現 no link 的 message , 直 到 link 成 功 為 止 。 我 們 在 OSK5912_misc.c 之 中 , plf_hardware_init()加入這一段 code,包括相關設定以及達到上述效果:
#define ETH_CONTROL_REG 0x0480000b
*((volatile unsigned short *) 0xfffece08) = 0x03FF;
*((volatile unsigned short *) 0xfffb3824) = 0x8000;
*((volatile unsigned short *) 0xfffb3830) = 0x0000;
*((volatile unsigned short *) 0xfffb3834) = 0x0009;
*((volatile unsigned short *) 0xfffb3838) = 0x0009;
*((volatile unsigned short *) 0xfffb3818) = 0x0002;
*((volatile unsigned short *) 0xfffb382C) = 0x0048;
*((volatile unsigned short *) 0xfffb3824) = 0x8603;
hal_delay_us(3);
*((volatile unsigned short *) 0xfffb381C) = 0x6610;
hal_delay_us(30);
*((volatile unsigned char *) ETH_CONTROL_REG) &= ~0x01;
hal_delay_us(3);
Tftp 的使用,在 redboot 之下,使用指令可以取得在 pc 端 tftp root 資料夾的 檔案: load –v –m tftp filename。在 kernel 之下,依照 embedded software development with eCos[18],之中步驟 build 出 kernel。欲使用 tftp 必需再加入幾 個 package:
package CYGPKG_NET current ;
package CYGPKG_NET_FREEBSD_STACK current ; package CYGPKG_IO_FILEIO current ;
和填入 eth0 相關網路設定,如下:
cdl_component CYGHWR_NET_DRIVER_ETH0_ADDRS {user_value 1};
cdl_option CYGHWR_NET_DRIVER_ETH0_ADDRS_IP {user_value 140.113.208.18};
cdl_option CYGHWR_NET_DRIVER_ETH0_ADDRS_BROADCAST {user_value 140.113.208.255};
cdl_option CYGHWR_NET_DRIVER_ETH0_ADDRS_GATEWAY {user_value 140.113.208.254};
cdl_option CYGHWR_NET_DRIVER_ETH0_ADDRS_SERVER
{user_value 140.113.208.183 };
並使用 tftp_get() / tftp_put(); 在程式之中即可。
4.3.18. OSK5912_eth_drivers.cdl
CYGSEM_DEVS_ETH_ARM_OSK5912_ETH0_SET_ESA 可 以 設 定 MAC address 由板子上的 EEPROM 讀取,或由使用者設定。我們己知板子的 MAC address,就直接使用使用者設定。
CYGDAT_DEVS_ETH_ARM_OSK5912_ETH0_ESA 可以設定 MAC address