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.

[参考译文] TM4C1294NCPDT:在中断中运行 ROM 函数时遇到问题、获取故障 ISR#39

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/627805/tm4c1294ncpdt-having-trouble-running-rom-functions-in-interrupt-getting-fault-isr-s

器件型号:TM4C1294NCPDT

我有一个由 SysTick 中断调用的函数、用于将软件中的传输缓冲区中的字符加载到器件的 Uart4 TX 缓冲区中。  如果每个中断有10个字符、并且器件的 TX 缓冲区中有空间、则最多可以添加10个字符。  该功能如下所示:

/*********

  函数:     Uart4_Load_TX_Buffer


  说明:  此函数由 SysTick 中断例程和调用
                 从 Uart4循环缓冲区加载多达10个字符
                 器件的 TX 缓冲器。  该例程在任一时间返回时返回
                 器件 TX 缓冲区已满、已加载10个字符或
                 没有更多字符可供发送。

  参数:   无

  返回:      无

秘书长的报告 /
空 Uart4_Load_TX_Buffer (空)

int 索引= 0;

   //禁用中断
  ROM_IntMasterDisable();

  //检查是否满足所有条件
  while (索引< 10 &&
          COM4_TX_Head!= COM4_TX_Tail &&
          //ROM_UARTSpaceAvail (UART4_base)
          UARTSpaceAvail (UART4_base)
        )
     {
     //递增索引
     ++索引;

     //将下一个字符发送到器件 TX 缓冲区
 //   ROM_UARTCharPutNonBlocking (UART4_base、COM4_TX_Buffer[COM4_TX_Tail]);

     //使缓冲区尾部递增
     +++COM4_TX_Tail;

     //检查回绕
     IF (COM4_TX_Tail >= Com4TXBufferSize)
        {
        //复位到缓冲区的开头
        COM4_TX_Tail = 0;
        }
     }

  //启用中断
  ROM_IntMasterEnable();


1.如果我参加了 Space Available 测试、并且 CHARPut 函数运行无故障、

2.如果我添加了任何可用空间、并且 Char 放置了故障 ISR、我不确定原因。

3.在中断中使用这些函数是否有任何限制?

4.在初始化 UART 时是否有特殊的顺序允许函数工作?

5.由于我使用 SysTick 中断加载 TX 缓冲区、是否有针对 UART 的推荐 UART 设置? 我假设我不需要使用 TX 中断、因为我根据字符空间的可用性填充缓冲区。65。 是否有一个在中断中实际使用这些函数的示例、在这里我可以看到需要在中断和 UART 中设置什么才能使这些函数运行? 当文档以最简单的形式编写时、我会遇到问题、并会留下实际示例来说明函数的实际工作方式。

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

    [引用 user="Mike Fontes"]我有一个函数由 SysTick 中断调用,用于将软件中的传输缓冲区中的字符加载到器件的 Uart4 TX 缓冲区

    为什么您不使用发送中断而是这样做? 我同意、传输中断在该 UART 上的实现不是特别好、但仍然...

    [引用用户="Mike Fontes">2. 如果我添加了任何可用空间、并且 Char 放置了故障 ISR、我不确定原因。

    我认为您可能应该明白这一点。

    Robert

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

    我可能需要在本地软件缓冲区中放置比 UART 可以容纳的更多信息、因此我只需将信息分为几组字符、直到整个软件缓冲区被清空。 我正在使用 SysTick、因为它在不添加第三个中断的情况下可用。

    我通过单步执行程序进行了调试、我知道当调用基于 ROM 的 UART 函数或其库等效函数时会发生故障。 我假设 UART 的设置方式有问题、但没有使用这些函数的实例来确定处理器为什么会获得 FaultISR。 这就是我提出上述问题的原因。

    您说得对、我需要弄清楚为什么我要获得 FaultISR。 我的问题是、我不确定要寻找什么、因为我不必在其他 Tiva、Stellaris 和 ST Arm 项目中处理这些问题。 我要求在如何确定系统不喜欢的方面提供一些帮助、因为我认为我正在正确使用这些功能。 我认为 UART 的设置存在一些问题、但不知道在哪里可以找到使用这些函数的完整 C 语言实现。

    此致、

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

    [引用 user="Mike Fontes">我可能需要在本地软件缓冲区中放置比 UART 可以容纳的更多信息、因此我只需用一组字符来定义信息、直到清空整个软件缓冲区。 我正在使用 SysTick、因为它在不添加第三个中断的情况下可用。 [/报价]

    从技术上讲、它不会是第三个中断(如果它实际上更干净)。 如果逻辑上独立的函数不共享同一个中断、代码可能会更清晰。

    您必须注意的一点是、发送中断仅发生在通过 FIFO 阈值时、而不是发生在空时。 这是 UART 设计人员非常不幸的疏忽。

    [引用 user="Mike Fontes">您说得对、我需要弄清我为什么要获得 FaultISR。 我的问题是、我不确定要寻找什么、因为我不必在其他 Tiva、Stellaris 和 ST Arm 项目中处理这些问题。 我要求在如何确定系统不喜欢的方面提供一些帮助、因为我认为我正在正确使用这些功能。 我认为 UART 的设置存在一些问题、但不知道在哪里可以找到使用这些函数的完整 C 语言实现。

    我很确定有一个包含 TIVAWare 库的串行示例。

    还有一个有关故障排除的 TI 应用手册。 故障寄存器将告诉您故障源、然后您需要弄清楚这意味着什么、但它比"我在故障 ISR 中结束"要近得多。

    Robert

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

    我的计划是完全不使用 UART 发送中断、只需填充发送缓冲区、因为它是使用我在第一个帖子中展示的 SysTick 处理程序函数进行清空的。 我使用的命令结构不会被阻止、并且会在50ms 内完成大部分传输、对于短命令和数据应答来说、速度很快。

    我能够跟踪反汇编代码到发生故障的线路、并且可以查看寄存器。 我还无法确定寄存器值告诉我的内容、因为我还没有在器件数据表中查看过。

    您能告诉我在哪里找到故障排除应用手册吗?

    我仍然认为它在抱怨 UART 的设置、但我不确定要为其提供什么、因为我不想使用 TX 中断。 我只想加载 UART FIFO 并知道何时有可用字符。

    我在 UART_echo 示例中看到了 PutChar 非阻塞函数的简化用法、但它们不检查缓冲区中是否有空间、而是将字符填充到中。 我需要进行实际缓冲以防止丢失、因为我的缓冲区可以发送32个字符的命令、而硬件中只有16个字符的空间。

    此致、

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

    [引用 user="Mike Fontes"]我的计划是完全不使用 UART 发送中断,只需填充发送缓冲区,因为它是使用我在第一个帖子中显示的 SysTick 处理程序函数清空的。

    我意识到、我只是认为混合这样的功能是一个坏主意。 它会询问问题。

    [报价用户="Mike Fontes"]您能告诉我在哪里可以找到故障排除应用手册吗?

    来自 e2e.ti.com/search 中的第一个链接

    http://www.ti.com/lit/an/spma043/spma043.pdf

    [引用 user="Mike Fontes">我在 UART_echo 示例中看到了 PutChar 非阻塞函数的简化用法、但他们不检查缓冲区中是否有空间、而是将字符填充到中。 我需要进行实际缓冲以防止丢失、因为我的缓冲区可以发送32个字符的命令、而硬件中只有16个字符的空间。 [/报价]

    然后、将该检查逐步添加到示例代码中看起来是按顺序进行的。

    Robert

    我仍然建议使用发送中断、而不是从 SysTick 中断中添加发送中断。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Mike、
    如果您有32个字节要发送、它已经证明了创建更强大的传输解决方案的必要性。
    其理念是:
    -按字节将任何可以直接发送到 UART 硬件 FIFO 缓冲区,直至满。
    -将其余部分复制到单独的传输 RAM 缓冲器,然后返回到主应用程序
    从那以后、有两个选项:要么重新访问"ram 到 fifo transmission when you get a TX interrupt (当您收到 TX 中断时、ram 到 fifo 传输)"、要么以低优先级持续轮询以检查是否有更多的数据要发送、FIFO 空间要放置它。
    通过适当的组织、这可以可靠地传输您的命令、甚至超过32位-您的限制将是中间缓冲区的大小和 UART 通道的物理速度。 您还将能够"发送更多命令"(当然、发送到中间缓冲器)、即使在前一个命令完全从 MCU 传输出去之前也是如此。
    布鲁诺
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    布鲁诺

    我同意你的意见。  我认为我的设置可以正常工作。

    我创建了256个字符的 RAM 缓冲区。 我使用一个简单的 PutChar 函数加载它、该函数负责处理循环缓冲区要求、包括回绕检查。

    2.我计划使用 SysTick 作为轮询、以便在空间可用时通过调用我发布的原始函数向 FIFO 中添加字符。  我愿意在每个 SysTick 期间使用一个 FW 微秒来检查 FIFO 中是否有空间、还有更多的时间将每个 SysTick 最多10个字符放入 FIFO 中。  这使我得到了你所描述的投票。

    我遇到的问题是每次我尝试一次基于 ROM 或库的 UART 函数调用来放置或检查 FIFO 时、我都会得到 FaultISR。  我还没有机会确定由于某些排班优先级而导致的故障原因、但我将在今晚尝试进行检查。

    4、我不明白为什么在 SysTick 中断中检查 FIFO 寄存器的值并写入 FIFO 会有问题。 在主器件被禁用时、不应该有中断优先级覆盖。

    5.在过去的15年左右,我在多个 M3和 MSP430系统上使用过这种基本设置,因此我对故障感到困惑。  通常、我只需非常轻松地修改低级寄存器调用和其余的 C 软件端口。

    此致、

    Mike Fontes

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

    虽然我认为这是一个有缺陷的架构、但我认为使用 SysTick 不会导致您目前的问题。

    [引用用户="Mike Fontes">3. 我遇到的问题是、每次我尝试一个基于 ROM 或库的 UART 函数调用来放置或检查 FIFO 时、我都会得到 FaultISR。  我还没有机会确定由于某些计划优先级而导致的故障原因、但今晚将尝试对此进行检查。[/引述]

    这是第一。 我认为这与 ROM 函数也没有任何关系(除非你已经尝试过正常函数并且它们正常工作)。

    我怀疑这是内存问题。 您启用了外设、您没有?

    我首先尝试使用非 ROM 变体、ROM 变体没有太多优势。

    Robert

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

    如果您检查原始代码、您将看到我已经注释掉了可用字符的 ROM 版本、并尝试使用 driverlib 版本而不是 ROM 版本。 结果没有变化、因为我仍然得到 FaultISR。

    我尝试了几种不同的 UART 设置、其中启用了 TX 中断、启用了不同的缓冲区填充中断组合、但结果中没有发现差异。 这就是我添加原始帖子的原因。 我找不到一个使用 RAM 缓冲器的示例、该缓冲器需要由一些轮询技术提供、Bruno 定义了这一点、我认为我正在使用中断例程。 我发现的所有版本都设计为发送小于完整的数据 FIFO、尽管其中一个版本可能允许更多数据并崩溃、因为它不会查看填充 FIFO 时返回的布尔结果、只会继续发送额外的字符。

    在 MSP430中、我能够使用这个基本结构向蓝牙模块发送和接收几百个字符的数据串。 我只需弄清楚如何运行该版本。

    根据您看到的情况、您将如何解决 Bruno 讨论过的轮询问题、以便为 FIFO 充电? 当您需要通过从一个例程加载一个或两个初始字符、然后从另一个例程对 FIFO 执行轮询更新来启动 TX 中断系统时、我会担心有两种填充 FIFO 的方法。

    如果今晚的工作没有发现问题、我愿意尝试不同的想法。 了解他人如何解决类似问题总是很好的。

    此致、

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

    [引用用户="Mike Fontes"]
    如果您检查原始代码、您将看到我已注释出可用字符的 ROM 版本、并尝试使用 driverlib 版本而不是 ROM 版本。

    您也是这样做的。

    [引用 USER="Mike Fontes"]我尝试了几种不同的 UART 设置,其中启用了 TX 中断,启用了 Out 中断,并且使用了不同的缓冲区填充中断组合,但结果没有发现差异。

    我的更大问题是外设的启用、而不是其配置。 读取/写入未启用的外设会导致故障。 我认为从空 FIFO 读取或写入完整 FIFO 不太可能。 我对 FIFO 已满执行检查、因此我知道它不会导致故障。

    [引用 user="Mike Fontes"]根据您所见过的内容,您将如何解决轮询问题,以便为 FIFO 充电,正如 Bruno 所讨论的?

    首先、我会找到并修复故障。 其他所有内容都是次要的。

    [报价用户="Mike Fontes"]当有两种填充 FIFO 的方法时,我会感到担心

    有两种方法? 只有一个是我知道的。 除了处理 FIFO 阈值外、这是一个相当传统的 UART。

    Robert

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

    Mike、

    在您确认 ROM_或 TivaWare 函数会产生相同的问题(如预期的那样)之后、您可能只是遇到了"一个非常基本的问题"? 您是否尝试增加堆栈并查看其是否正常工作? 我非常喜欢直接启动高达4096字节的 TM4C129。

    现在、另一个因素是"假定"、您的循环缓冲解决方案已完全解决-可能是这样、但您是否确定了? 存储器损坏超过缓冲区限制会导致 ISR 故障、这种情况并不少见、而且这种情况可能很棘手。

    不过、您还提到了"您将在稍后的某个优先级之后调试故障 ISR "。 面对龙! 在调试这些故障时、首先听起来很痛苦和困难、大多数故障在分析的第一阶段或第二阶段之后澄清了原因-这些痛苦的"直到你习惯了60分钟"将为你节省120分钟、这些故障会在你的手指上徘徊、试图猜测原因...

    祝您好运、并告诉我们(好)的成果!

    布鲁诺

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

    布鲁诺

    你让我笑了!  我所讨论的优先级不是按照调试顺序进行的。  我有肾脏问题、准备进行透析、因此有时我不得不把有趣的东西放在一边处理健康的东西。

    我确信 RAM 缓冲是好的、因为它已经在大约8个不同的项目上进行了测试。  我测试绕回并相应地更新缓冲器的头部和尾部。

    我确实同意、我需要首先确定故障问题、我认为我可能会像您提到的那样堆栈。 我认为我使用 ROM 函数是正确的、因此涉及设置问题。 这就是为什么我要问是否有一个更完整的示例要看。

    或许、在我开始工作后、应该考虑应用手册。

    此致、

    Mike Fontes

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Mike、您能向我们展示您的设置代码吗? 您已经向我们展示了缓冲区代码、但我看不到设置代码。

    Robert
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    哦,我的!!! 你让我感到羞耻!!!
    在处理这些令人厌恶的字节之前、请务必确保您的健康!!!
    罗伯特似乎有一个如此有灵感的星期,我会一直在这里,如果我发现任何东西,我会帮助你,但现在让我放下来看看他的宝贵的下一步...
    谢谢
    布鲁诺
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Robert、

    我已经完成了一些调试、并将为您提供详细信息。  首先、下面的代码是 UART4的初始化代码。  很抱歉、评论不完整、但我不确定是什么情况、所以我不想过多记录、直到我确定要保留什么内容以及将要执行什么操作。

    /*********

      函数:     init_uart4


      说明:  此函数由调用

      参数:   无

      返回:      无

    秘书长的报告 /
    空 Init_Uart4 (空)

      //禁用中断
      ROM_IntDisable (INT_UART4);

      //将 GPIO A0和 A1设置为 UART 引脚。
      GPIOPinConfigure (GPIO_PA2_U4RX);
      GPIOPinConfigure (GPIO_PA3_U4TX);
      ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_2 | GPIO_PIN_3);

      //将 UART 配置为115、200、8-N-1操作。
      ROM_UARTConfigSetExpClk (UART4_base、g_ui32SysClock、115200、
                              (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
                               UART_CONFIG_PAR_NONE));

      //启用 UART 中断。
      ROM_UARTIntEnable (UART4_base、UART_INT_RX | UART_INT_RT);

      ROM_UARTFIFOEnable (UART4_BASE);
      ROM_UARTFIFOLevelSet (UART4_base、16、1);

      ROM_UARTEnable (UART4_base);

      //启用中断
      ROM_IntEnable (INT_UART4);


    我已经调试了代码、直到我多次遇到故障 ISR。  下面是在我遇到故障之前的 CCS 调试屏幕。

    我在右侧的"Disassembly"窗格中、准备好在92C 行上执行 blx。 我可以在前面的代码中看到、在这里测试了索引、并且缓冲区被测试为具有字符、因此我知道代码的这些部分实际上在工作。 下一步将导致 FaultISR。  我知道这是一个尝试读取 UART 4 UARTFR 寄存器的 TXFF 位时的故障。  根据您指向的应用手册、我从 NVIC 寄存器获得了寄存器信息。  该错误是合理的、因为它是由 ROM_UARTSpaceAvail 调用引起的读取。  令我感到困扰的一点是、当我尝试读取 UART 寄存器中的值时、我会获得寄存器窗格中显示的无法读取指示。  请记住、如果我滚动到它、我可以读取 NVIC 寄存器的内容。

    我仍然感觉自己设置的 UART 不正确、但不确定我做了什么错误。  我确实按照 Bruno 的建议将堆栈设置为4K、但功能没有变化。

    如果您需要任何其他信息、请告诉我。

    此致、

    Mike Fontes

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

    [引用 user="Mike Fontes">我已经完成了一些调试、并将为您提供详细信息。  首先、下面的代码是 UART4的初始化代码。  [/报价]

    谢谢、使用"过去的代码"选项会很有用 "使用丰富格式"中的图标。 只需内联粘贴代码通常会导致格式丢失。 作为一个额外的好处、粘贴代码会对行进行编号、以便于参考。

    也没有附加的图像。

    话虽如此、假设没有缺失的初始化代码、我可以很好地猜测这个问题。

    您不会初始化外设、也不会初始化 UART 和端口。 您直接进行配置而不进行初始化。

    您首先需要使用 SysCtlPeripheralEnable 调用对它们进行初始化、然后使用 SysCtlPeripheralReady 调用验证它们是否已通电并准备好进行检查。 作为优化、我先启用所有外设、然后再检查它们是否就绪。

    您可能在 UART 地址空间的某个地址处遇到存储器故障(您可以通过检查故障寄存器来验证该故障)。

    Robert

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

    Robert、

    我明白了!  我已经在启动时启用了 UART4外设、但我已将其移至 Init_Uart4函数。  但是这不是问题。  真正的问题是、您还必须启用 GPIOA 外设才能消除故障。 启用 UART 似乎不会启用它自动连接到的 GPIO 引脚。  我将初始化更改为以下内容、它工作正常。  

    /*********
    
    功能: init_uart4
    
    
    说明:主程序调用此函数以初始化 Uart4
    
    参数:none
    
    返回: 没有
    
    什么特别的 /
    void Init_Uart4 (void)
    {
    // bool READY = false;
    
    //禁用中断
    ROM_IntDisable (INT_UART4);
    
    //启用 UART 使用的外设
    //重要!! 必须启用 GPIOA 外设以避开 FaultISR
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_UART4);
    ROM_SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA);
    
    // READY = ROM_SysCtlPeripheralReady (SYSCTL_Periph_UART4);
    
    //将 A1和 A0引脚设置为 GPIO 引脚。
    GPIOPinConfigure (GPIO_PA2_U4RX);
    GPIOPinConfigure (GPIO_PA3_U4TX);
    ROM_GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_2 | GPIO_PIN_3);
    
    //将 UART 配置为115、200、8-N-1操作。
    ROM_UARTConfigSetExpClk (UART4_base、g_ui32SysClock、115200、
    (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
    UART_CONFIG_PAR_NONE);
    
    //启用 UART 中断。
    ROM_UARTIntEnable (UART4_base、UART_INT_RX | UART_INT_RT);
    
    //设置 FIFO
    ROM_UARTFIFOEnable (UART4_base);
    ROM_UARTFIFOLevelSet (UART4_base、16、1);
    
    //在此 UART
    ROM_UARTFlowControlSet (UART4_base、UART_FlowControl_none)上设置无流控制;
    
    ROM_UARTEnable (UART4_base);
    
    //启用中断
    ROM_IntEnable (INT_UART4);
    }
    

    这肯定是一个设置问题。 感谢你的帮助。

    此致、

    Mike Fontes

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

    [引用用户="Mike Fontes">我明白了!  我已经在启动时启用了 UART4外设、但我已将其移至 Init_Uart4函数。  但是这不是问题。  真正的问题是、您还必须启用 GPIOA 外设、才能消除故障。[/QUERP]

    正如我说过的、我在您的代码中找不到任何一个。

    你找到了。

    有一点、您仍然不会检查外设是否已启用。 您实际上应该这样做、否则您可能会取决于边际时间。

    Robert