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.

[参考译文] AM6421:AM64x 上的组中断帮助

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1374538/am6421-help-with-bank-interrupts-on-am64x

器件型号:AM6421

工具与软件:

您好!  

在我们的器件上、我们尝试对从 MCU_PLUS_SDK 获取的某些代码使用基于组的中断、但是我们遇到了问题。 首先、我要先讲一讲目前的代码:

int32_t IOLM_SOC_UTIL_gpioIrqSet(uint32_t u32BankNumber_p,
                                 uint32_t u32IntRouter_p,
                                 uint32_t u32IntSrcID_p,
                                 uint32_t u32IntDstID_p,
                                 uint32_t u32BankSrcIndexBase_p)
{
  int32_t retVal = SystemP_FAILURE;
  struct tisci_msg_rm_irq_set_req rmIrqReq;
  struct tisci_msg_rm_irq_set_resp rmIrqResp;

  /* For setting the IRQ for GPIO using sciclient APIs, we need to populate
   * a structure, tisci_msg_rm_irq_set_req instantiated above. The definition
   * of this struct and details regarding the struct members can be found in
   * the tisci_rm_irq.h.
   */
  /* Initialize all flags to zero since we'll be setting only a few */
  rmIrqReq.valid_params = 0U;
  /* Our request has a destination id, so enable the flag for DST ID */
  rmIrqReq.valid_params |= TISCI_MSG_VALUE_RM_DST_ID_VALID;
  /* DST HOST IRQ is the output index of the interrupt router. We need to make sure this is also enabled as a valid
   * param */
  rmIrqReq.valid_params |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID;
  /* This is not a global event */
  rmIrqReq.global_event = 0U;
  /* Our interrupt source would be the GPIO peripheral. The source id has to be a device id recognizable by the SYSFW.
   * The list of device IDs can be found in tisci_devices.h file under
   * source/drivers/sciclient/include/tisci/am64x_am243x/. In GPIO case there are 3 possible options - TISCI_DEV_GPIO0,
   * TISCI_DEV_GPIO1, TISCI_DEV_MCU_GPIO0. For input interrupt, we need to choose the TISCI_DEV_GPIO1
   */
  rmIrqReq.src_id = u32IntSrcID_p;
  /* This is the interrupt source index within the GPIO peripheral */
  rmIrqReq.src_index = u32BankSrcIndexBase_p + u32BankNumber_p;
  /* This is the destination of the interrupt, usually a CPU core. Here we choose the TISCI device ID for R5F0-0 core.
   * For a different core, the corresponding TISCI device id has to be provided */
  rmIrqReq.dst_id = u32IntDstID_p;
  /* This is the output index of the interrupt router. This depends on the core and board configuration */
  rmIrqReq.dst_host_irq = u32IntRouter_p;
  /* Rest of the struct members are unused for GPIO interrupt */
  rmIrqReq.ia_id = 0U;
  rmIrqReq.vint = 0U;
  rmIrqReq.vint_status_bit_index = 0U;
  rmIrqReq.secondary_host = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST;

  /* To set the interrupt we now invoke the Sciclient_rmIrqSet function which
   * will find out the route to configure the interrupt and request DMSC to
   * grant the resource
   */
  retVal = Sciclient_rmIrqSet(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER);
  return retVal;
}

这来自 mcu_plus_sdk/docs/api_guide_am64x/drivers_SCICLIENT_page.html。

