beagelboard-xm下dvsdk移植2:Bug出现的原因和解决

beagelboard-xm上dvsdk移植2:Bug出现的原因和解决。
          

本文均属自己阅读源码的点滴总结,转账请注明出处谢谢。

欢迎和大家交流。qq:1037701636 email:gzzaigcn2009@163.com,gzzaigcn2012@gmail.com

        在前面移植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 <jkridner@beagleboard.org>
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,后发现如下:beagelboard-xm下dvsdk移植2:Bug出现的原因和解决

可以看到,这个cpu reset时默认配置为输入,所以这里必须先进行    *(unsigned long *)(p + 0x34) = 0 << (DEBUG_LED1 % 32);设为输出。实现led轮流显示。