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.

[参考译文] RTOS:硬件中断挤占逻辑如何在 SYS_BIOS 中工作

Guru**** 2551110 points
Other Parts Discussed in Thread: OMAP-L138, SYSBIOS

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/604190/rtos-how-does-hardware-interrupt-pre-empt-logic-works-in-sys_bios

Thread 中讨论的其他器件:OMAP-L138SYSBIOS

工具/软件:TI-RTOS

你(们)好。

我使用的是 OMAP-L138 SoC,而在内核的 DSP 端,我尝试使用两个中断。

SPI1设置为中断编号5、UART0设置为中断编号7。 我目前没有对这些项目使用任何优先级。  

下面是配置信息:

var hwi5Params = new hwi.Params();
hwi5Params.instance.name ="hwi5";
hwi5Params.priority =-1;
hwi5Params.EventID = 38;
program.global.hwi5 = Hwi.create (5、"&uart0ISR"、hwi5Params);

var hwi7Params = new hwi.Params();
hwi7Params.instance.name ="hwi7";
hwi7Params.EventID = 43;
hwi7Params.priority =-1;
hwi7Params.maskSetting = XDC.MODULE ("ti.sysbios.interfaces.IHwi").MaskingOption_SELF;
program.global.hwi7 = Hwi.create (7、"&SPI1Isr"、hwi7Params);

