如何在uCOS II和TM4C123G(ARM M4)MCU中实现硬件中断



背景:

我使用的是uCOS IIKeil uVision 5和一块带有TM4C123GH6PMMCU的TIVA板。我得到了uCOS II的端口以及一个空白项目文件。我编写了所需的任务,程序也能正常工作,但现在我对实现中断感兴趣,并试图了解它们如何与RTOS共存。这一切都是在C中完成的

问题:

中断不起作用;它们根本不会着火。在某些情况下,其他任务也不会执行。核心问题是,我并不真正理解中断如何与RTOS共存。我已经在裸机上编写了中断完美工作的代码(汇编和C),我完全理解当代码和cpu之间没有层时它们是如何工作的。

我尝试过的:

  • 我阅读了uCOS II附带的书籍和参考手册,并寻找实现中断的方法。只字未提;关于中断,唯一提到的是它们如何与调度器交互,因此中断只涉及理论领域
  • 我在micrium(原始供应商)论坛上问,没有回复/似乎是一个死论坛
  • 我查看了uCOS端口中包含的库,发现了一些有用的东西:

    • bsp_int是处理中断的库。BSP代表Board Support Package,旨在促进软件和代码之间的交互
    • 该库具有注册和启用中断的功能。rtos使用自己的ISR处理程序表映射到cpu的NVIC。所有处理程序都通过通用处理程序进行筛选。此库中的两个有用函数是:
      • bsp_intVectSet,它获取中断触发器ID(即bsp_int_ID_gpiof)和指向中断处理程序的指针并将其注册
      • bsp_intEn,它获取中断ID并启用它
  • bsp_int库包含在nbsp.c中,它为中断(bsp_IntInit())调用初始化函数(来自bsp_int)
  • nbsp.h文件包含在主应用程序文件(app.c)中
  • app.c main是该程序的入口点。main禁用中断,初始化uCOS(即内核),创建名为AppTaskStart的第一个/启动任务,并启动多任务处理(即控制rtos,函数永远不会返回)。我假设内核重新启用中断,因为它需要这些中断来运行
  • 因此,rtos的工作方式(据我所知)是劫持systick计时器,因此在每个时钟周期,内核都会被调用,并能够调度任务
  • AppTaskStart是在内核域中执行的第一个任务,它调用bsp_init(其中,调用bsp_IntInit来初始化中断表等)并执行其他初始化任务
  • 我以前在没有内核的情况下设置中断的方法是使用TI提供的Tivaware库(C)。它具有创建中断、指定触发器(即上升沿/下降沿、计时器溢出等)并启用它们的功能。这个方法有效,我认为这是我应该用来设置我想要的中断
  • 因此,我使用tivaware库在上升沿的一个gpio端口(机械开关连接到该端口)上设置中断。这方面的代码,以及启动端口f外设、将交换机引脚设置为输入和启用上拉的其他代码,都包含在bsp_init(bsp.c)中,该代码是从AppTaskStart调用的,该代码从main调用。到目前为止,一切都很完美,rtos启动了,它的所有任务都相应地执行。当我试图将代码直接移动到主代码并将程序闪存到板上时,rtos会初始化(LED闪烁),但任务不会执行。有什么想法吗
  • 如果我使用tivaware库中的代码添加代码来启用和注册同一函数中开关闭合时的中断,那么rtos不会初始化
  • 我是否需要使用tivaware库设置/注册/启用中断,以及使用板支持包(bsp)库注册和启用中断?到目前为止,我对这一点的理解是,bsp只为内核注册/启用中断,而tivaware代码通过直接写入寄存器来启用中断,因此需要后者来设置中断的cpu部分,而需要前者来设置中断中的OS部分。但我不知道。我真的不明白他们是如何在uCOS II下设计合并中断的。它们确实指定了应该如何编写中断处理程序以及使用什么宏,但没有其他内容

我下一步该怎么做?有人有使用这两个组件(rtos和板)的经验吗

我只是被困在这一点上,我一直在玩代码,四处移动东西,试图找到解决这个问题的线索/线索。我甚至不能调试rtos,因为uVision不支持uCOS,我也不能使用分步调试,因为每一个时钟周期都会有中断,而且电脑一直在变化,所以IDE无法跟上。

