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.

[参考译文] AM2634:AM2634 - WWDT 取消初始化函数不执行任何操作

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1576902/am2634-am2634---wwdt-de-initialization-functions-do-nothing

器件型号:AM2634


处理故障(例如,从 undefine_instruction_handler 内处理 0 分频陷阱)时、我们希望禁用特定内核的看门狗、写入一些持久信息、然后重新启动(通过热复位或重新启用看门狗而不是检测)

但是、这无法正常工作、因此我们调查了 SDK 源代码。 Watchdog_Close、Watchdog_deinit 的 API 似乎没有执行任何操作。 请参阅下图 1。 image.png

同样、尝试重构此结构(根据 WATCHDOG_OPEN 的术语实现 WATCHDOG_CLOSE、但这似乎也不会停止生成 warmreset。

void Watchdog_close(Watchdog_Handle handle) {
    Watchdog_Config* ptrWatchdogConfig;
    ptrWatchdogConfig            = (Watchdog_Config*)handle;
    Watchdog_MCB* ptrWatchdogMCB = (Watchdog_MCB*)ptrWatchdogConfig->object;

    if (ptrWatchdogConfig->object == NULL) {
        return;
    }

    const Watchdog_Params close_params = {
        .resetMode       = Watchdog_RESET_OFF,
        .debugStallMode  = Watchdog_DEBUG_STALL_OFF,
        .windowSize      = Watchdog_WINDOW_100_PERCENT,
        .expirationTime  = 1000,
        .callbackFxn     = NULL,
        .callbackFxnArgs = NULL,
    };

    Watchdog_open_handle(handle, &close_params);

    ptrWatchdogMCB->state = Watchdog_DriverState_UNINIT;
    return;
}

static int32_t Watchdog_open_handle(Watchdog_Handle handle, const Watchdog_Params* params) {    
    Watchdog_Config*  ptrWatchdogConfig;
    Watchdog_MCB*     ptrWatchdogMCB;
    Watchdog_HwAttrs* ptrHwCfg;
    int32_t           retVal = 0;
    uint32_t          preloadMaxValue;
    uint64_t          preloadValueTmp;
    /* Get the Watchdog Configuration: */
    ptrWatchdogConfig = (Watchdog_Config*)handle;

    /* Get the hardware configuration: */
    ptrHwCfg = (Watchdog_HwAttrs*)ptrWatchdogConfig->hwAttrs;

    /* Get the Watchdog Driver Object */
    ptrWatchdogMCB = (Watchdog_MCB*)ptrWatchdogConfig->object;

    /* Initialize the memory: */
    memset((void*)ptrWatchdogMCB, 0, sizeof(Watchdog_MCB));

    /* Store the WDT parameters */
    if (params == NULL) {
        /* No params passed in, so use the defaults */
        Watchdog_paramsInitDefaults(&(ptrWatchdogMCB->params));
    } else {
        /* Copy the params contents */
        ptrWatchdogMCB->params = *params;
    }

    /* Calculate preload value from the expiration time */
    /* Expiration time (in millisecond)/1000 = (preload value + 1)*(2^13)/RTICLK */
    preloadValueTmp =
        ((uint64_t)(ptrHwCfg->wdtClkFrequency)) * ((uint64_t)ptrWatchdogMCB->params.expirationTime) / 1000;
    /* Pre load is 12 bit value in register and actual value should be multiplied by 2^13) */
    preloadMaxValue = (1 << (12 + 13)) - 1;
    if (preloadValueTmp > preloadMaxValue) {
        retVal = SystemP_FAILURE;
    }

    if (retVal == SystemP_FAILURE) {
        return retVal;
    }

    /* Bring watchdog out of reset */
    Watchdog_reset(handle);

    /* if NMI interrupt mode is configured */
    if (ptrWatchdogMCB->params.resetMode == Watchdog_RESET_OFF) {
        /* Clear the status flags */
        //               HW_WR_REG32(ptrHwCfg->baseAddr + CSL_RTI_RTIWDSTATUS, WATCHDOG_CLEAR_STATUS);
    } else {
        /* Configure the SOC moule to trigger a warm reset upon watchdog reset */
        Watchdog_configureWarmReset(handle);
    }

    uint32_t preloadValue;
    uint32_t dwwdPreloadVal_l;
    /* CSL API needs shifted value but doesnot do -1 while programming.
     * So updating the preload value.
     */
    preloadValue = ((uint32_t)(preloadValueTmp) >> RTI_DWWDPRLD_MULTIPLIER_SHIFT) - 1;
    preloadValue = preloadValue << RTI_DWWDPRLD_MULTIPLIER_SHIFT;

    /* Clear the status flags */
    HW_WR_REG32(ptrHwCfg->baseAddr + CSL_RTI_RTIWDSTATUS, WATCHDOG_CLEAR_STATUS);

    /* Configure window in which watch-dog should be serviced */
    Watchdog_setWindowSize(handle, ptrWatchdogMCB->params.windowSize);

    /* Set the preload value */
    dwwdPreloadVal_l = (preloadValue >> ((uint32_t)RTI_DWWDPRLD_MULTIPLIER_SHIFT));
    if ((uint32_t)CSL_RTI_RTIDWDPRLD_DWDPRLD_MAX > dwwdPreloadVal_l) {
        /* Initialize DWD Expiration Period */
        HW_WR_FIELD32(ptrHwCfg->baseAddr + CSL_RTI_RTIDWDPRLD, CSL_RTI_RTIDWDPRLD_DWDPRLD, dwwdPreloadVal_l);
    }

    /* Configure the reset mode    */
    Watchdog_setReaction(handle, ptrWatchdogMCB->params.resetMode);

    /* Configure the stall mode */
    HW_WR_FIELD32(ptrHwCfg->baseAddr + CSL_RTI_RTIGCTRL, CSL_RTI_RTIGCTRL_COS, ptrWatchdogMCB->params.debugStallMode);

    /* Enable DWWD by writing pre-defined value '0xA98559DA' to RTIDWDCTRL */
    HW_WR_REG32(ptrHwCfg->baseAddr + CSL_RTI_RTIDWDCTRL, CSL_RTI_RTIDWDCTRL_DWDCTRL_ENABLE);

    /* Mark the driver to be operational */
    ptrWatchdogMCB->state = Watchdog_DriverState_OPERATIONAL;

    return retVal;
}

Watchdog_Handle Watchdog_open(uint8_t index, Watchdog_Params* params) {
    Watchdog_Handle handle = NULL;
    int32_t         status = SystemP_SUCCESS;

    /* Check index */
    if (index >= gWatchdogConfigNum) {
        status = SystemP_FAILURE;
    } else {
        handle = (Watchdog_Handle) & (gWatchdogConfig[index]);
    }

    if (status != SystemP_SUCCESS || handle == NULL) {
        return NULL;
    }

    status = Watchdog_open_handle(handle, params);
    if (status != SystemP_SUCCESS) {
        return NULL;
    }

    return handle;
}

 

3 个问题:

  1. 我们做什么错了? 临时禁用 WWDT 的正确方法是什么? 显然、它不是 HAL_SDK、因为 API 不起作用
  2. 为什么上面的示例代码不起作用?