int32_t IOLM_SOC_UTIL_registerGPIOInterrupt(HwiP_Object* gpioHwiObject_p,
                                            uint32_t u32Bank_p,
                                            uint32_t u32Base_p,
                                            uint32_t u32BaseIndex_p,
                                            uint32_t u32Router_p,
                                            uint32_t u32Src_p,
                                            uint32_t u32Dst_p,
                                            HwiP_FxnCallback vISR_p)
{
  int32_t retVal = SystemP_SUCCESS;
  HwiP_Params hwiPrms;

  // setup the GPIO input interrupt capability
  // interrupt router needs to exist, ie. MCU_GPIO0 to R50_0
  retVal = IOLM_SOC_UTIL_gpioIrqSet(u32Bank_p, u32Router_p, u32Src_p, u32Dst_p, u32BaseIndex_p);
  if (SystemP_SUCCESS == retVal)
  {
    GPIO_bankIntrEnable(u32Base_p, u32Bank_p); // not pin interrupt

    /* Register pin interrupt */
    HwiP_Params_init(&hwiPrms);
    hwiPrms.intNum = u32Router_p;
    hwiPrms.callback = vISR_p;
    hwiPrms.args = (void*)u32Bank_p; // NOLINT
    retVal = HwiP_construct(gpioHwiObject_p, &hwiPrms);
  }
  else
  {
    printf("Error setting up interrupt.\n");
  }

  return retVal;
}

此代码主要来自 mcu_plus_sdk/docs/api_guide_am64x/drivers_gpio_page.html。  

问题就在这里:我们正在尝试进行状态中断。 在电路板上、我们需要中断的引脚为 GPIO0_45、GPIO0_46、GPIO0_47和 GPIO0_48。 因此、 根据 SDK 中的示例代码、我们认为以下是 IOLM_SOC_UTIL_registerGPIOInterrupt 的参数:

u32Bank_p:2 (这仅涵盖引脚 GPIO0_45:47、但我们获得该值是因为每个组有16个引脚)

u32Base_p:CSL_GPIO0_BASE (因为我们想要中断的引脚为 GPIO0)

u32BaseIndex_p:90 ( 这是我们最常遇到的问题。 由于 SDK 示例使用的是 GPIO1、因此我们不知道该值是否正确。 此值添加到存储体编号以填充 tisci_msg_rm_irq_set_req 结构中的 src_index 字段、但当我们尝试90时、它不起作用 )

u32Router_p: CSLR_R5FSS0_CORE0_INTR_MAIN_GPIOMUX_INTROUTER0_OUTP_8

u32Src_p: TISCI_DEV_GPIO0

u32Dst_p: TISCI_DEV_R5FSS0_CORE0

最后、我们做了大量实验来验证 u32BaseIndex_p 的值应该是什么。 我们成功启用了该功能  个中断 仅在一个引脚上  暴力破解  tisci_msg_rm_irq_set_req 结构中的 SRC_INDEX 等于45、即我们要监测的一个引脚的 GPIO 数(GPIO0_45)。 对我们来说、这指向了一个事实、即我们的当前代码未正确注册  发生了什么、更确切地说是如此  质量 个中断。  