我知道IAR Embedded Workbench支持uCOS II,我的笔记本电脑上有这个应用程序,我试着建立一个项目,但我只得到了一个Keil的端口/启动程序项目,我不知道如何为IAR EW建立一个。Micrium网站上唯一的端口是TM4C129系列,我试着用它来启动IAR EW项目,但我无法让它工作(库没有链接/缺少文件)。

谢谢

有人有使用这两个组件(rtos和板)的经验吗?

恐怕我还没有使用过uCos(但使用过其他操作系统,主要是SysBios和FreeRTOS),也没有使用过Tiva(但使用了Sitara AM335x)。尽管如此,我认为下面的一些提示可能对您有所帮助(尽管您使用的实现不同,但仍然适用)。

我下一步应该尝试什么?

我建议您考虑以下步骤。你可以把它们按你觉得最有用的顺序排列。

  • 调用RTOS库API的ISR的中断优先级不得高于RTOS考虑的级别,否则RTOS内部状态可能会损坏,任何事情都可能发生。请查看您的操作系统文档。

  • 请验证中断矢量表的位置及其内容:每个矢量表条目是否都指向RTOS提供的ISR包装处理程序之一,或者您是否也找到了"独立"的ISR实现?如果是,后者会做什么?如果你找到了指向你没有代码的第三方库的指针,不要放弃。这些可能同样重要。。。甚至比将正确的报头包括到bsp_Int...API更重要的是,所有软件组件的中断管理都通过一个唯一的API运行,例如bsp_Int...API。

  • 你对app.c/main()的假设听起来很合理。请确保您还了解间接访问中断的每个组件。

    • AppTaskStart是在内核域中执行的第一个任务,它调用bsp_init(其中,调用bsp_IntInit来初始化中断表等)并执行其他初始化任务

    请检查如果在每个任务函数的顶部放置断点会发生什么。然后,您应该能够观察所有任务启动并运行到其断点一次。

    • 我以前在没有内核的情况下设置中断的方法是使用TI提供的Tivaware库(C)。它具有创建中断、指定触发器(即上升沿/下降沿、计时器溢出等)并启用它们的功能。这个方法有效,我认为这是我应该用来设置我想要的中断

    您应该确保Tivaware库仅以与RTOS兼容的方式使用中断。你可以通过RTM或阅读来源来做到这一点。

    • 所以我使用tivaware库在上升沿的一个gpio端口(机械开关连接到该端口)上设置中断。这方面的代码,以及启动端口f外设、将交换机引脚设置为输入和启用上拉的其他代码,都包含在bsp_init(bsp.c)中,该代码是从AppTaskStart调用的,该代码从main调用。到目前为止,一切都很完美,rtos启动了,它的所有任务都相应地执行。当我试图将代码直接移动到主代码并将程序闪存到板上时,rtos会初始化(LED闪烁),但任务不会执行。有什么想法吗

    可能是连接到中断的控制器引脚之一的电子问题开始一直触发该中断吗?

    • 如果我将代码添加到[…]

    您是否尝试创建最小可重复的例子?当你这样做时,你可以通过同时执行橡皮鸭调试。

    • 是否需要使用tivaware库设置/注册/启用中断,以及使用板支持包(bsp)库注册和启用中断?到目前为止,我对这一点的理解是,bsp只为内核注册/启用中断,而tivaware代码通过直接写入寄存器来启用中断,因此需要后者来设置中断的cpu部分,而需要前者来设置中断中的OS部分。但我不知道。我真的不明白他们是如何在uCOS II下设计合并中断的。它们确实指定了应该如何编写中断处理程序以及使用什么宏,但没有其他内容

    这听起来很危险。我还没有使用Tiva,而是使用另一个TI芯片(AM335x)。在那里,我们遇到了类似的情况,不同的库通过不同的抽象层访问同一系统资源的不同/重叠部分。当我们清理了相互忽略的抽象层的混乱,并将一些代码移植到一个通用的抽象分层方案中时,情况才开始好转。

和一些PS:

  • 您可以随心所欲地用C或汇编程序编写ISR。根据工具链的质量和优化设置,汇编程序可能会产生更好的性能(或者根本不会),并且通过从汇编程序调用C API,一些程序员往往会犯新的错误。我建议您保持在C中,直到您详细了解操作系统和IRQ发生了什么

最新更新