没有代码的朋友可以从连接中下载 ITE_V12.4_Update.rar,订阅了专栏的朋友可以私聊联系我,我将会把代码直接发送给您,从本篇博文开始,我将使用此套纯净的代码进行相关功能的讲解。
main入口函数概述
学过C语言的人都知道,在C语言中,main函数是代码的入口函数,代码从main函数开始运行,不管你的工程有多么的复杂,我们拿到代码的第一件事情就是找到代码中的main函数,然后从main函数一步一步往下分析代码。
ITE_V12.4中的main函数
其实在代码中不止有一个main函数,我们全局搜索发现会有几个地方有main函数:
那么我们如何确定那个main函数是第一个执行的函数呢?
首先回到51单片机中,在C51中有一个名为startup.a51的文件,该文件为启动程序,启动位置为C_STARTUP:
?C_C51STARTUP SEGMENT CODE
?STACK SEGMENT IDATA
RSEG ?STACK
DS 1
EXTRN CODE (?C_START)
PUBLIC ?C_STARTUP
CSEG AT 0
?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
接着是一个长跳转命令到STARTUP1位置执行:
.
.
.
LJMP ?C_START
END
最后跳转至C_START位置处执行,那么哪个main函数对应的段地址名是C_START,那么谁就是第一个执行的函数。
在EC_BBK.MAP中找到了函数名和代码段地址的对应关系,从中得出C_START对应的代码段地址为0100018BH。那么接下来就是找那个main函数的地址对应为0100018BH。
同样的在EC_BBK.MAP文件中找到:
ITE_BOOT.C中的main函数对应的地址为00018BH,这个地址和前面的C_START对应的代码段地址0100018BH是不是很接近了,因为
0x0100018BH = 0x01000000H + 0x0000018BH
从这张截图的最上方注释可以看到,这个地址对应于CODE MEMORY,即代码内存空间,那么可以找一找代码内存空间的基地址,如果基地址正好为0x01000000H,这ITE_BOOT.C中的main函数即对应C_START。
再回到之前的截图,如下所示:
在C51中,C_STARTUP对应于代码段的基地址,从截图中可以得到该地址为0x01000000H,这样就得到了ITE_BOOT.C中的main函数的代码段对应的地址为代码段基地址加上偏移地址,即:
0x0100018BH(实际地址) = 0x01000000H(代码段基地址) + 0x0000018BH(代码段偏移地址)
得出结论:ITE_BOOT.C中的mian函数为第一个执行的C函数,即C代码的入口函数。
ITE_BOOT.C中main函数如何跳转到CORE_MAIN.C中的main函数
ITE_BOOT.C中的main函数内容:
* ************************************************************************* */
/* CODE START */
/* ************************************************************************* */
void main(void)
{
FUNCT_PTR_V_V code GoMainBoot = 0x1000;
SP = 0xD0;
EA = 0x00;
TMOD = 0x11;
TF0 = TR0 = 0; // Stop timer 0 and clear interrupt
TF1 = TR1 = 0; // Stop timer 1 and clear interrupt
//- - - - - - - - - - - - - - - - -
//Version Information Load...
CORE_Version = KernelCode_Version;
Oem_SubVer = EC_SUB_VER;
Oem_BBKVer = EC_BBK_VER;
Oem_CodeVer = EC_OEM_VER;
Oem_ModelVer = EC_MODEL_VER;
Oem_PCBVer = EC_PCB_VER;
Oem_TestVer = EC_TEST_VER;
//- - - - - - - - - - - - - - - - -
#if !SUPPORTED_EC_BOOT_BLOCK
GoMainBoot();
#endif
if( BB_CheckEntry() ) // Check Entry Condition
{
uBoot_InitGPIO();
uBoot_InitRegs();
BB_Main(); //BL51 Locate: ?PR?BB_MAIN?CORE_BBLOCK(0x0200)
}
GoMainBoot();
}
这里主要关注GoMainBoot函数,首先有一个函数指针赋值,将GoMainBoot的函数指针地址赋值为0x1000,在后面只要执行GoMainBoot函数就会跳转到对应于0x1000的代码地址执行,接下来只要找到0x1000地址(通过前面的介绍知道这个地址肯定是一个偏移地址)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-63tyOMf5-1654871304187)(https://files.mdnice.com/user/30213/7eaa60d6-491f-405d-86ef-30bcae1c518e.png)]
找到CORE_MAIN.C的mian函数对应的地址刚好是001000H,所以在ITE_BOOT.C的main函数中执行GoMainBoot()函数时就会跳转到CORE_MAIN.C中的main函数,就开始执行EC相关的业务逻辑代码了。