本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。
欢迎和大家交流。qq:1037701636 email:[email protected],[email protected]
在前面移植1中,本文主要介绍了bb-xm 上dvsdk移植出现的几个Bug和我的解决方法。主要来自于xload.
编译完成后,xload启动不了,原因如下:
1.下载的补丁脚本没有对xload执行patch相关操作,虽然下载了补丁但是没有完成实际打补丁的操作,需要对Setup-dvsdk-4-01-beaglexm-110126.sh内容做一定的修改
# Apply the patches to the local repository for patchfile in ${XLOADPATCHESSTRIPPED} ; do git am oepatches/$patchfile done cd ..这里的操作不会完成patch的内容,原因暂时不知,需修改为以下内容:
# Apply the patches to the local repository for patchfile in ${XLOADPATCHESSTRIPPED} ; do # git am oepatches/$patchfile git am --abort git apply oepatches/$patchfile done
2.xload编译后系统不能启动,原因是下载到的x-load-beagle源码缺少一个补丁xmc.patch
From b35937bf29c828e311f1d9bb1385bd32d34ec060 Mon Sep 17 00:00:00 2001 From: Jason Kridner <[email protected]> Date: Mon, 7 Mar 2011 19:31:15 -0600 Subject: [PATCH] Forced newer revisions to default to xM. --- board/omap3530beagle/omap3530beagle.c | 15 ++++++++++++++- 1 files changed, 14 insertions(+), 1 deletions(-) diff --git a/board/omap3530beagle/omap3530beagle.c b/board/omap3530beagle/omap3530beagle.c index 1b3d8c7..d55d32e 100644 --- a/board/omap3530beagle/omap3530beagle.c +++ b/board/omap3530beagle/omap3530beagle.c @@ -212,6 +212,7 @@ u32 cpu_is_3410(void) * GPIO173, GPIO172, GPIO171: 1 1 0 => C1/2/3 * GPIO173, GPIO172, GPIO171: 1 0 1 => C4 * GPIO173, GPIO172, GPIO171: 0 0 0 => XM + * default => XM ******************************************/ int beagle_revision(void) { @@ -227,6 +228,18 @@ int beagle_revision(void) rev = omap_get_gpio_datain(173) << 2 | omap_get_gpio_datain(172) << 1 | omap_get_gpio_datain(171); + + /* Default newer board revisions to XM */ + switch(rev) { + case REVISION_AXBX: + case REVISION_CX: + case REVISION_C4: + break; + case REVISION_XM: + default: + rev = REVISION_XM; + } + omap_free_gpio(171); omap_free_gpio(172); omap_free_gpio(173); @@ -662,7 +675,7 @@ int misc_init_r(void) printf("Beagle Rev C4\n"); break; case REVISION_XM: - printf("Beagle xM Rev A\n"); + printf("Beagle xM\n"); break; default: printf("Beagle unknown 0x%02x\n", rev); -- 1.6.1回到这个补丁所添加的代码,我们可以发现,在board/omap3530beagle/omap3530beagle.c中添加了部分代码,为何这部分代码的缺损会造成xload不能正常启动,下面从xload的启动流程做简单介绍。
从x-load-beagle/board/omap3530beagle下的xload.s启动,运行start.s汇编代码对CPU做一定的初始化,最终跳入start_armboot执行C语言代码部分(位于lib/board.c)中:
void start_armboot (void) { init_fnc_t **init_fnc_ptr; int i, size; uchar *buf; int *first_instruction; block_dev_desc_t *dev_desc = NULL; for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { if ((*init_fnc_ptr)() != 0) { hang (); } } misc_init_r(); buf = (uchar*) CFG_LOADADDR; #ifdef CONFIG_MMC /* first try mmc */ if (mmc_init(1)) { size = file_fat_read("u-boot.bin", buf, 0); if (size > 0) { #ifdef CFG_PRINTF printf("Loading u-boot.bin from mmc\n"); #endif buf += size; } } #endif if (buf == (uchar *)CFG_LOADADDR) { /* if no u-boot on mmc, try onenand or nand, depending upon sysboot */ if (get_mem_type() == GPMC_ONENAND){ #ifdef CFG_PRINTF printf("Loading u-boot.bin from onenand\n"); #endif for (i = ONENAND_START_BLOCK; i < ONENAND_END_BLOCK; i++){ if (!onenand_read_block(buf, i)) buf += ONENAND_BLOCK_SIZE; } } else if (get_mem_type() == GPMC_NAND){ #ifdef CFG_PRINTF printf("Loading u-boot.bin from nand\n"); #endif for (i = NAND_UBOOT_START; i < NAND_UBOOT_END; i+= NAND_BLOCK_SIZE){ if (!nand_read_block(buf, i)) buf += NAND_BLOCK_SIZE; /* advance buf ptr */ } } } /* if u-boot not found on mmc or * nand read result is erased data * then serial boot */ first_instruction = (int *)CFG_LOADADDR; if((buf == (uchar *)CFG_LOADADDR) || (*first_instruction == 0xffffffff)) { printf("u-boot.bin not found or blank nand contents - attempting serial boot . . .\n"); do_load_serial_bin(CFG_LOADADDR, 115200); } /* go run U-Boot and never return */ ((init_fnc_t *)CFG_LOADADDR)(); /* should never come here */ }这部发的代码很好理解,首先完成几个指针函数的初始化如下所示:
init_fnc_t *init_sequence[] = { cpu_init, /* basic cpu dependent setup */ board_init, /* basic board dependent setup */ #ifdef CFG_NS16550_SERIAL serial_init, /* serial communications setup */ #endif print_info, nand_init, /* board specific nand init */ #ifdef CONFIG_MMC init_func_i2c, #endif NULL, };这里比较重要的是serial_init初始化,复杂后续信息的打印输出。随后执行函数misc_init_r,安装源码的理解是读取当前板子的具体型号通过beagle_revision()实现,而此处就是我们的xload不能正常启动的原因所在。
int beagle_revision(void) { int rev; int b; omap_request_gpio(171); omap_request_gpio(172); omap_request_gpio(173); omap_set_gpio_direction(171, 1); omap_set_gpio_direction(172, 1); omap_set_gpio_direction(173, 1); rev = omap_get_gpio_datain(173) << 2 | omap_get_gpio_datain(172) << 1 | omap_get_gpio_datain(171); /* Default newer board revisions to XM */ /*switch(rev) { case REVISION_AXBX: case REVISION_CX: case REVISION_C4: break; case REVISION_XM:*/ //default: // rev = REVISION_XM; // } omap_free_gpio(171); omap_free_gpio(172); omap_free_gpio(173); return rev; }安装源码的理解,这里首先会对GPIO_171,172,173进行信号读取,通过rev来判断当前beagleboard是什么版本。而这里问题产生的原因就在于rev读取出来是2即010电平
(与本板子型号beagleboard-xm REVC符号),这个情况下,在整个程序里都没有出现对010这个信号量的解析。如果缺少switch这个函数,rev=2返回使得后续函数处理不了,因为只对如下Revsion进行了定义:
/* BeagleBoard revisions */
#define REVISION_AXBX 0x7
#define REVISION_CX 0x6
#define REVISION_C4 0x5
#define REVISION_XM 0x0
因此如果加上了当前注释掉的代码,那么rev返回0,后续的程序就可以继续处理,程序就不会卡死。
最好的解决方法是#define REVISION_XM 0x2,这样整个xload在做初始化时都不会产生错误的bug.
3.在使用hang()函数时出现的错误(该函数会使系统一直对led进行操作),但是我在调用时发现源码有误:
#define DEBUG_LED1 149 /* gpio */ #define DEBUG_LED2 150 /* gpio */ void blinkLEDs() { void *p; /* Alternately turn the LEDs on and off */ p = (unsigned long *)OMAP34XX_GPIO5_BASE; while (1) { /* turn LED1 on and LED2 off */ *(unsigned long *)(p + 0x94) = 1 << (DEBUG_LED1 % 32); *(unsigned long *)(p + 0x90) = 1 << (DEBUG_LED2 % 32); /* delay for a while */ delay(1000); /* turn LED1 off and LED2 on */ *(unsigned long *)(p + 0x90) = 1 << (DEBUG_LED1 % 32); *(unsigned long *)(p + 0x94) = 1 << (DEBUG_LED2 % 32); /* delay for a while */ delay(1000); } }在这部发简单的操作led的代码中,可以发现没有对GPIO_149,150进行I/0口工作模式的操作,我以以前的编程经验,一般这种复用的I/O口肯定需要先申明是输入或者输出,参考TRM,后发现如下:
可以看到,这个cpu reset时默认配置为输入,所以这里必须先进行 *(unsigned long *)(p + 0x34) = 0 << (DEBUG_LED1 % 32);设为输出。实现led轮流显示。