TC397 SOTA代码实现

上一篇主要介绍了TC397 SOTA相关配置寄存器,此篇主要讲解TC397 SOTA的实现过程,在开始之前先做如下的约定:
a : 在标准地址映射中活动的Bank称为A Bank
b : 在备用地址映射中活动的Bank称为B Bank

1、TC397 SOTA的初始化过程
一个全新的TC397芯片,SOTA的功能是未开启的且此种状态下使用的标准地址映射,因此可以按照一下的操作步骤启动TC397 的SOTA功能,下面的x取值范围0~15。
a : 用调试器把APP镜像烧写到A Bank和B Bank地址处
b : 向MARKERLx寄存器中写入0x00000055
c : 向MARKERHx寄存器中写入MARKERL0寄存器的地址
d : 向CONFERMATIONLx寄存器中写入0x57B5327F
f : 向CONFERMATIONHx寄存器中写入CONFERMATIONx寄存器的地址
g : 向UCB_OPT0中的SWAPEN(bit16和bit17)中写入1,来使能SOTA
h : 下电重启TC397
经过上面的配置过程,TC397在重启后便会进入SOTA模式,如果是新片子,经过一次操作,便会在重启后执行B Bank区域的代码。
在英飞凌的手册中也给出了如下的操作流程图供我们参考,如下所示:
TC397 SWAP 初始化配置
2、TC397 SOTA RunTime Configuration
上面1中提到是初始状态进行一次SOTA操作,接下来我们看看SOTA启用后,是怎么进行APP更新的,首先先看手册中的流程图,后面再对此流程图进行解释。
SOTA Runtime configuration
根据上图以及个人调试SOTA的经验,进行如下的总结:
a : 此时TC397已经处于SOTA激活的状态了
b : 通过活动的Bank(B Bank)将新的APP程序写入到未激活的B Bank(比如A Bank)中,同时根据写入后的Bank 选择标准地址映射还是备用地址映射。
c : 先配置Bank 交换,根据当前激活的Bank来选择下一次复位后使用标准地址映射还是备用地址映射,即根据当前的Bank状态来更新UCB_SWAP_ORIG_MARKERLx+1寄存器的值是写0x00000055还是写0x000000AA。
d : 然后向UCB_SWAP_ORIG_CONFIRMATIONLx+1寄存器中写入0x57B5327F。
e : 接着往UCB_SWAP_ORIG_CONFIRMATIONHx+1寄存器中写入UCB_SWAP_ORIG_CONFIRMATIONLx+1寄存器的地址。
f : 然后向UCB_SWAP_ORIG_CONFIRMATIONLx寄存中写入0xFFFFFFFF,使当前UCB_SWAP_ORIG内容失效。
g : 最后向UCB的配置写入到UCB SWAP FLASH中。

3、TC397 SOTA 功能代码
在讲解代码之前,先做几点说明:
a : UCB FLASH Bank的特性是需要先进行擦除操作,然后才能进行写操作

3.1 UCB_SWAP_Enable的代码实现

void UCB_SWAP_Enable(void)
{
    unsigned short safetyWdtPassword;
    safetyWdtPassword = Ifx_Ssw_getSafetyWatchdogPassword();

    Ifx_DMU_HF_PROCONTP *pHF_PROCONTP = (Ifx_DMU_HF_PROCONTP *)0xAF4041E8;

    if(pHF_PROCONTP->B.SWAPEN != UCB_SWAP_EN)
    {
        Ifx_DMU_HF_PROCONTP HF_PROCONTP;
        HF_PROCONTP.B.SWAPEN   = UCB_SWAP_EN;
        HF_PROCONTP.B.CPU0DDIS = CPUX_DIS;
        HF_PROCONTP.B.CPU1DDIS = CPUX_DIS;
        HF_PROCONTP.B.CPU2DDIS = CPUX_DIS;
        HF_PROCONTP.B.CPU3DDIS = CPUX_DIS;
        HF_PROCONTP.B.CPU4DDIS = CPUX_DIS;
        HF_PROCONTP.B.CPU5DDIS = CPUX_DIS;

        FlashUcb_waitUnbusy();
        Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
        FlashUcb_eraseSector(UCB_DMU_OTP_ADDRESS);
        Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);

        FlashUcb_waitUnbusy();
        FlashUcb_enterPageMode();
        FlashUcb_waitUnbusy();
        FlashUcb_loadPage2X32(HF_PROCONTP.U, 0x00000000);
        Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
        FlashUcb_writePage(UCB_DMU_HF_PROCONTP);
        Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);

        FlashUcb_waitUnbusy();
        FlashUcb_enterPageMode();
        FlashUcb_waitUnbusy();
        FlashUcb_loadPage2X32(UCB_SWAP_UNLOCKED, 0x00000000);
        Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
        FlashUcb_writePage(UCB_OTP0_ORIG_CODE);
        Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);
        FlashUcb_waitUnbusy();
    }

}

