上一篇讲到,DSP的BOOT流程是:

上电 =》从0x3F FFC0开始取复位中断向量=》跳转到InitBoot =》启动系统boot (StartSystemBoot)。

在系统boot里面,如果配置选择的是waitBoot模式,就会停在一个死循环中。那么,如果不是waitBoot模式,而是FLASH_BOOT模式呢?接下来继续分析。

FLASH_BOOT模式

首先,看看CPU1BROM_startSystemBoot()函数的最后:

    //// Enter specified wait boot or enable watchdog, then branch to address//if(CPU1BROM_bootMode == WAIT_BOOT){SysCtl_enableWatchdog();for(;;){}}else if(CPU1BROM_bootMode == WAIT_BOOT_ALT1){for(;;){}}else{SysCtl_enableWatchdog();return(entryAddress);}

如果不是WAIT_BOOT(或者WAIT_BOOT_ALT1),则进入else分析,开启开门狗,返回程序入口地址。如果是FLASH_BOOT,则entryAddress = 0x 0008 0000。这个值作为函数的返回值,保存在ACC寄存器里。后面会用到的!

CPU1BROM_startSystemBoot函数被调用的地方在这里:

cpu1brom_init_boot.asm文件中:    LCR    CPU1BROM_startSystemBoot

;
; Branch to system initialization to run final initializations and execute boot mode
;LCR    CPU1BROM_startSystemBoot;
; Function: ExitPBISTLoc
;
; Cleanup and exit after PBIST. At this point the EntryAddr
; is located in the ACC register
;
ExitPBISTLoc:BF      ExitBoot,UNC

因此,CPU1BROM_startSystemBoot函数返回后继续执行:    BF      ExitBoot,UNC

退出系统BOOT

ExitBoot函数如下:

;
; Function: ExitBoot
;
; This module cleans up after boot
;
; 1) Make sure the stack is re-initialized
; 2) Push 0 onto the stack so RPC will be
;    0 after using LRETR to jump to the
;    entry point
; 2) Load RPC with the entry point
; 3) Clear all XARn registers
; 4) Clear ACC, P and XT registers
; 5) LRETR - this will also clear the RPC
;    register since 0 was on the stack
;
ExitBoot:
;
;   Insure that the stack is re-initialized
;MOV     SP,#__stack;
; Clear the bottom of the stack.  This will endup
; in RPC when we are finished
;MOV     *SP++,#0MOV     *SP++,#0;
; Load RPC with the entry point as determined
; by the boot mode.  This address will be returned
; in the ACC register.
;PUSH    ACCPOP     RPC;
; Put registers back in their reset state.
;
; Clear all the XARn, ACC, XT, and P and DP
; registers
;
; NOTE: Leave the device in C28x operating mode
;       (OBJMODE = 1, AMODE = 0)
;ZAPAMOVL    XT,ACCMOVZ    AR0,ALMOVZ    AR1,ALMOVZ    AR2,ALMOVZ    AR3,ALMOVZ    AR4,ALMOVZ    AR5,ALMOVZ    AR6,ALMOVZ    AR7,ALMOVW    DP, #0;
;   Restore ST0 and ST1.  Note OBJMODE is
;   the only bit not restored to its reset state.
;   OBJMODE is left set for C28x object operating
;   mode.
;
;  ST0 = 0x0000     ST1 = 0x0A0B
;  15:10 OVC = 0    15:13      ARP = 0
;   9: 7  PM = 0       12       XF = 0
;      6   V = 0       11  M0M1MAP = 1
;      5   N = 0       10  reserved
;      4   Z = 0        9  OBJMODE = 1
;      3   C = 0        8    AMODE = 0
;      2  TC = 0        7 IDLESTAT = 0
;      1 OVM = 0        6   EALLOW = 0
;      0 SXM = 0        5     LOOP = 0
;                       4      SPA = 0
;                       3     VMAP = 1
;                       2    PAGE0 = 0
;                       1     DBGM = 1
;                       0     INTM = 1
;MOV     *SP++,#0MOV     *SP++,#0x0A0BPOP     ST1POP     ST0;
;   Jump to the EntryAddr as defined by the
;   boot mode selected and continue execution
;LRETR

