ZHCZ038A October   2017  – June 2025 MSP432E401Y , MSP432E411Y

 

  1.   1
  2. 1MSP432E4 SimpleLink™ 微控制器
    1. 1.1 简介
    2. 1.2 器件命名规则
    3. 1.3 器件标识
    4. 1.4 勘误表概述
    5. 1.5 勘误说明
      1.      ADC#13
      2.      ADC#14
      3.      EPI#01
      4.      GPIO#09
      5.      GPTM#09
      6.      GPTM#15
      7.      HIB#10
      8.      HIB#16
      9.      HIB#18
      10.      HIB#19
      11.      MEM#07
      12.      MEM#15
      13.      MEM#16
      14.      PWM#04
      15.      PWM#05
      16.      PWM#06
      17.      QEI#01
      18.      SSI#03
      19.      SSI#05
      20.      SSI#06
      21.      SSI#07
      22.      SSI#08
      23.      SYSCTL#03
      24.      SYSCTL#18
      25.      SYSCTL#24
      26.      USB#04
      27.      WDT#08
    6. 1.6 附录 1:
    7. 1.7 附录 2:
  3. 2商标
  4. 3修订历史记录

附录 1:

要解决错误 HIB#16 在清除期间,应用代码可能丢失新的篡改事件 ,必须将 HibernateTamperEventsClear() API 替换为以下 API:

HibernateTamperEventsClearNoLock();
HibernateTamperUnLock();
HibernateTamperLock();

API 定义如下:

//*****************************************************************************
//
//! Clears the tamper feature events without Unlock and Lock.
//!
//! This function is used to clear all tamper events without unlock/locking
//! the tamper control registers, so API HibernateTamperUnLock() should be
//! called before this function, and API HibernateTamperLock() should be
//! called after to ensure that tamper control registers are locked.
//! 
//! This function doesn't block until the write is complete. 
//! Therefore, care must be taken to ensure the next immediate write will
//! occure only after the write complete bit is set.
//!
//! This function is used to implement a software workaround in NMI interrupt
//! handler to fix an issue when a new tamper event could be missed during
//! the clear of current tamper event.
//!
//! \note The hibernate tamper feature is not available on all 
//! devices.  Please consult the data sheet for the device that you
//! are using to determine if this feature is available.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateTamperEventsClearNoLock(void)
{
    //
    // Wait for write completion.
    //
    _HibernateWriteComplete();
    // 
    //
    // Set the tamper event clear bit.
    //
    HWREG(HIB_TPCTL) |= HIB_TPCTL_TPCLR;
}
//*****************************************************************************
//
//! Unlock temper registers.
//!
//! This function is used to unlock the temper control registers.  This
//! function should be only used before calling API
//! HibernateTamperEventsClearNoLock().
//!
//! \note The hibernate tamper feature is not available on all
//! devices.  Please consult the data sheet for the device that you
//! are using to determine if this feature is available.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateTamperUnLock(void)
{
    //
    // Unlock the tamper registers.
    //
    HWREG(HIB_LOCK) = HIB_LOCK_HIBLOCK_KEY;
    _HibernateWriteComplete();
}
//*****************************************************************************
//
//! Lock temper registers.
//!
//! This function is used to lock the temper control registers.  This
//! function should be used after calling API
//! HibernateTamperEventsClearNoLock().
//!
//! \note The hibernate tamper feature is not available on all 
//! devices.  Please consult the data sheet for the device that you
//! are using to determine if this feature is available.
//!
//! \return None.
//
//*****************************************************************************
void
HibernateTamperLock(void)
{
    //
    // Wait for write completion.
    //
    _HibernateWriteComplete();
    //
    // Lock the tamper registers.
    //
    HWREG(HIB_LOCK) = 0;
    _HibernateWriteComplete();
}

必须将软件权变措施添加到 NMI 处理程序中。代码主要在篡改清除同步期间轮询篡改日志条目。

具有此权变措施的 NMI 处理程序示例如下所示。