3.2 UCB_SWAP_Disable代码实现

void UCB_SWAP_Disable(void)
{
    unsigned short safetyWdtPassword;
    safetyWdtPassword = Ifx_Ssw_getSafetyWatchdogPassword();

    Ifx_DMU_HF_PROCONTP *pHF_PROCONTP = (Ifx_DMU_HF_PROCONTP *)0xAF4041E8;

    if(pHF_PROCONTP->B.SWAPEN != UCB_SWAP_EN)
    {
        Ifx_DMU_HF_PROCONTP HF_PROCONTP;
        HF_PROCONTP.B.SWAPEN   = UCB_SWAP_DIS;
        HF_PROCONTP.B.CPU0DDIS = CPUX_DEN;
        HF_PROCONTP.B.CPU1DDIS = CPUX_DEN;
        HF_PROCONTP.B.CPU2DDIS = CPUX_DEN;
        HF_PROCONTP.B.CPU3DDIS = CPUX_DEN;
        HF_PROCONTP.B.CPU4DDIS = CPUX_DEN;
        HF_PROCONTP.B.CPU5DDIS = CPUX_DEN;

        FlashUcb_waitUnbusy();
        Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
        FlashUcb_eraseSector(UCB_DMU_OTP_ADDRESS);
        Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);

        FlashUcb_waitUnbusy();
        FlashUcb_enterPageMode();
        FlashUcb_waitUnbusy();
        FlashUcb_loadPage2X32(HF_PROCONTP.U, 0x00000000);
        Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
        FlashUcb_writePage(UCB_DMU_HF_PROCONTP);
        Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);

        FlashUcb_waitUnbusy();
        FlashUcb_enterPageMode();
        FlashUcb_waitUnbusy();
        FlashUcb_loadPage2X32(UCB_SWAP_UNLOCKED, 0x00000000);
        Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
        FlashUcb_writePage(UCB_OTP0_ORIG_CODE);
        Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);
        FlashUcb_waitUnbusy();
    }
}
在这里插入代码片

3.3 Swap_Init 代码实现

void Swap_Init(void)
{
    uint8 i = 0;
    Swap_Flag = FALSE;
    Swap.ActiveMarkerNumber = 0;

    if(A_BANK == SCU_SWAPCTRL.B.ADDRCFG)
    {
        Swap.ActiveBank = SWAP_A_BANK_ACTIVE;
    }
    else if(B_BANK == SCU_SWAPCTRL.B.ADDRCFG)
    {
        Swap.ActiveBank = SWAP_B_BANK_ACTIVE;
    }
    else
    {
        Swap.ActiveBank = SWAP_ACTIVE_ILLEGAL;
    }

    Confirm_Value = (*(uint32 *)UCB_SWAP_ORIG_CONFIRMATION_ADDRESS);
    if((Confirm_Value == UCB_SWAP_UNLOCKED) || (Confirm_Value == UCB_SWAP_CONFIRMED))
    {
        Swap.ActiveUCB = UCB_SWAP_ORIG_ACTIVE;
        Swap.ActiveAddress = UCB_SWAP_ORIG_ADDRESS;
    }
    else
    {
        Swap.ActiveUCB = UCB_SWAP_COPY_ACTIVE;
        Swap.ActiveAddress = UCB_SWAP_COPY_ADDRESS;
    }

    for(i = 0; i < UCB_SWAP_SIZE; i++)
    {
        Swap.UCB.US.CONFIRMATIONLx = (*(uint32 *)(Swap.ActiveAddress + 0x00000008));
        if(Swap.UCB.US.CONFIRMATIONLx != UCB_SWAP_CONFIRMED)
        {
            Swap.ActiveAddress = Swap.ActiveAddress + 0x00000010;
        }
        else
        {
            Swap.ActiveMarkerNumber = i;
            break;
        }
    }

    if(i >= (UCB_SWAP_SIZE -1))
    {
        Swap.ActiveMarkerNumber = 0;
        Swap.EraseAtNextSwap = TRUE;
        if(Swap.ActiveUCB == UCB_SWAP_ORIG_ACTIVE)
        {
            Swap.ActiveAddress = UCB_SWAP_ORIG_ADDRESS + 0xF0;
        }
        else
        {
            Swap.ActiveAddress = UCB_SWAP_COPY_ADDRESS + 0xF0;
        }
    }

}
在这里插入代码片

3.4 SOTA Runtim Configuration 代码实现