希望这是足够的信息、如果您需要更多信息、请告诉我。 谢谢你

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

    一些其他信息:我使用的是 AM64x MCU+ SDK 09.02.00

    我已尝试在 mcu_plus_sdk\source\drivers\sciclient\sciclient_rm_irq.c 中放置调试断点  我在  Sciclient_rmIrqRouteValidate 中的每个位置放置断点、其中显示"valid = false;"行、可能会表明我失败的位置。 我并不真正了解这些数据结构、但我认为这可能会提供一些见解。 验证在  sciclient_rm_irq.c 的第1761行失败、因为"next_INP_VALID"为 false。 我发现 next_inp_valid 为 false、因为在第1630行、对 Sciclient_rmIrInpIsFree 的调用返回 SystemP_Failure。 这发生在第2730行。 评论似乎表明"输入正在使用"? 传递到 Sciclient_rmIrInpIsFree 的值为 id=3和 INP=192。 我认为 id=3来自 TISCI_DEV_MAIN_GPIOMUX_INTROUTER0、但可能不正确。 根据此页面(https://software-dl.ti.com/tisci/esd/latest/5_soc_doc/am64x/interrupt_cfg.html#main-gpiomux-introuter0-interrupt-router-input-sources)、对于 GPIO0组2192似乎是 GPIO_BANK 正确的数字。 但是、在尝试注册中断时仍然失败。  

    不确定这是否有任何帮助,但它是一些更多的信息,我试图自己找出这个问题。  

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

    还有一些信息:我们在 A53内核上的器件上运行 Linux。 我们的 Linux 应用程序是一个加载 R5 FreeRTOS 代码的应用程序。 我们使用以下资源表:

    e2e.ti.com/.../5314.rm_2D00_cfg.c

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

    您好、Owen、

    感谢您访问德州仪器(TI) E2E 支持论坛。

    我可以在上面的代码中看到、在设置 Hwip 参数时、您已传递了 hwiPrms.args =(void*) u32Bank_p  即存储体编号。

    您能尝试 一次传递引脚编号吗?

    请参阅以下代码。

    hwiPrms.args     = (void *) pinNum;
    /* GPIO interrupt is a pulse type interrupt */
    hwiPrms.isPulse  = 1;
     

    pinNum 应该是确切的引脚编号(例如、GPIO0_45中为45)。

    此致、

    Tushar

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

    感谢你的评分  

    我试过你提供的代码。  它成功注册了中断、但是、 当它 在中断触发后尝试调用 GPIO_getBankIntrStatus 时、我们的 ISR 函数(未在此处显示)运行不正常。 在此处发生调试置位。  因此、我们将 IOLM_SOC_UTIL_registerGPIOInterrupt 中的代码保持不变、而是将以下参数传递给该代码:

    u32Bank_p: 0

    u32Base_p:CSL_GPIO0_BASE  

    u32BaseIndex_p: 45.

    u32Router_p: CSLR_R5FSS0_CORE0_INTR_MAIN_GPIOMUX_INTROUTER0_OUTP_8

    u32Src_p: TISCI_DEV_GPIO0

    u32Dst_p: TISCI_DEV_R5FSS0_CORE0

    这样做、我们基本上会模拟一个组中断、但对 Sciclient_rmIrqSet 的调用仅会将中断寄存在 GPIO0_45 中、因为我们传入的值会解析为此行中的"45":

      rmIrqReq.src_index = u32BankSrcIndexBase_p + u32BankNumber_p;

    后续测试确认、通过执行此操作、我们仅在一个引脚上成功注册和处理中断。

    我不认为问题出在 ISR 函数上、问题在于我们只在为一个引脚注册中断时才将中断恢复到软件层、而我们真正想要的是为整组引脚获得中断。  

    Owen

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

    您好、Owen、

    感谢您的答复。

    您能否尝试使用以下参数并告诉我们结果?

    rmIrqReq.src_id                 = TISCI_DEV_GPIO0;
    rmIrqReq.src_index              = TISCI_BANK_SRC_IDX_BASE_GPIO0 + GPIO_GET_BANK_INDEX(45);
    rmIrqReq.dst_id                 = TISCI_DEV_R5FSS0_CORE0;
    rmIrqReq.dst_host_irq           = CSLR_R5FSS0_CORE0_INTR_MAIN_GPIOMUX_INTROUTER0_OUTP_8;

    其中  TISCI_BANK_SRC_IDX_BASE_GPIO0 = 90u

    GPIO_GET_BANK_INDEX (45) 会返回 2u .

    此致、

    Tushar

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

    Tushar ,不幸的是,这种代码基本上是我在我的原始文章中尝试过的(一旦参数被解析)。 然而、我尝试了您提供的代码片段、对 Sciclient_rmIrqSet 的调用仍然失败。  

    Owen

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

    我们发现了这个问题。

    我们的器件在 A53内核上运行 Linux。 我们有一个 Linux 应用程序、它会将 FreeRTOS 代码(此处发布的代码)加载到 R5处理器上。 Linux 显然在使用 GPIO0外设。 我们必须在器件树文件中添加几行代码、以将 gpio0标记为"保留"、使 Linux 不会使用其中任何一行。 现在我们成功注册了中断、上面的代码没有改变。