static uint32_t g_ui32RTCLog[4];
static uint32_t g_ui32EventLog[4];
//*****************************************************************************
//
// Handles an NMI interrupt generated by a Tamper event.
//
//*****************************************************************************
void
NMITamperEventHandler(void)
{
    uint32_t ui32NMIStatus, ui32TamperStatus;
    uint32_t pui32Buf[3];
    uint8_t ui8Idx, ui8StartIdx;
    bool     bDetectedEventsDuringClear;
    //
    // Get the cause of the NMI event.
    //
    ui32NMIStatus = SysCtlNMIStatus();
    //
    // We should have got the cause of the NMI event from the above function.
    // But in Snowflake RA0 the NMIC register is not set correctly when an
    // event occurs.  So as a work around check if the NMI event is caused by a
    // tamper event and append this to the return value from SysCtlNMIStatus().
    // This way only this section can be removed once the bug is fixed in next
    // silicon rev.
    //
    ui32TamperStatus = HibernateTamperStatusGet();
    if(ui32TamperStatus & (HIBERNATE_TAMPER_STATUS_EVENT |
                         HIBERNATE_TAMPER_STATUS_EXT_OSC_FAILED))
    {
        ui32NMIStatus |= SYSCTL_NMI_TAMPER;
    }
    //
    // Check if SysCtlNMIStatus() returned a valid value.
    //
    if(ui32NMIStatus)
    {
        //
        // Check if the NMI Interrupt is due to a Tamper event.
        //
        if(ui32NMIStatus & SYSCTL_NMI_TAMPER)
        {
            //
            // If the previous NMI event has not been processed by main
            // thread, we need to OR the new event along with the old ones.
            //
            if(g_ui32NMIEvent == 0)
            {
                //
                // Reset variables that used for tamper event.
                //
                g_ui32TamperEventFlag = 0;
                g_ui32TamperRTCLog = 0;
                //
                // Clean the log data for debugging purpose.
                //
                memset(g_ui32RTCLog, 0, (sizeof(g_ui32RTCLog))<<2);
                memset(g_ui32EventLog, 0, (sizeof(g_ui32EventLog))<<2);
            }
            //
            // Log the tamper event data before clearing tamper events.
            //
            for(ui8Idx = 0; ui8Idx< 4; ui8Idx++)
            {
                if(HibernateTamperEventsGet(ui8Idx,
                                            &g_ui32RTCLog[ui8Idx],
                                            &g_ui32EventLog[ui8Idx]))
                {
                    //
                    // Event in this log entry, store it.
                    // 
                    g_ui32TamperEventFlag |= g_ui32EventLog[ui8Idx];
                    g_ui32TamperRTCLog = g_ui32RTCLog[ui8Idx];
                }
                else
                {
                    //
                    // No event in this log entry. Done checking the logs.
                    //
                    break;
                }
            }
            //
            // Process external oscillator failed event.
            //
            if(ui32TamperStatus & HIBERNATE_TAMPER_STATUS_EXT_OSC_FAILED)
            {
                g_ui32TamperXOSCFailEvent++;
                g_ui32TamperEventFlag |= HIBERNATE_TAMPER_EVENT_EXT_OSC;
                g_ui32TamperRTCLog = HWREG(HIB_TPLOG0);
            }
注:

权变措施代码块由此开始。


            // The following block of code is to workaround hardware defect
            // which results in missing new tamper events during tamper clear
            // synchronization.
            // 
            // There is a window after the application code writes the tamper
            // clear where a new tamper event can be missed if the application
            // requires more than one tamper event pins detection.
            // 
            // The tamper Clear is synchronized to the hibernate 32kHz clock
            // domain.  The clear takes 3 rising edges of the 32KHz clock.
            // During this window, new tamper events could be missed.
            // A software workaround is to poll the tamper log during the
            // tamper event clear synchronization.
            // 
            //
            // Clear the flag for the case there are events triggered
            // during clear execution.
            //
            bDetectedEventsDuringClear = false;
            //
            // Unlock the Tamper Control register. This is required before
            // calling HibernateTamperEventsClearNoLock().
            // 
            HibernateTamperUnLock();
            do
            {
                //
                // We will start to poll the log registers at index 1 for
                // any new events.
                // 
                ui8StartIdx = 1;
                //
                // Clear the Tamper event.
                // Note this API doesn't wait for synchronization, which
                // allows us to check the tamper log during
                // synchronization.
                //
                HibernateTamperEventsClearNoLock();
                //
                // Check new tamper event during tamper event clear
                // synchronization.
                // This will take about 92us(three clock cycles) at most.
                //
                while(HibernateTamperStatusGet() & HIBERNATE_TAMPER_STATUS_EVENT)
                {
                    //
                    // Clear execution isn't done yet , poll for new events.
                    // If there were any new event, it will be logged in log 1
                    // registers and so on.
                    //
                    for(ui8Idx = ui8StartIdx; ui8Idx< 4; ui8Idx++)
                    {
                        if(HibernateTamperEventsGet(ui8Idx, 
                                                    &g_ui32RTCLog[ui8Idx],
                                                    &g_ui32EventLog[ui8Idx]))
                        {
                            //
                            // detected new event, store it.
                            //
                            g_ui32TamperEventFlag |= g_ui32EventLog[ui8Idx];
                            //
                            // check for more event.
                            //
                            continue;
                        }
                        else
                        {
                            //
                            // no new event in this log, update the log index
                            // to be checked next, and break out of loop.
                            //
                            ui8StartIdx = ui8Idx;
                            break;
                        }
                    }
                    //
                    // all last three logs have info. Check if all 4 logs
                    // have the same info. This is to detect the case that
                    // events happen during clear execution. 
                    // 
                    if(ui8Idx == 4)
                    {
                        //
                        // If events happens during clear
                        // execution, all four log registers will be
                        // logged with the same event, to detect this
                        // condition, we will compare with all four log data.
                        // 
                        if(HibernateTamperEventsGet(0, &g_ui32RTCLog[0], &g_ui32EventLog[0]))
                        {
                            if((g_ui32RTCLog[0] == g_ui32RTCLog[1])     &&
                               (g_ui32EventLog[0] == g_ui32EventLog[1]) &&
                              (g_ui32RTCLog[0] == g_ui32RTCLog[2])     &&
                               (g_ui32EventLog[0] == g_ui32EventLog[2]) &&
                               (g_ui32RTCLog[0] == g_ui32RTCLog[3])     &&
                               (g_ui32EventLog[0] == g_ui32EventLog[3]))
                            {
                                //
                                // Detected events during clear execution.
                                // Event logging takes priority, the clear
                                // will not be done in this case. We will need
                                // to go back to the beginning of the loop and
                                // clear the events.
                                //
                                if(bDetectedEventsDuringClear)
                                {
                                    //
                                    // This condition has already detected,
                                    // we have cleared the event,
                                    // clear the flag.
                                    // 
                                    bDetectedEventsDuringClear = false;
                                }
                                else
                                {
                                    // This is the first time it has been
                                    // detected, set the flag.
                                    //
                                    bDetectedEventsDuringClear = true;
                                }
                                //
                                // Break out of while loop so that we can
                                // clear the events, and start the
                                // workaround all over again.
                                //
                                break;
                            }
                        }
                        else
                        {
                            //
                            // Log 0 didn't detect any events. So this is not
                            // the case of missing events during clear
                            // execution.
                            // Update the log index at which we will poll next.
                            // It should be the last log entry that OR all the
                            // new events.
                            //
                            ui8StartIdx = 3;
                        }
                    }
                }
            }
            while(bDetectedEventsDuringClear);
            //
            // Lock the Tamper Control register.
            // 
            HibernateTamperLock();
注:

权变措施代码块由此结束。

            //
            // Save the tamper event and RTC log info in the Hibernate Memory
            //
            HibernateDataGet(pui32Buf, 3);
            pui32Buf[1] = g_ui32TamperEventFlag;
            pui32Buf[2] = g_ui32TamperRTCLog;
            HibernateDataSet(pui32Buf, 3);
            //
            // Signal the main loop that an NMI event occurred.
            //
            g_ui32NMIEvent++;
        }
        //
        // Clear NMI events
        //
        SysCtlNMIClear(ui32NMIStatus);
    }
}