最关键的是下面几句:

    PUSH    ACCPOP     RPCLRETR

前面提到了,CPU1BROM_startSystemBoot函数返回时,把下一段程序的入口地址保存在ACC寄存器里。这里先把ACC压栈,再出栈到RPC里!到这时,RPC就保存了下一段程序的地址,就是FLASH的入口地址0x0008 0000。

跳转到FLASH入口

当执行LRETR时,RPC的值就会加载到PC中,CPU跳转到FLASH的入口开始执行。

现在,调试器也显示到f2838x_codestartbranch.asm文件中的code_start了:

到这个时候,已经脱离了厂家内置在CPU中的boot了,运行到用户领空。后面的代码跟用户及编译器有关了。

跳转到_c_int00

再往下,就是关闭看门狗,跳转到_c_int00。

    .if WD_DISABLE == 1.text
wd_disable:SETC OBJMODE        ;Set OBJMODE for 28x object codeEALLOW              ;Enable EALLOW protected register accessMOVZ DP, #7029h>>6  ;Set data page for WDCR registerMOV @7029h, #0068h  ;Set WDDIS bit in WDCR to disable WDEDIS                ;Disable EALLOW protected register accessLB _c_int00         ;Branch to start of boot._asm in RTS library.endif

_c_int00也是有源代码的:boot28.asm。这个文件位置跟编译器的安装路径和编译器的版本有关。

比如,我使用的编译器版本是V16.9.1,对应的boot28.asm文件在:

D:\ti\ccs1040\ccs\tools\compiler\ti-cgt-c2000_16.9.1.LTS\lib\src\boot28.asm

主要功能是初始化全局变量:c_int, DO_BINIT, DO_PINT, _const_init

当所有的初始化完成之后,马上就要到main函数了。稍等一下,在进入main之前,还有最后一道关:args_main

调用__args_main

最后的关键时刻,先调用__args_main。如果函数返回了,则再调用_exit。

BYPASS_AUTO_INIT:
****************************************************************************
*  CALL USER'S PROGRAM                                                     *
****************************************************************************LCR     __args_main         ; execute main()LCR     _exit.endasmfunc

__args_main函数是C代码,在args_main.c文件中:

int _args_main()
{
#pragma diag_suppress 1107,173register ARGS *pargs = (ARGS*)_symval(&__c_args__);
#pragma diag_default 1107,173register int    argc = 0;register char **argv = 0;if (_symval(&__c_args__) != NO_C_ARGS) { argc = pargs->argc; argv = pargs->argv; }return main(argc, argv);
}

至此,已经完整地走完了孕育过程,main函数即将降临!让我们一起期待main函数的精彩表现吧!