void Swap_Swich(void)
{
    unsigned short safetyWdtPassword;
    unsigned short swapOrigCopy = 0;

    if(Swap_Flag == TRUE)
    {
        Swap_Flag = FALSE;

        safetyWdtPassword = Ifx_Ssw_getSafetyWatchdogPassword();
        IfxCpu_disableInterrupts();

        if(Swap.EraseAtNextSwap == TRUE)
        {
            Swap.EraseAtNextSwap = FALSE;
            swapOrigCopy = 1;

            FlashUcb_waitUnbusy();
            Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
            if(Swap.ActiveBank == UCB_SWAP_ORIG_ACTIVE)
            {
                FlashUcb_eraseSector(UCB_SWAP_COPY_ADDRESS);
            }
            else
            {
                FlashUcb_eraseSector(UCB_SWAP_ORIG_ADDRESS);
            }
            Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);

            FlashUcb_waitUnbusy();
            FlashUcb_enterPageMode();
            FlashUcb_waitUnbusy();
            FlashUcb_loadPage2X32(UCB_SWAP_UNLOCKED, 0x00000000);

            Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
            if(Swap.ActiveUCB == UCB_SWAP_ORIG_ACTIVE)
            {
                FlashUcb_writePage(UCB_SWAP_COPY_CONFIRMATION_ADDRESS);
                Swap.ActiveAddress = UCB_SWAP_COPY_ADDRESS;
            }
            else if(Swap.ActiveUCB == UCB_SWAP_COPY_ACTIVE)
            {
                FlashUcb_writePage(UCB_SWAP_ORIG_CONFIRMATION_ADDRESS);
                Swap.ActiveAddress = UCB_SWAP_ORIG_ADDRESS;
            }
            Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);
            FlashUcb_waitUnbusy();
        }
        else
        {
            FlashUcb_waitUnbusy();
            FlashUcb_enterPageMode();
            FlashUcb_waitUnbusy();
            FlashUcb_loadPage2X32(UCB_SWAP_INVALIDATION, UCB_SWAP_INVALIDATION);
            Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
            FlashUcb_writePage(Swap.ActiveAddress + 0x00000008);
            Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);
            FlashUcb_waitUnbusy();

            Swap.ActiveAddress = Swap.ActiveAddress + 0x00000010;
        }

        if(Swap.ActiveBank == SWAP_A_BANK_ACTIVE)
        {
            Swap.ActiveBank      = SWAP_B_BANK_ACTIVE;
            Swap.UCB.US.MARKERLx = UCB_SWAP_B_BANK_ACTIVE;
        }
        else
        {
            Swap.ActiveBank      = SWAP_A_BANK_ACTIVE;
            Swap.UCB.US.MARKERLx = UCB_SWAP_A_BANK_ACTIVE;
        }
        Swap.UCB.US.MARKERHx       = Swap.ActiveAddress;
        Swap.UCB.US.CONFIRMATIONLx = UCB_SWAP_CONFIRMED;
        Swap.UCB.US.CONFIRMATIONHx = Swap.ActiveAddress + 0x00000008;

        FlashUcb_waitUnbusy();
        FlashUcb_enterPageMode();
        FlashUcb_waitUnbusy();
        FlashUcb_loadPage2X32(Swap.UCB.US.MARKERLx, Swap.UCB.US.MARKERHx);
        Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
        FlashUcb_writePage(Swap.ActiveAddress);
        Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);

        FlashUcb_waitUnbusy();
        FlashUcb_enterPageMode();
        FlashUcb_waitUnbusy();
        FlashUcb_loadPage2X32(Swap.UCB.US.CONFIRMATIONLx, Swap.UCB.US.CONFIRMATIONHx);
        Ifx_Ssw_clearSafetyEndinit(safetyWdtPassword);
        FlashUcb_writePage(Swap.ActiveAddress + 0x00000008);
        Ifx_Ssw_setSafetyEndinit(safetyWdtPassword);

        FlashUcb_waitUnbusy();
        if(swapOrigCopy)
        {
            swapOrigCopy = 0;
            FlashUcb_enterPageMode();
            FlashUcb_waitUnbusy();
            FlashUcb_loadPage2X32(UCB_SWAP_INVALIDATION, 0x00000000);
            if(Swap.ActiveUCB == UCB_SWAP_ORIG_ACTIVE)
            {
                FlashUcb_writePage(UCB_SWAP_ORIG_CONFIRMATION_ADDRESS);
            }
            else if(Swap.ActiveUCB == UCB_SWAP_COPY_ACTIVE)
            {
                FlashUcb_writePage(UCB_SWAP_COPY_CONFIRMATION_ADDRESS);
            }
        }

    }
}在这里插入代码片

4、总结
以上就是TC397 SOTA功能的代码实现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

u010203121

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

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

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

打赏作者

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

抵扣说明:

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

余额充值