16.EC实战 入口函数main函数剖析(CORE_MAIN.C中的mian函数是如何跑起来的)


没有代码的朋友可以从连接中下载 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相关的业务逻辑代码了。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三哥编程分享

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值