UBOOT代码调试万能模版-C++模版小试牛刀 王凯(光谷)
2016-02-25 16:13
344 查看
1. 概述
UBOOT的代码有其特殊性,如果没有仿真器,难以方便的调试。一般用printf来调试很方便,可是难以将代码的各个逻辑都走到。就笔者个人的经验而言,BUG的出现往往是那些没有注意的逻辑流程出问题,所以代码写好后,每一行都过一遍十分重要。不要想当然的以为,“这个else的情况不可能出现”,或者自以为“这么简单的代码,一定没有问题”。防患于未然才是王道,等到项目快结束的时候,一个难以察觉的到的bug再找起来就很困难了。2. UBOOT中所做的修改
UBOOT中所作的修改用patch的形式来展现,如下:
index 89c5483..74769bf 100644 --- a/booter/lib_arm/bootm.c +++ b/booter/lib_arm/bootm.c @@ -30,6 +30,7 @@ #include <bootimg.h> #include "../yuwei/libra_app.h" +#include "../libra/libra_impl.h" DECLARE_GLOBAL_DATA_PTR; @@ -62,6 +63,31 @@ static struct tag *params; static char bootargs_buffer[1024]; // 定义了一个enum类型 +typedef enum { + otg_null, + otg_device, + otg_host +} otg_type_t; + // 获取当前otg的状态,是device还是host。 +static otg_type_t i_fetch_otg_device_mode(void) { + sram_status_t st; + int passport = PASSCODE; + long ret = lba_sram_status_fetch(&passport, &st); + if (ret != e_ok) { + printf("***lba_sram_status_fetch,ret = %ld***\n", ret); + return otg_null; + } + if ( (st.reserved[13] & (1<<4)) && !(st.reserved[14] & (1<<4)) ) { + return otg_device; + } else if ( !(st.reserved[13] & (1<<4)) && (st.reserved[14] & (1<<4)) ) { + return otg_host; + } else { + printf("st.reserved[13] = 0x%x, st.reserved[14] = 0x%x, is OK???\n", + st.reserved[13], st.reserved[14]); + return otg_null; + } +} + int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) { bd_t *bd = gd->bd; @@ -108,6 +134,7 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) #endif #ifdef CONFIG_CMDLINE_TAG + #if YW_BOARD_TYPE_T6 /* * King add to check board type for recover. @ 2016.01.27 */ @@ -123,9 +150,21 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images) intonum = 0x12; } memset(bootargs_buffer, 0, sizeof(bootargs_buffer)); - sprintf(bootargs_buffer, "%s ywboardtype=%x", - commandline, intonum); + // 上述接口的调用 + otg_type_t otg_type; + char type_str[64]; + memset(type_str, 0, sizeof(type_str)); + if ( (otg_type = i_fetch_otg_device_mode()) == otg_host ) { + strcpy(type_str, "ywotgtype=otg_host"); + printf("otg type = %s\n", type_str); + } else if (otg_type == otg_device) { + strcpy(type_str, "ywotgtype=otg_device"); + printf("otg type = %s\n", type_str); + } // else do nothing... + sprintf(bootargs_buffer, "%s ywboardtype=%x %s", + commandline, intonum, type_str); strcpy(commandline, bootargs_buffer); + #endif
代码说明:
修改的代码很简单。定义了一个enum类型,一个获取otg状态的函数,一个调用者。其中和平台相关的是lba_sram_status_fetch,其他东西都是通用的。lba_sram_status_fetch这个函数的功能是获取平台的静态内存里面的数据,其中和这次修改相关的成员是reserved[13]和reserved[14]。所以,只需要更改reserved[13]和reserved[14]的值,就可以把本次修改的代码逻辑走完。3. C++万能模版的实现
testBaseClass.h
<pre name="code" class="html"><pre name="code" class="html">#ifndef __TESTBASECLASS__H#define __TESTBASECLASS__H#include <libio.h>#include <stdio.h>#include <iostream>using namespace std;template <typename T>class testBaseClass {private:bool status; //定义了一个状态,来判断代码运行过程中是否出错。public:testBaseClass(int arg = 0, T* val = NULL); // 构造函数,默认参数都是0。~testBaseClass() {}virtual void run(void *)=0; // 一个纯虚函数,用作标准的接口。bool getStatus(void) const {return status;}};template <typename T>testBaseClass<T>::testBaseClass(int arg, T* val){int getv;for (int i=0; i<arg; i++) {cout << "Enter a digit: "; // 输入数字的提示cin >> getv; // 将输入的数字存入getvif (val != NULL) {val[i] = getv;} else {status = false;return;}}status = true;}#endif
otgTypeTest.cpp
#include "testBaseClass.h"#include <string.h>// 枚举类型照抄typedef enum {otg_null,otg_device,otg_host} otg_type_t;// 结构体照抄typedef struct sram_sts {int reserved[16];} sram_status_t;// 手动定义了一个全局变量sram_status_t st;// 获取otg状态的函数,平台相关的部分static otg_type_t i_fetch_otg_device_mode(void) {if ( (st.reserved[13] & (1<<4)) && !(st.reserved[14] & (1<<4)) ) {return otg_device;} else if ( !(st.reserved[13] & (1<<4)) && (st.reserved[14] & (1<<4)) ) {return otg_host;} else {printf("st.reserved[13] = 0x%x, st.reserved[14] = 0x%x, is OK???\n",st.reserved[13], st.reserved[14]);return otg_null;}}// 模版的类型是int,目前只实现了int版本,以后会扩充到其他的类型。class otgTypeTest : public testBaseClass<int>{public:otgTypeTest(int argc, int *p) : testBaseClass(argc, p){}void run(void *obj) { // run函数里面填的是当时UBOOT的调用,照抄。otg_type_t otg_type;char type_str[64];memset(type_str, 0, sizeof(type_str));if ( (otg_type = i_fetch_otg_device_mode()) == otg_host ) {strcpy(type_str, "ywotgtype=otg_host");printf("otg type = %s\n", type_str);} else if (otg_type == otg_device) {strcpy(type_str, "ywotgtype=otg_device");printf("otg type = %s\n", type_str);} // else do nothing...}};int main(void){otgTypeTest *test = new otgTypeTest(2, &st.reserved[13]); // reserverd[13],reserved[14]是用从外界输入的,来模拟。if (test->getStatus())test->run(NULL);elsecout << "otgTypeTest obj construct error\n";return 0;}
<pre name="code" class="html"><pre name="code" class="html">
相关文章推荐
- C/C++基础::sizeof() 与 sizeof(string)
- [C++11]_[初级]_[shared_ptr的使用场景]
- [C++11]_[初级]_[shared_ptr的简单使用]
- C++ 拆分字符串
- C++设计模式之工厂模式
- 面试题六 C/C++面试秘笈 之约瑟夫问题的解答--程序员面试题
- C++的运算符重载
- c++模板元编程
- 面试题五 C/C++面试秘笈 之链表的正向排序--程序员面试题
- 请问在VC++2010中如何连接用Access2010创建好的accdb数据库?
- [c++]string中删除相同字符
- C语言 链表的使用(链表的增删查改,链表逆转,链表排序)
- C++ template —— tuple(十三)
- 面试题四 C/C++面试秘笈 之判断链表是否存在环形链表问题-程序员面试题
- c++服务端用webservices【gsoap】做服务端与java后台对接信息的测试工具
- C++虚继承的概念
- 面试题三 C/C++面试秘笈 查找单链表的中间元素 --程序员面试题
- c语言入门之项目4.3——利用for循环求1-1/2*2+1/2*2*2...-1/2*2*2*2到2的8次方
- winodws平台C++共享内存实现
- C++基础知识易错点总结(2)