SPI1 ISR 运行约1.2ms、UART0 ISR 运行200usec、但 UART0的频率更高、因此我为 SPI1中断分配了中断编号5、以获得更高的优先级。 但出于某种原因、当存在 UART0中断时、SPI1中断不会挤占。 我在这里有什么问题吗? 谢谢

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

    [引用 USER="Mitesh Hiran"] SPI1 ISR 运行时间约为1.2ms,UART0 ISR 运行时间为200usec[/引用]

    这些是 ISR 的周期还是 ISR 执行时间的持续时间?

    [引用 USER="Mitesh Hiran"]但 UART0的频率更高、因此我为 SPI1中断分配了中断编号5、以获得更高的优先级。[/引用]

    在 C6x DSP 上、硬件中断优先级不指示一个中断与另一个中断的可抢占性、而只是指示当两个中断都出现在给定的 CPU 周期中时、将首先获取哪个中断。

    在 SYS/BIOS 中、您可以通过屏蔽来控制 ISR 的抢占性。  您已经为 hwi7中的 SPI ISR 选择了 MaskingOption_self、这意味着每个其他中断都可以优先(即中断)它。  您尚未为 UART 中断 hwi5指定 maskSeting、但默认设置(用于 hwi5) 为 MaskingOption_self、因此每个其他中断都应该能够中断 hwi5。

    这一切似乎都适合您的设置。

    您能否为 hwi5和 hwi7的 ISR (uart0ISR 和 SPI1Isr)展示完整的源代码?

    此致、

    - Rob

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

    我对可能发生的情况有了另一种想法...

    是否有可能:

    1. uart0ISR 运行、屏蔽自身(hwi5)
    2. SPI1Isr 优先于 uart0ISR (因此在掩码了 hwi5和 hwi7的情况下运行),并且在执行时...
    3. (笑声) 发生另一个 UART0中断、但由于它不能抢占自身、它会被保持关闭、直到第1步中的 uart0ISR 实例发生。 完成。

    如果您遇到这种情况、则可以通过将 hwi5的'askSetting'设置为 MaskingOption_all 来解决该问题、这将阻止 SPI1Isr 在 uart0ISR 运行时运行。  但是、如果你需要 SPI1Isr 来挤占 uart0ISR、那么这将不适合你。

    此致、

    - Rob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Rob、您好、感谢您的回复。
    感谢您指出 UART 和 SPI 的屏蔽逻辑。
    但是、它看起来应该正常工作。
    如果 SPI ISR 正在运行,则存在 UART 中断.... 然后它应该优先于 SPI 到 UART。
    由于 UART 是中断编号5、SPI 是中断编号7、我想 SPI 通常应被 UART 抢先(由于 UART 是最高优先级、因此永远不能被抢占!!)
    因此、它绝不会出现您提到的情况。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Rob、这是 ISR 代码

    空 SPI1Isr (空)

    unsigned int 代码= 0;

    #ifdef _TMS320C6x
    IntEventClear (CSL_INTC_EventID_SPIINT1);
    其他
    IntSystemStatusClear (56);
    #endif

    intCode = SPIInterruptVectorGet (CSL_SPI_1_regs);

    while (intCode)

    //设置 FPGA 数据标志
    if (intCode = SPI_TX_BUF_EMPTY)


    SPITransmitData1 (CSL_SPI_1_regs、* p_tx);



    if (intCode = SPI_RECV_FULL)

    * p_rx =(无符号短整型) SPIDataReceive (CSL_SPI_1_regs);//(char)



    intCode = SPIInterruptVectorGet (CSL_SPI_1_regs);



    和 UART ISR:

    void uart0ISR(){

    unsigned int int_id = 0;
    unsigned char dataRdy=0;
    extern unsigned char GPSDataInt;

    /*这决定了 UART0中断的原因。*/
    INT_id = UARTIntStatus (CSL_UART_0_regs);

    #ifdef _TMS320C6x
    //清除 DSPINTC 中的 UART0系统中断
    IntEventClear (SYS_INT_UART0_INT);
    其他
    /*清除 AINTC 中 UART0的系统中断状态。 *
    IntSystemStatusClear (SYS_INT_UARTINT0);
    #endif

    /*已检查原因是否为发送器空状态。*/
    if (UART_INTID_TX_EMPTY = int_id)

    如果(长度> 0)

    /*如果 THR 是空闲的、请将一个字节写入 THR。 *
    UARTCharPutNonBlocking (CSL_UART_0_regs、gpsInit[count]);
    长度--;
    count++;
    //虚拟读取
    UARTCharGetNonBlocking (CSL_UART_0_regs);

    if (length ==0)

    /*在 UART 中禁用发送器中断。*/
    UARTIntDisable (CSL_UART_0_regs、UART_INT_TX_EMPTY);
    计数= 0;
    //虚拟读取
    UARTCharGetNonBlocking (CSL_UART_0_regs);
    //启用 RX 中断
    UARTIntEnable (CSL_UART_0_regs,(UART_INT_LINE_STAT | UART_INT_RXDATA_CTI));



    /*检查原因是否是接收器数据条件。*/
    if (UART_INTID_RX_DATA == int_id)

    //重置 ISR 的字符长度起始
    CharLen = 0;
    //接收到通知中断
    GPSDataInt=1;

    执行{
    //从 FIFO 读取字符
    //将接收到的字符写入缓冲区
    GPSMesgBuffer[wrIdx]=(char) UARTCharGetNonBlocking (CSL_UART_0_regs);
    //字符 Rx 的数量
    CharLen++;
    wrIdx++;
    //重置 buf 指针
    if (wrIdx = 1008){
    wrIdx = 0;

    dataRdy =(char) UARTCharsAvail (CSL_UART_0_regs);
    } while (dataRdy = 0x01 && CharLen <= 15);
    wrIdx = 0;
    Semaphore_post (GPSDecode_SEM);



    /*检查原因是否是接收器线路错误条件。*/
    if (UART_INTID_RX_LINE_STAT = int_id)

    while (UARTRxErrorGet (CSL_UART_0_regs))

    /*如果 RBR 有数据,则从 RBR 读取一个字节。*/
    UARTCharGetNonBlocking (CSL_UART_0_regs);


    返回;
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我提到的时间是 ISR 中花费的时间。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在附加的图形中、当 SPI ISR (中断编号7)运行时、它不会让 msCounter (中断编号6)和 UART (中断编号5)占先。 这是我不理解的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Mitesh Hiran">由于 UART 是中断编号5、SPI 是中断编号7、我猜 SPI 通常应被 UART 抢先(由于 UART 是最高优先级、因此永远不能被抢占!!!) [/报价]

    正如我在最初的应答中所说的那样,硬件中断优先级不是这样工作的,它只用来决定在给定的 CPU 周期*上需要哪个中断。  让我以一个示例进行解释...

    假设中断被全局禁用(在 CSR 中为 GIE=0)、并且在禁用期间、两个单独的中断触发、从而导致它们的标志在中断标志寄存器(IFR)中被置位。  由于中断被全局禁用、因此这两个中断都不会被执行。  当代码再次启用全局中断时、CPU 需要决定这两个中断中的哪一个要处理。  它将为具有更高硬件优先级的中断提供服务(在本例中为 hwi5)。  这是硬件优先级最重要的时刻。  然后、在 DSP/BIOS HWI 调度过程中、hwi5的中断屏蔽将应用于中断使能寄存器(IER)、屏蔽本身、然后发送程序将启用全局中断以允许嵌套中断、并调用 hwi5的 ISR。  但是、HWI 调度程序启用中断后、Hwi7就会立即得到服务、因为它不会被屏蔽。  硬件优先级在这里无关紧要、因为 IFR 中只有一个中断被标记。  只能通过将 maskSetting 设置为屏蔽 hwi5的值来防止 hwi7中断 hwi5、例如 MaskingOption_ALL 或 MaskingOption_bitmask、其位掩码值为0x0080。

    在这方面、C6x DSP 与许多其他 CPU 和 MCU (如果不是大多数)不同、因为在这些 CPU 和 MCU 中、较低优先级的中断不能取代较高优先级的中断的 ISR。

    因此、防止 hwi7中断 hwi5的唯一方法是让 DSP/BIOS 调度程序屏蔽 hwi7、位掩码为0x0080 (IER 是一个16位寄存器)。

    Mitesh Hiran 说:
    因此,它绝不会出现您提到的情况。

    我希望大家现在明白、它能够而且将会进入我提到的情况。

    此致、

    - Rob

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

    [引用 USER="Mitesh Hiran">在附加的图表中、当 SPI ISR (中断编号7)运行时、它不会让 msCounter (中断编号6)和 UART (中断编号5)占先。 这是我不理解的。[/引述]

    您能否放大执行图并发布更详细的新屏幕截图?  我希望看到灰色矩形的更多详细信息。  我想在 SPI ISR 的长红线之前查看其中一个较小矩形和矩形的详细信息。

    此致、

    - Rob

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

    [引用用户="Mitesh Hiran"]

    空 SPI1Isr (空)

      unsigned int 代码= 0;
     
    #ifdef _TMS320C6x
      IntEventClear (CSL_INTC_EventID_SPIINT1);
    其他
      IntSystemStatusClear (56);
    #endif

      intCode = SPIInterruptVectorGet (CSL_SPI_1_regs);

      while (intCode)
      {
        //设置 FPGA 数据标志
        if (intCode = SPI_TX_BUF_EMPTY)
        {
            SPITransmitData1 (CSL_SPI_1_regs、* p_tx);
         }

        if (intCode = SPI_RECV_FULL)
        {
          * p_rx =(无符号短整型) SPIDataReceive (CSL_SPI_1_regs);//(char)
         }
      }

    [/报价]

    您的"while (intCode)"循环不会更改 intCode、因此它永远不会终止。  不确定这是否说明了您看到的所有内容、但对我来说似乎很糟糕。

    此致、

    - Rob

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此外、请尝试设置 UART ISR Hwi.maskSetting = MaskingOption_ALL 并报告结果。

    此致、

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

    尊敬的 Rob:

    好的、现在我明白了。。。 因此、如果我需要 UART 中断来优先于所有其他不可能的中断。 我只能控制是否有多个中断挂起、并且当时是否有一个中断触发器的优先级。

    这意味着、如果一个中断正在处理、那么其他中断不能挤占它。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我以前曾尝试过这种方法、但没有什么不同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在 while 循环中存在"intCode = SPIInterruptVectorGet (CSL_SPI_1_regs);"、哦。 我在这里粘贴和编辑额外代码时、可能错过了它。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 USER="Mitesh Hiran"]因此,如果我需要 UART 中断来抢占所有其他不可能的中断[/引用]

    这当然是可能的。  我只是想告诉您忘记硬件优先级、它基本上不存在、 而是使用软件优先级。

    软件优先级通过屏蔽设置来控制相对中断优先级。  那么、您希望 UART 抢占所有其他中断(可能不包括自身)?   这是通过不屏蔽所有 其他中断的 UART 中断来实现的。

    换而言之、您希望 UART 中断(hwi5) 具有比 SPI 中断(hwi7)更高的调度优先级。 您可以通过让 UART Hwi 的 maskSetting = MaskingOption_bitmask 及其 DisableMask 和 restoreMask = 0x00A0来完成此操作。  SPI 的 Hwi 将具有 maskSetting = MaskingOption_SELF、因为所有 Hwi 都应防止自嵌套。  这样、SPI 不能取代 UART、但 UART 可以取代 SPI。

    [引用 USER="Mitesh Hiran"]这意味着,如果一个中断正在处理中,则其他中断不能取代它。

    当然不是。  你可以完全控制哪个 Hwi 可以或不能抢占任何其他 Hwi。

    此致、

    - Rob

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

    [引用 USER="Mitesh Hiran]OH、"intCode = SPIInterruptVectorGet (CSL_SPI_1_regs);"出现在 while 循环中。 我在这里粘贴并编辑额外代码时、可能错过了该代码。

    好的。  您的函数中有一个额外的右括号、因此我不确定。

    那么、在您的执行图中、为什么前几个 SPI Hwi 执行的时间非常短、然后最后几个 SPI Hwi 执行的时间非常长?

    此致、

    - Rob

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

    您好 Rob、谢谢。 我将尝试使用屏蔽选项执行此操作。

    在 cfg 文件中、如何更改位掩码?

    我尝试了 maskingOption_LOWER。 这是最好的一个、但看起来还不受支持。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    将在 cfg 文件中添加以下行
    hwi5Params.disableMask = 0x00A0
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    尊敬的 Rob:
    原因是我们接收到的最后一个 SPI 字有额外的计算、需要的时间应小于1ms。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Mitesh Hiran">我尝试了 maskingOption_LOWER。 这是最好的一个、但看起来还不受支持。

    此选项可用于具有真硬件优先级的目标。  由于 C6x 没有这种功能、因此 C6x DSP 上也不支持它、这种情况也不会发生。

    此致、

    - Rob

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

    Mitesh Hiran 说:
    right 将在 cfg 文件中添加以下行
    hwi5Params.disableMask = 0x00A0[/quot]

    请务必同时设置

    hwi5Params.restoreMask = 0x00A0;

    否则、这些中断将在从中断返回时保持禁用状态。

    此致、

    - Rob

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

     [引用 user="Mitesh Hiran"]原因是我们接收到的最后一个 SPI 字需要执行额外的计算,所需的时间应小于1ms。

    这将有助于更详细地了解执行图上的最后一个块:(在嵌入屏幕截图时遇到问题、因此如果您看不到、请打开附件)

    左侧的灰色矩形是一组记录活动、这些活动全部聚集在一起。  您可以放大执行图以显示更精细的粒度。

    您是否能够更详细地了解这一点?

    谢谢、此致、

    - Rob

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

    尊敬的 Rob:

    在我的设计中、我们使用 NDK、TX 和 RX 的中断定义是运行时的、它没有 restoreMask!! 那么、如果我们没有 restoreMask、那么默认值是 sel自我 掩码吗?  

    但是、我无法在 cfg 文件中添加 restoreMask 和 disableMask。 请告诉我如何添加这些内容。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    很抱歉 Rob、我想我已经这么做了。 将尽快执行。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="Mitesh Hiran">但是,我无法在 cfg 文件中添加 restoreMask 和 disableMask。 请告诉我如何添加这些内容。[/引述]

    restoreMask 和 disableMask 是 c64p 专用 Hwi 参数的元素。  软件包 ti.sysbios.family.c64p.Hwi 从 ti.sysbios.hal.Hwi 继承。

    我假设您当前在 C 代码中包含 ti.sysbios.hal.hwi:

       #include

    相反、您应该:

       #include

    这样做时、Hwi_Params 结构来自 c64p Hwi、它包含 disableMask 和 restoreMask 元素。

    当从.cfg 文件中执行等效操作时也是如此:

       VAR Hwi = xdc.useModule('ti.sysbios.family.c64p.Hwi');

    此致、

    - Rob

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

    Rob、您好、感谢您的回复。

    我根据您之前的邮件进行了更改。 我没有收到此警告:  

    "非默认掩码设置、但已禁用派单自动网络支持。"

    我是否需要启用自动嵌套功能???  

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

    [引用用户="Mitesh Hiran"]

    "非默认掩码设置、但已禁用派单自动网络支持。"

    我是否需要启用自动嵌套功能???

    [/报价]

    嗯、派单 AutoNestingSupport 的默认值是"true"(或已启用)、因此我想知道如何将其设置为"false"(或已禁用)。  您的配置设置是否为 false?  您提到您使用的是 NDK、因此我还想知道 NDK 是否将其设置为 false。

    只有 在 maskSetting = MaskingOption_self 时、配置可以将其设置为 false、而不会产生任何错误、这是您以前使用的配置、我建议您使用 MaskingOption_bitmask。  但是现在您正在使用位掩码、由于您要求使用位掩码设置进行屏蔽、因此会发生此错误、但出于某种原因、发送程序的嵌套已被禁用。

    这将解释您的 UART 中断不能抢占 SPI 中断的原因、所以让我们来看看它是如何被禁用的。  您可以尝试将其手动设置为"true"以查看发生了什么。

    此致、

    - Rob

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

    尊敬的 Rob:

    是的、我在 cfg 文件中将其更改为"true"、看起来所有警告都消失了。 但我没有意识到、否则会停止中断的挤占。

    抱歉、尚未上传图表。 很快就会去

    谢谢。

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

    [引用用户="Mitesh Hiran"]

    是的、我在 cfg 文件中将其更改为"true"、看起来所有警告都消失了。 但我没有意识到、否则会停止中断的挤占。

    抱歉、尚未上传图表。 很快就会去

    [/报价]

    也许您不再需要上传图表、因为您刚才所做的更改可以很好地解决问题。

    此更改后问题是否仍然发生?  如果是、请上传我请求的执行图片段。

    谢谢、此致、

    - Rob