28388D上电时从BOOT跳转到main过程分析相关推荐

  1. 我的STM32 IAP BOOT跳转到APP进入HardFault_Handler解决方案

    客户要求实现OTA功能,于是程序分BOOT和APP,因需要添加一个浮点型全局变量gfHtTmpValue,发现只要调用这个全局变量,BOOT跳转APP后,APP初始化外设结束进入HardFault_H ...

  2. Ubuntu更新时遇到/boot空间不足

    2019独角兽企业重金招聘Python工程师标准>>> 经常升级Linux内核,导致更新时警告/boot分区空间不足.这是以为多次升级内核后,导致内核版本太多,清理一下没用的内核文件 ...

  3. 用js做分页,点击下一页时,直接跳到了最后一页——Number()的妙用

    Number()的妙用 Number()是javascript中将字符型转换为数值型的函数: 问题描述:做分页,用js实现,获取当前页面的值,然后js自加1,可是点击下一页时,直接跳到最后一页.选择跳 ...

  4. 1个球从100m落下,每次时,反跳原高度的一半,再落,再反弹,求第10次落地共经过多少m,第10次反弹多高。 谭浩强《c语言程序设计》第五章第十一题

    题目 本题是谭浩强<c语言程序设计>第五章第十一题 题目:1个球从100m落下,每次时,反跳原高度的一半,再落,再反弹,求第10次落地共经过多少m,第10次反弹多高. 提示:以下是本篇文章 ...

  5. 快服务助手卡片测试时为什么不跳转线上快应用?

    [问题描述] 卡片测试时直接跳转至快应用本地包,无法跳转到已上线的快应用. 接入方案:卡片类 流量入口: 情景智能&智慧搜索 快服务助手版本:2.4.0版本 [原因分析]   快服务助手测试时 ...

  6. 解决WORD2013输入时光标老跳的问题

    解决WORD2013输入时光标老跳的问题 参考文章: (1)解决WORD2013输入时光标老跳的问题 (2)https://www.cnblogs.com/Alear/p/10224669.html ...

  7. 硬件电路设计之——DC-DC上电时电压输出尖峰电压

    硬件电路设计之--DC-DC上电时电压输出尖峰电压 发现问题 在使用XL1509-5.0E时发现,当电源在上电瞬间会出现一个上升到 8V的尖峰电压.使用的STC单片机好像能抗住这个电压,并且不损坏.但 ...

  8. esp8266灯上电闪一下_消除esp8266上电时继电器抖动的几种方法

    本帖最后由 lwq1947 于 2020-6-17 18:01 编辑 众所周知esp8266在上电时它的一些GPIO端口会有瞬间电平翻转现象,这就导制了在其输出控制的继电器就会突然瞬间吸合一下.这种状 ...

  9. Esp8266上电时IO抖动解决方案

    使用芯片:Esp8266-01s 问题:此芯片在上电瞬间,GPIO0.GPIO2.RX.TX这四个引脚中的三个(在这里,我把四个IO口都设置为普通的GPIO了,也就是RX.TX也设置为GPIO)会通断 ...

  10. 台达服务器怎么把绝对位置初始化,台达plc上电时参数的自动初始化实例

    有关台达plc的编程实例,在台达plc中上电时参数自动初始化的例子,介绍了该编程实例的控制要求,元件说明,以及自动初始化的控制程序的完整代码,程序的功能说明,供大家学习参考. 上电时参数的自动初始化 ...

最新文章

  1. 转 C++STL之string
  2. WPF下可编辑Header的Tab控件实现
  3. 在Linux下怎样让top命令启动之后就按内存使用排序(或CPU使用排序)?
  4. 正则表达式的深入理解
  5. 路由器的异步和同步串行接口
  6. android baidupush
  7. 缺失值填充6——拉格朗日插值法填充序列缺失值
  8. 苹果计算机怎么添加在快捷方式,如何在 iPhone 主屏幕上添加文件快捷方式?
  9. 我们为什么用 Go 编写机器学习架构,却不用 Python?
  10. 入侵感知系列之弱口令检测思路
  11. 如何在Visio中绘制KPT模型中的用户(小人)?在哪里找?
  12. C Sharp进行附合水准路线计算中间点高程简易程序
  13. BOCHS模拟器配置和使用
  14. oracle 白鳝 row cache lock,ROW CACHE LOCK导致数据库CPU高案例分析
  15. 2023二建建筑施工备考第二天Day04
  16. 计算机理论和地理的关系,计算机辅助地理教学的理论和实践
  17. Geohash算法的概括
  18. 在线小工具箱引流网站源码
  19. 农村居民和谐消费模式构建及实现途径
  20. 彻底解决快播不可点播方法

热门文章

  1. 怎样自学python_怎样自学Python?
  2. c语言中node是数据类型吗,lnode(数据结构lnode是什么类型)
  3. jquery 图片左右切换,一长条的显示,点击左右移动。
  4. 配置vhost、https、重定向
  5. openg-光照贴图
  6. 【Python打卡2019】20190423之52周存钱挑战-for+range()函数使用
  7. 那些被苏宁奖励的人、重用的人
  8. yaahp层次分析法步骤_层次模型构造
  9. 如何用计算机函数来求加权总分,Excel小技巧-使用函数「SUMPRODUCT」计算加权后的总和及平均值...
  10. table2excel 导出表格有边框,文字居中