28388D上电时从BOOT跳转到main过程分析
上一篇讲到,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过程分析相关推荐
- 我的STM32 IAP BOOT跳转到APP进入HardFault_Handler解决方案
客户要求实现OTA功能,于是程序分BOOT和APP,因需要添加一个浮点型全局变量gfHtTmpValue,发现只要调用这个全局变量,BOOT跳转APP后,APP初始化外设结束进入HardFault_H ...
- Ubuntu更新时遇到/boot空间不足
2019独角兽企业重金招聘Python工程师标准>>> 经常升级Linux内核,导致更新时警告/boot分区空间不足.这是以为多次升级内核后,导致内核版本太多,清理一下没用的内核文件 ...
- 用js做分页,点击下一页时,直接跳到了最后一页——Number()的妙用
Number()的妙用 Number()是javascript中将字符型转换为数值型的函数: 问题描述:做分页,用js实现,获取当前页面的值,然后js自加1,可是点击下一页时,直接跳到最后一页.选择跳 ...
- 1个球从100m落下,每次时,反跳原高度的一半,再落,再反弹,求第10次落地共经过多少m,第10次反弹多高。 谭浩强《c语言程序设计》第五章第十一题
题目 本题是谭浩强<c语言程序设计>第五章第十一题 题目:1个球从100m落下,每次时,反跳原高度的一半,再落,再反弹,求第10次落地共经过多少m,第10次反弹多高. 提示:以下是本篇文章 ...
- 快服务助手卡片测试时为什么不跳转线上快应用?
[问题描述] 卡片测试时直接跳转至快应用本地包,无法跳转到已上线的快应用. 接入方案:卡片类 流量入口: 情景智能&智慧搜索 快服务助手版本:2.4.0版本 [原因分析] 快服务助手测试时 ...
- 解决WORD2013输入时光标老跳的问题
解决WORD2013输入时光标老跳的问题 参考文章: (1)解决WORD2013输入时光标老跳的问题 (2)https://www.cnblogs.com/Alear/p/10224669.html ...
- 硬件电路设计之——DC-DC上电时电压输出尖峰电压
硬件电路设计之--DC-DC上电时电压输出尖峰电压 发现问题 在使用XL1509-5.0E时发现,当电源在上电瞬间会出现一个上升到 8V的尖峰电压.使用的STC单片机好像能抗住这个电压,并且不损坏.但 ...
- esp8266灯上电闪一下_消除esp8266上电时继电器抖动的几种方法
本帖最后由 lwq1947 于 2020-6-17 18:01 编辑 众所周知esp8266在上电时它的一些GPIO端口会有瞬间电平翻转现象,这就导制了在其输出控制的继电器就会突然瞬间吸合一下.这种状 ...
- Esp8266上电时IO抖动解决方案
使用芯片:Esp8266-01s 问题:此芯片在上电瞬间,GPIO0.GPIO2.RX.TX这四个引脚中的三个(在这里,我把四个IO口都设置为普通的GPIO了,也就是RX.TX也设置为GPIO)会通断 ...
- 台达服务器怎么把绝对位置初始化,台达plc上电时参数的自动初始化实例
有关台达plc的编程实例,在台达plc中上电时参数自动初始化的例子,介绍了该编程实例的控制要求,元件说明,以及自动初始化的控制程序的完整代码,程序的功能说明,供大家学习参考. 上电时参数的自动初始化 ...
最新文章
- 转 C++STL之string
- WPF下可编辑Header的Tab控件实现
- 在Linux下怎样让top命令启动之后就按内存使用排序(或CPU使用排序)?
- 正则表达式的深入理解
- 路由器的异步和同步串行接口
- android baidupush
- 缺失值填充6——拉格朗日插值法填充序列缺失值
- 苹果计算机怎么添加在快捷方式,如何在 iPhone 主屏幕上添加文件快捷方式?
- 我们为什么用 Go 编写机器学习架构,却不用 Python?
- 入侵感知系列之弱口令检测思路
- 如何在Visio中绘制KPT模型中的用户(小人)?在哪里找?
- C Sharp进行附合水准路线计算中间点高程简易程序
- BOCHS模拟器配置和使用
- oracle 白鳝 row cache lock,ROW CACHE LOCK导致数据库CPU高案例分析
- 2023二建建筑施工备考第二天Day04
- 计算机理论和地理的关系,计算机辅助地理教学的理论和实践
- Geohash算法的概括
- 在线小工具箱引流网站源码
- 农村居民和谐消费模式构建及实现途径
- 彻底解决快播不可点播方法
热门文章
- 怎样自学python_怎样自学Python?
- c语言中node是数据类型吗,lnode(数据结构lnode是什么类型)
- jquery 图片左右切换,一长条的显示,点击左右移动。
- 配置vhost、https、重定向
- openg-光照贴图
- 【Python打卡2019】20190423之52周存钱挑战-for+range()函数使用
- 那些被苏宁奖励的人、重用的人
- yaahp层次分析法步骤_层次模型构造
- 如何用计算机函数来求加权总分,Excel小技巧-使用函数「SUMPRODUCT」计算加权后的总和及平均值...
- table2excel 导出表格有边框,文字居中