This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TMS570LS1227:在 RAM 被初始化之前访问 RAM

Guru**** 1794070 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/573725/ccs-tms570ls1227-access-ram-before-ram-has-been-initialized

器件型号:TMS570LS1227

工具/软件:Code Composer Studio

您好!

我想在 ECC RAM 初始化之前访问 RAM 并在 CPU 寄存器中抓取几个字节。 但是、当 RAM 损坏或器件未通过写入 SYSECR 来执行复位时、我不想这么做。

我想知道应该检查哪个寄存器?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Charlie、

    SYSESR 寄存  器(请参阅 SPNU515中的2.5.1.49)将告诉您复位源是什么。

    但我认为您不能仅仅根据对复位状态的了解来得出有关 RAM 状态(损坏、有效)的任何结论。

    也许您可以排除某些不想查看 RAM 内容的情况、例如、您可能不想读取它们

    在 SWRST 之后、如果这是您"不通过写入 SYSECR 来执行复位"的意思。

    但是、从不能保证读取 RAM 不会读取 ECC 错误的位置。   这是您需要考虑的问题
     即使在系统启动并运行后、仍然可能出现软错误(通常可纠正)。

    无论如何、我想说、您应该在您希望通过复位保留在 RAM 中的任何信息上实施某种编码方案、这样、您就不可能(您很可能决定)让器件随机加电、看起来"有效"。    例如、您可能希望自己的软件 ECC 比 SECDED 强得多、但涵盖您尝试验证的 RAM (小)块。  

    我认为硬件功能集中没有任何我可以放心地依靠它来实现这一目的的东西。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我使用 RAM 将信息从主应用程序传递到引导加载程序。 我对用户代码块1、5、31、38的修改。 我读取存储器位置以进行寄存器、并在 RAM 初始化完成后再次保存到存储器位置

    /**@file sys_startup.c
    *@简要启动源文件
    *@日期2016年10月5日
    *@版本04.06.00
    *
    *此文件包含:
    *-包含文件
    *-类型定义
    *-外部功能
    *- VIM RAM 设置
    *-启动例程
    *。
    与启动相关的*。
    */
    
    *
    版权所有(C) 2009-2016德州仪器(TI)公司- www.ti.com
    *
    
    *
    *只要
    符合以下条件*,就允许以源代码和二进制形式重新分发和使用,无论是否进行*修改:
    *
    *源代码的重新分发必须保留上述版权
    声明*、此条件列表和以下免责声明。
    *
    *二进制形式的再发行必须在
    
    *
    发行版随附的*文档和/或其他材料中复制上述版权声明、本条件列表和以下免责声明。
    *
    *未经
    
    事先书面许可、不得使用德州仪器公司的名称或*其贡献者的名称认可或推广从本软件派生的产品*。
    *
    *本软件由版权所有者和贡献者
    *按原样"提供、
    
    且不承认任何明示或暗示的保证、包括但不限于*特定用途*的适销性和适用性的暗示保证。 在任何情况下、版权
    *所有者或贡献者都不对任何直接、间接、偶然、
    *特殊、模范、 或相应的损害(包括但不
    限于*采购替代产品或服务;丧失使用、
    *数据或利润; 或业务中断)、但出于
    任何*责任理论、无论是合同、严格责任还是侵权
    行为*(包括疏忽或其他原因)、即使
    被告知可能会造成此类损坏、也是出于此类责任理论。
    *
    */
    
    
    *用户代码开始(0)*/
    /*用户代码结束*
    
    
    /*包含文件*/
    
    #include "sys_common.h"
    #include "sys_vim.h"
    
    #include "sys_core.h"
    #include "sys_breme.h"#include "mibne.h"
    
    
    
    *
    / userbcode.h"
    
    
    
    ***/bide.h"(包含"sys_code.h"*/code.h"*/ne.h"*/code.h"*/usbide"/bidegine.h"*/us.ide.h"
    /*用户代码结束*/*
    
    
    外部函数*/*SAFETYMCUSW
    218 S MR:20.2. "库中的函数"*/
    extern void __TI_auto_init (void);
    /*SAFETYMCUSW 354 S MR:NA "启动代码(主代码应由用户声明)"*/
    extern int main (void);
    /* SAFETYMCUSW 122 S MR:20.11 "启动代码(需要存在 EXIT 和 ABORT)"*/
    /* SAFETYMCUSW 354 S MR:NA "启动代码(库中存在示例声明)"*/
    extern void exit (int _status);
    
    
    //用户代码开始(3)*/
    //*用户代码结束*/
    
    *启动例程*/
    void _c_int00 (void);
    /* USER CODE BEGIN (4)*/*
    /* USER CODE END */
    
    #pragma CODE_STATE (_c_int00,32)
    #pragma INTERRUPT (_c_int00,RESET)
    #pragma WEAK (_c_int00)
    
    //* ceId:startup_sourceId_001 */*
    DesignHL:startup_DesignId_001 *
    
    
    */void *(*/?00)要求*/*/* void
    
    /*用户代码开始(5)*/
    #if defined (for_bootloader)|| defined (bootloader)
    注册 uint32_t tmp;
    #endif
    //用户代码结束*
    
    /*初始化内核寄存器以避免 CCM 错误*/
    _coreInitRegisters_();
    
    /*用户代码开始(6)*/
    /*用户代码结束*/
    
    /*初始化堆栈指针*/
    _coreInitStackPointer_();
    
    //用户代码开始(7)*//
    *用户代码结束*
    
    /*启用 CPU 事件导出*/
    /*这允许 CPU 发出检测到的任何单位或双位错误的信号
    *通过其 ECC 逻辑访问程序闪存或数据 RAM。
    *
    _coreEnableEventBusExport_();
    //用户代码开始(9)*/*
    用户代码结束*/
    
    /*为闪存访问启用 CPU 指示的 ECC 错误响应*/
    flashWREG->FEDACCTRL1 = 0x000A060AU;
    
    //用户代码开始(10)*/
    *用户代码结束*/
    
    /*为 ATCM (闪存访问)启用 CPU ECC 检查*/
    _coreEnableFlashEcc_();
    
    
    /*用户代码开始(11)*/
    /*用户代码结束*/
    
    /* Errata CORTEXR4的权变措施66 */
    _errata_CORTEXR4_66_();
    
    /*勘误表 CORTEXR4 57的权变措施*/
    _errata_CORTEXR4_57_();
    
    /*复位处理程序:以下指令从系统异常状态寄存器中读取
    *以确定 CPU 复位的原因。
    *
    
    /*检查上电复位条件*/
    /*SAFETYMCUSW 139 S MR:13.7 "硬件状态位读取检查"*/
    if ((SYS_EXception & powerON_RESET)!= 0U)
    {
    //*用户代码开始(12)*/
    //*用户代码结束*/
    
    /*清除所有复位状态标志*/
    SYS_EXception = 0xFFFFFFU;
    
    //用户代码开始(13)*/
    //*用户代码结束*/
    *用户代码开始(14)*/
    //*用户代码结束*/
    *用户代码开始(15)*/
    *用户代码结束*/
    /*继续正常启动序列*/
    }
    /*SAFETYMCUSW 139 S MR:13.7 "硬件状态位读取检查"*/
    如果((SYS_EXception & OSC_failure_reset)!= 0U)则为其他
    {
    /*由于振荡器故障导致的复位。
    在此处添加用户代码以处理振荡器故障*/*
    
    用户代码开始(16)*/*
    用户代码结束*/
    }
    /*SAFETYMCUSW 139 S MR:13.7 "硬件状态位读取检查"*/
    如果((SYS_EXCE异常 和安全装置复位)!=0U)则为其他
    {
    /*复位原因
    * 1)窗口式看门狗违规-在此处添加用户代码以处理看门狗违规。
    * 2) ICEPICK 复位-通过 CCS 加载代码/通过 CCS 复位系统之后
    *
    /*检查看门狗状态寄存器*/
    if (watchdog_status!= 0U)
    {
    /*在此处添加用户代码以处理看门狗违规。 */
    *用户代码开始(17)*/
    *用户代码结束*/
    
    /*清除异常状态寄存器中的看门狗复位标志*/
    SYS_EXception =安全装置复位;
    
    /*用户代码开始(18)*/*
    用户代码结束*/
    }
    其他
    {
    /*清除异常状态寄存器中的 ICEPICK 复位标志*/
    SYS_EXCE异常= ICEPICK_RESET;
    //用户代码开始(19)*/
    //用户代码结束*/
    }
    }
    /*SAFETYMCUSW 139 S MR:13.7 "硬件状态位读取检查"*/
    否则((SYS_EXCE异常 和 CPU_RESET)!=0U)
    {
    /*由于 CPU 复位导致的复位。
    CPU 复位可能由 CPU 自检完成、或引起
    通过切换 CPU 复位控制寄存器的"CPU RESET"位。 */
    
    *用户代码开始(20)*/
    */*用户代码结束*/
    
    /*清除所有复位状态标志*/
    SYS_EXception = CPU_RESET;
    
    //用户代码开始(21)*/
    //*用户代码结束*/
    
    }
    /*SAFETYMCUSW 139 S MR:13.7 "硬件状态位读取检查"*/
    否则((SYS_EXception & SW_RESET)!= 0U)
    {
    /*由于软件复位导致的复位。
    添加用户代码以处理软件复位。 */
    
    /*用户代码开始(22)*/
    /*用户代码结束*/
    }
    其他
    {
    /*由外部驱动低电平的 nRST 引起的复位。
    添加用户代码以处理外部复位。 */
    
    *用户代码开始(23)*/
    *用户代码结束*/
    }
    
    /*检查加电期间是否存在 ESM 组3错误。
    *这些可能发生在电子保险丝自动加载期间或从闪存 OTP 读取期间
    *在加电期间。 器件运行不可靠、不建议这样做
    *。
    * ESM 组3错误仅将 nERROR 引脚驱动为低电平。 外部电路
    *监控 nERROR 引脚的器件必须采取适当的措施来确保这一点
    *系统被置于安全状态,由应用程序确定。
    *
    if ((esmREG->SR1[2])!= 0U)
    {
    //用户代码开始(24)*/
    #if 0
    //用户代码结束*/
    /*SAFETYMCUSW 5 C MR:NA "for (;;)可通过在上述和下方的用户代码中添加"#if 0"和"#endif"来删除。"*/
    /*SAFETYMCUSW 26 S MR:NA "for (;;)可通过在上述和下方的用户代码中添加"#if 0"和"#endif"来删除。"*/
    /*SAFETYMCUSW 28 D MR:NA "for (;;)可通过在上述和下方的用户代码中添加"#if 0"和"#endif"来删除。"*/
    for (;;)
    {
    }/*等待*/
    /*用户代码开始(25)*/
    #endif
    //用户代码结束*/
    }
    
    /*用户代码开始(26)*/
    /*用户代码结束*/
    
    /*初始化系统-时钟、闪存设置、带 Efuse 自检*/
    systemInit();
    
    /* Errata PBIST#4权变措施*/
    errata_PBIST_4 ();
    
    /*对内存自检控制器运行诊断检查。
    *此函数选择 RAM 测试算法并在片上 ROM 上运行。
    *内存自检预计会失败。 该功能可确保 PBIST 控制器
    *能够检测并指示内存自检失败。
    *
    pbistSelfCheck();
    
    /*在 STC ROM 上运行 PBIST */
    pbistRun (((uint32) STC_ROM_PBIST_RAM_GROUP、
    (((uint32) PBIST_TripleReadSlow |(uint32) PBIST_TripleReadFast);
    
    /*等待 PBIST 完成 STC ROM *
    /*SAFETYMCUSW 28 D MR:NA "硬件状态位读取检查"*/
    while (pbistIsTestCompled()!= true)
    {
    }/*等待*/
    
    /*检查 STC ROM 上的 PBIST 是否通过自检*/
    if (pbistIsTestPassed()!= true)
    {
    /* PBIST 和 STC ROM 自检失败。
    *需要自定义处理程序来检查内存故障
    *并执行适当的下一步。
    *
    
    pbistFae();
    
    }
    
    /*禁用 PBIST 时钟并禁用内存自检模式*/
    pbistStop();
    
    /*在 PBIST ROM 上运行 PBIST */
    PbistRun (((uint32) PBIST_ROM_PBIST_RAM_GROUP、
    (((uint32) PBIST_TripleReadSlow |(uint32) PBIST_TripleReadFast);
    
    /*等待 PBIST 完成 PBIST ROM *
    /*SAFETYMCUSW 28 D MR:NA "硬件状态位读取检查"*/
    while (pbistIsTestCompled()!= true)
    {
    }/*等待*/
    
    /*检查 PBIST ROM 是否通过自检*/
    if (pbistIsTestPassed()!= true)
    {
    /* PBIST 和 STC ROM 自检失败。
    *需要自定义处理程序来检查内存故障
    *并执行适当的下一步。
    *
    
    pbistFae();
    
    }
    
    /*禁用 PBIST 时钟并禁用内存自检模式*/
    pbistStop();
    /*用户代码开始(29)*/
    /*用户代码结束*/
    
    *用户代码开始(31)*/
    #if defined (for_bootloader)|| defined (bootloader)
    tmp = reboot_state;
    #endif
    //用户代码结束*/
    
    /*在为主 RAM 执行 PBIST 之前禁用 RAM ECC */
    _coreDisableRamEcc_();
    
    /*在 CPU RAM 上运行 PBIST。
    *需要为单端口和双端口 SRAM 分别配置 PBIST 控制器。
    * CPU RAM 是单端口内存。 所有片载 SRAM 的实际"RAM 组"在中定义
    *器件数据表。
    *
    PbistRun (0x00300020U、/* ESRAM 单端口 PBIST *
    (uint32) PBIST_March13N_SP);
    
    //用户代码开始(32)*/
    //*用户代码结束*/
    
    /*等待 PBIST 完成 CPU RAM */
    /*SAFETYMCUSW 28 D MR:NA "硬件状态位读取检查"*/
    while (pbistIsTestCompled()!= true)
    {
    }/*等待*/
    
    
    /*用户代码开始(33)*/
    /*用户代码结束*/
    
    /*检查 CPU RAM 是否通过自检*/
    if (pbistIsTestPassed()!= true)
    {
    /* CPU RAM 未通过自检。
    *需要自定义处理程序来检查内存故障
    *并执行适当的下一步。
    */
    *用户代码开始(34)*/
    *用户代码结束*/
    
    pbistFae();
    
    /*用户代码开始(35)*/*
    用户代码结束*/
    }
    
    /*用户代码开始(36)*/
    /*用户代码结束*/
    
    /*禁用 PBIST 时钟并禁用内存自检模式*/
    pbistStop();
    
    
    /*用户代码开始(37)*/
    /*用户代码结束*/
    
    
    /*初始化 CPU RAM。
    *此函数使用系统模块的硬件对存储器及其进行自动初始化
    *相关的保护方案。 通过将 MSIENA 寄存器的位0置位来初始化 CPU RAM。
    *因此、值0x1传递给函数。
    *此函数将初始化整个 CPU RAM 和相应的 ECC 位置。
    *
    memoryInit (0x1U);
    
    //用户代码开始(38)*/
    #if defined (for_bootloader)|| defined (bootloader)
    reboot_state = tmp;
    #endif
    //用户代码结束*/
    
    /*启用 TCRAM 访问的 ECC 检查。
    *此函数为 B0TCM 和 B1TCM 的访问启用 CPU 的 ECC 逻辑。
    *
    _coreEnableRamEcc_();
    
    /*用户代码开始(39)*/
    /*用户代码结束*/
    
    /*在所有双端口存储器上启动 PBIST */
    /*注:有关支持的双端口内存列表,请参阅设备数据表。
    PBIST 测试只在 HALCoGen 的 GUI 安全初始选项卡中用户选择的存储器上执行。
    *
    PbistRun((UINT32) 0x00000000U /* EMAC RAM */
    |(UINT32) 0x00000000U // USB RAM */
    |(UINT32) 0x00000800U // DMA RAM */
    |(UINT32) 0x00000200U // VIM RAM */
    |(UINT32) 0x00000040U // MIBSPI1 RAM */
    |(UINT32) 0x00000080U // MIBSPI3 RAM */
    |(UINT32) 0x00000100U // MIBSPI5 RAM *
    |(UINT32) 0x00000004U // CAN1 RAM */
    |(UINT32) 0x00000008U // CAN2 RAM */
    |(UINT32) 0x00000010U // CAN3 RAM */
    |(UINT32) 0x00000400U // ADC1 RAM */
    |(UINT32) 0x00000000U // ADC2 RAM */
    |(UINT32) 0x00001000U // HET1 RAM */
    |(UINT32) 0x00000000U // HET2 RAM */
    |(UINT32) 0x00002000U // HTU1 RAM *
    |(UINT32) 0x00000000U // HTU2 RAM *
    |(UINT32) 0x00000000U // RTP RAM *
    |(UINT32) 0x00000000U //帧 RAM */
    ,(uint32) PBIST_March13N_DP);
    
    //用户代码开始(40)*/
    //*用户代码结束*/
    
    /*测试 RAM 访问的 CPU ECC 机制。
    *校验 BxRAMECC 函数会在 TCRAM 访问中引起故意的单位和双位错误
    * ECC 中的1或2位。 从 TCRAM 位置读取时出现2位错误
    *在 ECC 中导致数据中止异常。 数据中止处理程序将被写入以查找
    *故意引起异常并将代码执行返回到指令中
    *跟随导致中止的中断。
    *
    checkRAMECC ();
    
    //用户代码开始(41)*//
    *用户代码结束*/
    
    /*测试闪存访问的 CPU ECC 机制。
    * checkFlashECC 函数使用闪存接口模块的诊断模式7
    *在 CPU 对闪存的访问中创建单位和双位错误。 一个双位
    读取闪存时出错会导致数据中止异常。
    *编写数据中止处理程序是为了查找故意引起的异常和
    *将代码执行返回到已中止的指令之后的指令。
    *
    *
    checkFlashECC();
    flashWREG->FDIAGCTRL = 0x000A0007U; /*禁用闪存诊断模式*/
    
    /*用户代码开始(42)*/
    /*用户代码结束*/
    
    /*用户代码开始(43)*/
    /*用户代码结束*/
    
    /*等待 PBIST 完成 CPU RAM */
    /*SAFETYMCUSW 28 D MR:NA "硬件状态位读取检查"*/
    while (pbistIsTestCompled()!= true)
    {
    }/*等待*/
    
    
    /*用户代码开始(44)*/*
    用户代码结束*/
    
    /*检查 CPU RAM 是否通过自检*/
    if (pbistIsTestPassed()!= true)
    {
    
    //*用户代码开始(45)*/
    //*用户代码结束*/
    
    /* CPU RAM 未通过自检。
    *需要自定义处理程序来检查内存故障
    *并执行适当的下一步。
    */
    *用户代码开始(46)*/
    *用户代码结束*/
    
    pbistFae();
    
    /*用户代码开始(47)*/*
    用户代码结束*/
    }
    
    /*用户代码开始(48)*/
    /*用户代码结束*/
    
    /*禁用 PBIST 时钟并禁用内存自检模式*/
    pbistStop();
    
    /*用户代码开始(55)*/*
    用户代码结束*/
    
    /*从本地复位中释放 MibSPI1模块。
    *这将使 MibSPI1 RAM 与奇偶校验存储器一起被初始化。
    *
    mibspiREG1->GCR0 = 0x1U;
    
    /*从本地复位中释放 MibSPI3模块。
    *这将使 MibSPI3 RAM 与奇偶校验存储器一起被初始化。
    *
    mibspiREG3->GCR0 = 0x1U;
    
    /*从本地复位中释放 MibSPI5模块。
    *这将使 MibSPI5 RAM 与奇偶校验存储器一起被初始化。
    *
    mibspiREG5->GCR0 = 0x1U;
    
    /*用户代码开始(56)*/*
    用户代码结束*/
    
    /*在选定 RAM 上启用奇偶校验*/
    enableParity ();
    
    /*初始化除 MibSPIx RAM 之外的所有片上 SRAM
    * MibSPIx 模块有它们自己的被触发的自动初始化机制
    *一旦模块退出本地复位。
    *
    /*如果该模块仍处于本地复位状态、则系统模块自动初始化将在 MibSPI RAM 上挂起。
    *
    /*注:有关支持的内存列表及其通道号,请参阅设备数据表。
    内存初始化仅在 HALCoGen 的 GUI 安全初始化选项卡中用户选择的内存上执行。
    *
    memoryInit((UINT32)((UINT32) 1U <<1U )/* DMA RAM */
    |(uint32)((uint32) 1U << 2U)/* VIM RAM */
    |(UINT32)((UINT32) 1U << 5U)/* CAN1 RAM */
    |(UINT32)((UINT32) 1U << 6U)/* CAN2 RAM */
    |(UINT32)((UINT32) 1U << 10U)/* CAN3 RAM */
    |(uint32)((uint32) 1U << 8U)/* ADC1 RAM */
    |(uint32)((uint32) 0U << 14U)/* ADC2 RAM */
    |(uint32)((uint32) 1U << 3U)/* HET1 RAM */
    |(uint32)((uint32) 1U << 4U)/* HTU1 RAM */
    |(uint32)((uint32) 0U << 15U)/* HET2 RAM */
    |(UINT32)((UINT32) 0U << 16U)/* HTU2 RAM */
    );
    
    /*禁用奇偶校验*/
    disableParity ();
    
    /*测试外围 RAM 的奇偶校验保护机制
    注:有关支持奇偶校验的内存列表,请参阅设备数据表。
    奇偶校验自检仅在 HALCoGen 的 GUI 安全初始选项卡中用户选择的存储器上执行。
    */
    
    *用户代码开始(57)*/
    /*用户代码结束*/
    
    het1ParityCheck();
    
    /*用户代码开始(58)*/*
    用户代码结束*/
    
    htu1ParityCheck();
    
    /*用户代码开始(61)*/*
    用户代码结束*/
    
    adc1ParityCheck();
    
    /*用户代码开始(63)*/*
    用户代码结束*/
    
    can1ParityCheck();
    
    /*用户代码开始(64)*/
    /*用户代码结束*/
    
    can2ParityCheck();
    
    /*用户代码开始(65)*/*
    用户代码结束*/
    
    can3ParityCheck();
    
    /*用户代码开始(66)*/
    /*用户代码结束*/
    
    vimParityCheck();
    
    /*用户代码开始(67)*/*
    用户代码结束*/
    
    dmaParityCheck();
    
    
    /*用户代码开始(68)*/*
    用户代码结束*/*
    
    SAFETYMCUSW 28 D MR:NA "硬件状态位读取检查"*/
    while (((mibspiREG1->FLG & 0x01000000U)=0x01000000U)
    {
    }/*等待*/
    //等待 MibSPI1 RAM 完成初始化*/*
    SAFETYMCUSW 28 D MR:NA "硬件状态位读取检查"*/
    while (((mibspiREG3->FLG & 0x01000000U)=0x01000000U)
    {
    }/*等待*/
    //等待 MibSPI3 RAM 完成初始化*/*
    SAFETYMCUSW 28 D MR:NA "硬件状态位读取检查"*/
    while (((mibspiREG5->FLG & 0x01000000U)=0x01000000U)
    {
    }/*等待*/
    /*等待 MibSPI5 RAM 完成初始化*/*
    
    用户代码开始(69)*/
    /*用户代码结束*/
    
    mibspi1ParityCheck();
    
    /*用户代码开始(70)*/
    /*用户代码结束*/
    
    mibspi3ParityCheck();
    
    /*用户代码开始(71)*/*
    用户代码结束*/
    
    mibspi5ParityCheck();
    
    
    /*用户代码开始(72)*/*
    用户代码结束*/
    
    /*通过 Vic 控制器启用 IRQ 偏移*/
    _coreEnableIrqVicOffset_();
    
    
    /*用户代码开始(73)*/
    /*用户代码结束*/
    
    /*初始化 VIM 表*/
    vimInit();
    
    /*用户代码开始(74)*/*
    用户代码结束*/
    
    /*配置系统对发送给 ESM 组1的错误条件的响应*/
    /*可以从 HALCoGen 的"ESM"选项卡配置此函数*/
    esmInit();
    /*初始化复制表*/
    __TI_auto_init();
    //用户代码开始(75)*/
    //用户代码结束*/
    
    /*调用应用程序*/*SAFETYMCUSW
    296 S MR:8.6 "启动代码(块范围内的库函数)"*/
    /* SAFETYMCUSW 326 S MR:8.2 "startup code (Declaration for main in library)"*/
    /* SAFETYMCUSW 60 D MR:8.8 "启动代码(库中 main 的声明;仅为相同操作 extern)"*/
    MAIN();
    
    //用户代码开始(76)*//
    //*用户代码结束*//
    * SAFETYMCUSW 122 S MR:20.11 "启动代码(需要存在 EXIT 和 ABORT)"*/
    EXIT (0);
    
    /*用户代码开始(77)*/
    /*用户代码结束*/
    }
    
    /*用户代码开始(78)*/
    /*用户代码结束*/