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.

[参考译文] TM4C123GH6PM:伪波定时器中断

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/615981/tm4c123gh6pm-spurious-timer-interrupt

器件型号:TM4C123GH6PM

我将获得伪波计时器中断。

我之所以将其称为"假"、是因为我认为在计时器经过其计数周期和超时后才会发生。 但它会立即发生。

它的可重复性或多或少、在我尝试重现它的次数中、发生的次数大约为50%。 它发生在程序的启动逻辑期间、恰好在我启用中断之后、尤其是在闪存通过 CCS 对器件进行编程以启动调试会话之后、但也可能发生在系统复位或内核复位之后。

我认为发生这种情况是因为 GPTMRIS / GPTMMIS 位0已经打开、可能是通过程序前一次运行、也可能是因为我的错误。 我还没有找到这个位的原因是1。

奇怪的是、我认为我的计时器设置代码应该清除这个。 我仅使用 TivaWare 调用。

我的印象是在执行序列 TimerIntEnable()、IntEnable()、TimerEnable()之前调用 TimerIntClear ()会导致在计时器超时之前不会触发中断。

但显然 TimerIntClear ()还不够。 为了避免这个问题,必须在 TimerIntEnable()、IntEnable()、TimerEnable()之前进行哪些额外的调用?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好!
    CPU 跳转到哪个中断向量编号? 我只想确保它是 CPU 跳转到的计时器模块 ISR 之一。
    您能否确认 GPTMRIS/GPTMMIS 位0是否确实被置位? 如果您认为中断来自计时器、甚至在启用计时器之前、也许您可以临时修改计时器 ISR 并放置一个 while (1)、并调查 NVIC 和计时器寄存器。
    如果您有不同的电路板、您可以重复相同的行为吗? 这将有助于将问题与您的程序代码隔离。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢你的答复。 我将放置 while (1)循环并查看 NVIC。 如果根据经验进行猜测、哪些寄存器是最可能的罪魁祸首?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、12月12日下午、
    我想您首先要查看 PRIMASK、ENx 和 PENDx 寄存器、看看它们是否在启动期间设置、因为您报告了中断是在运行到 main 之前获取的、您的代码将在其中启用中断。

    我还建议您查看并运行 TivaWare 库中的 timers.c 示例。 该示例生成周期性中断。 在中断被启用前、它不会生成中断。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    顺便提一下、在查看寄存器时、我如何知道何时使用矢量编号(在本例中、对于 INT_TIMER1A 为37)以及何时使用中断编号(在本例中为21)? 仅为了澄清一下、INT_TIMER1A 将出现在 NVIC 寄存器 EN0位21中、而不是 EN1位5中?

    此外、在 TM4C123GH6PM 数据表的第104页的表2-9中、矢量地址或偏移列的含义是什么? --对于这个矢量/中断,它给出了0x0000.0094。 该数字指的是什么? 感谢您的耐心:-)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    以前我错了。 在 main()运行之前,中断不会触发。 它在定时器和中断被启用后、但在定时器运行了一段时间之前立即触发。 我想我知道原因、但还不确定。 到目前为止、我发现了以下内容:

    1.我的计时器配置为在内核暂停时继续运行。 (这是一个错误、需要改变。)

    2.当程序之前运行时、定时器和中断被启用。

    3.由于(1)和(2)、当 CCS 对部件进行闪存编程并启动调试会话时、定时器(每1ms 触发一次)继续运行、超时并设置 GPTMRIS / GPTMMIS 位0。

    NVIC 挂起中断(NVIC_NVIC_PEND0 0xe000e200第21位被置位)

    5.当内核再次开始执行时,定时器外设和 NVIC 中的这些位仍然置位。 (CCS 执行内核复位、而不是完全系统复位。 区别在于内核复位会使这些寄存器保持不变;系统复位会将它们清零。 当然、无论如何复位、都必须使程序正常工作。)

    6.我的初始化代码在防止这种情况的有效但失败的努力中调用了 SysCtlPeripheralDisable()、SysCtlPeripheralReset()、SysCtlPeripheralEnable()。 这会清除 GPTMRIS / GPTMMIS、但损坏(NVIC_NVIC_PEND0)已完成。

    7、同样、TimerIntClear ()清除 GPTMRIS / GPTMMIS、但不会在 NVIC 中取消挂起中断

    8.在程序的稍后部分、定时器和中断被使能;立即触发一直挂起的中断。

    如果这是正确的、那么在启用中断之前、我需要在启动代码中取消挂起中断。 我认为我应该进一步、解开所有中断、以确保这种情况不会再次出现。 在我验证这一问题是否解决后、我需要配置计时器以在 CPU 暂停时暂停。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、12月12日下午、
    您可以对问题进行合理的分析。 即使对于 CPU 内核复位、NVIC 寄存器也应该被清零。 可能会发生的情况是,在调用 TimerIntClear ()之前,您的主代码中可能会有 IntMasterEnable()。 在此窗口期间、可能会有一个计时器中断从之前的运行中生成。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Charles、

    NVIC 是 ARM 内核的一部分、因此应该清除这些寄存器。 但是、从我观察到的情况来看、它们似乎不是。 我正在使用 CCS 存储器浏览器。 这是否被视为检查此类寄存器的正确方法?

    IntMasterEnable()正在发挥作用。 该程序结构为轮询超循环。 程序中的每个模块(有很多!) 结构为有限状态机。 其中一些、例如使用相关定时器的模块、可以启动、停止和重新启动。 这几乎是正确的、当然除了不需要的中断!

    main 的结构非常标准:

    1.初始化硬件

    2.调用 IntMasterEnable()

    3.运行超级循环

    在第1步中的某个位置,计时器外设正在使用以下调用序列进行部分初始化:TimerConfigure()、TimerUpdateMode()、TimerPrescaleSet()、TimerLoadSet()、IntPrioritySet()、 TimerIntClear ()。

    在步骤3的后面部分、当超级循环运行时、会发生一个事件、该事件应启用计时器并进行中断。 此时,我将使用 IntMasterDisable()输入关键段,然后执行以下调用序列:TimerLoadSet()、TimerIntClear ()、TimerIntEnable()、IntEnable()、TimerEnable()、TimerEnable()、 然后使用 IntMasterEnable()退出关键段。

    在这个 IntMasterEnable()之后立即触发不需要的中断。

    我应该在 TivaWare 中的哪个位置搜索函数来解除中断挂起? 我将把它添加到计时器启用序列中。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    没关系,我发现了它:IntPendClear()。 这有多明显?! 我将测试并报告这是否解决了问题。 感谢你的所有帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在测试中,似乎在启用计时器和中断之前添加 IntPendClear()调用可防止不需要的中断。 这里的课程是、中断管理在外设和 NVIC 之间进行分离、并且必须对二者进行管理以实现所需的结果。

    顺便提一下,我很高兴你推荐了 timers.c 示例,因为我学到了一些不相关但非常重要的东西:FPULazyStackingEnable()!! 我的印象是,如果使用了编译器,它会堆栈浮点寄存器,但显然情况并非如此,并且必须通过此调用或更剧烈的 FPUStackingEnable()来明确启用堆栈。 缺少此调用可能会导致很难跟踪的问题!

    此外、由于我们谈到内核复位、我在 TM4C129中遇到了一个有趣的不相关问题、在该问题上、新调试会话经常会将芯片启动到一些 LA 区域中、程序计数器设置为一些奇怪的0xffffffe 值、直到我手动暂停、执行系统复位和重新启动。 这仅在调试时发生、仅在 GCC 中发生、我没有看到在正常上电时发生。 我强烈怀疑我的启动文件和/或自定义链接器脚本有问题。 我在这里提到它只是因为我们谈到了内核复位以及是否清除了问题。 稍后、我将在单独的线程中继续...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12PM"]我的印象是,如果使用了编译器,它会堆栈浮点寄存器,但显然情况并非如此,必须明确启用堆栈

    从角度来看、请注意一下。 大多数微控制器都是如此、这是有充分理由的。 必须以某种方式保存浮点寄存器集会增加中断的相当长的延迟、对于某些 RTOS/MICRO 组合、由于涉及开销、即使对于任务切换、也是可选的。 始终、在存在任务开关和中断的情况下、始终对浮点行为保持怀疑、直到您验证了详细信息。

    Robert

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

    [引用 user="12ve12pm"]这里的课程将中断管理划分外设 NVIC 之间并且必须对二者进行管理才能实现所需的结果。

    在"喝库勒-援助"或提出理论以教训地位之前,不妨考虑以下问题:

    • 无/零供应商计时器示例-包括外设文件夹和其他位置中的所有示例-采用此类"分离"管理。 努力/关注
    • Fire/I -雇用了前身供应商(LMI)和当前供应商的实现(10年以上)-也发现"没有这样的"分离"管理。  需求。
    • 如果这一"教训"被证明是真的--是否没有(许多)标记过这一点--寻求帮助?   (显然他们没有)
    • "课程状态"-从一个板、一个 IDE、一个用户、可能是高度个性化的设置/配置-可能证明是"过度促销"。

    没有人会对您的时间/想法/努力产生折扣-但这种"概括性"要求进行更严格的检查-而(上面列出的)注意事项需要(一些)注意...

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

    [引用用户="Robert Adsett72"]

    12时12分
    我的印象是、如果使用的话、编译器会堆栈浮点寄存器、但显然情况并非如此、并且必须明确启用堆栈

    [/报价]

    感谢您的意见。 我很高兴我学会了这种简单而不是艰难的方法! 从现在开始、浮点数将更加小心。 :-)

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

    [引用 USER="CB1_MOBILE"]

    12时12分
    这里的课程、中断管理外设 NVIC 之间进行分离并且必须对二者进行管理以实现所需的结果。
    • 无/零供应商计时器示例-包括外设文件夹和其他位置中的所有示例-采用此类"分离"管理。 努力/关注
    • Fire/I -雇用了前身供应商(LMI)和当前供应商的实现(10年以上)-也发现"没有这样的"分离"管理。  需求。
    • 如果这一"教训"被证明是真的--是否没有(许多)标记过这一点--寻求帮助?   (显然他们没有)
    • "课程状态"-从一个板、一个 IDE、一个用户、可能是高度个性化的设置/配置-可能证明是"过度促销"。

    没有人会对您的时间/想法/努力产生折扣-但这种"概括性"要求进行更严格的检查-而(上面列出的)注意事项需要(一些)注意...

    [/报价]

    尊敬的 CB1_MOBILE:

    我们始终欢迎您的意见。 我同意您在这里的大多数观点、当然、此处学习的"课程"可能与我们特定的硬件、软件、开发人员工具、我们奇怪的自定义链接器脚本和启动文件、启动配置、桌面操作系统以及谁知道其他什么相关。

    我不会对您和您的公司在使用这些器件超过十年的情况下所说的内容进行折现、而不会出现此问题。 使用这些芯片的方式很可能会有差异、但我们对 TM4C 和 ARM 非常陌生、这种情况并没有帮助我们。

    不过、我清楚地看到、NVIC 挂起寄存器在不应该包含时包含1、或者在我不希望包含时更准确。 当 CCS 执行闪存编程序列并启动调试会话时、该器件似乎复位了几次、当 CCS 从一个步骤移动到下一个步骤时、 该器件从复位中释放、并在再次复位之前部分运行程序。 它似乎是内核重置、尽管我已经阅读过、但似乎不会重置某些内容。 这可能是我们特定设置中某种情况的伪影。

    无论原因如何、都没关系。 程序必须初始化芯片并正常工作,即使问题(当前)仅在闪存编程和调试期间出现----例如,考虑如果我们实施引导加载程序并在现场执行闪存升级,会发生什么情况。 我们不能允许先前运行的过时状态影响执行。 这与输入 C 函数和初始化其局部变量没有什么不同、因为您不能也不能假设它们在输入时是清除的。 有时、它们可能是旧数据、但该存储器中很可能存在旧数据。

    此外、我认为中断处理在外设和 NVIC 之间进行划分并不过分。 例如,您必须执行 TimerIntEnable()和 IntEnable()才能启用中断。 因此、正如我们所看到的、以前挂起的中断可能会保持挂起状态、等待您启用中断的时刻、我认为在初始化期间通过取消挂起中断来处理这种可能性是明智的。 即使它没有什么成就、也不会因为它的存在而丢失任何东西。

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

    再次感谢您-您提出了一个有趣的问题-如果您返回到自己的过去一篇文章(我能够解决)-"中断挂起"得到了很好的注意!    (位于线程后端/周围)

    由于您是"detail Maven (详细 Maven)"的"位"、因此您想知道您选择 IDE 后会产生多少此类问题。   在这里(实际上)能否与更成熟、更随和(即"任何"ARM 供应商的 MCU)、更大(且满意)的竞争? 用户群-和(单独)专注于"IDE"    (因此、"Exclusive IDE Development & Support"的可用规模和资源可能会"受到任何单一、基础广泛(主要是芯片)供应商的"影响"-它们不是吗?)

    您的重要工作投入到可能证明存在"单一供应商异常"(弱点)的技术技能、时间、精力上可能会被证明是次优。   此外-如何证明您"锁定自己"一家供应商是合理的?    M0、M3、M7s (所有 Cortex)在哪里-您必须知道供应商-几乎经常-"互相跳跃"-因此"单一供应商 MCU 和 IDE 投入"似乎与您通常的"深思熟虑、展示和定向努力"不同步-定期来到这里...

    作为一项(潜在)比较工作- IAR 提供了其 ARM "Kickstarter"的32KB (代码大小受限)免费版本。    数千名员工(自愿)购买了"正常"版本、从而能够免费轻松地迁移到(其他) ARM MCU、这一事实表明、"IDE 专业化/独家关注 "确实会带来强大的功能、效率和(多个)优势...

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

    [引用 USER="CB1_MOBILE"]

    再次感谢您-您提出了一个有趣的问题-如果您返回到自己的过去一篇文章(我能够解决)-"中断挂起"得到了很好的注意!    (位于线程后端/周围)

    由于您是"detail Maven (详细 Maven)"的"位"、因此您想知道您选择 IDE 后会产生多少此类问题。   在这里(实际上)能否与更成熟、更随和(即"任何"ARM 供应商的 MCU)、更大(且满意)的竞争? 用户群-和(单独)专注于"IDE"    (因此、"Exclusive IDE Development & Support"的可用规模和资源可能会"受到任何单一、基础广泛(主要是芯片)供应商的"影响"-它们不是吗?)

    您的重要工作投入到可能证明存在"单一供应商异常"(弱点)的技术技能、时间、精力上可能会被证明是次优。   此外-如何证明您"锁定自己"一家供应商是合理的?    M0、M3、M7s (所有 Cortex)在哪里-您必须知道供应商-几乎经常-"互相跳跃"-因此"单一供应商 MCU 和 IDE 投入"似乎与您通常的"深思熟虑、展示和定向努力"不同步-定期来到这里...

    作为一项(潜在)比较工作- IAR 提供了其 ARM "Kickstarter"的32KB (代码大小受限)免费版本。    数千名员工(自愿)购买了"正常"版本、从而能够免费轻松地迁移到(其他) ARM MCU、这一事实表明、"IDE 专业化/独家关注 "确实会带来强大的功能、效率和(多个)优势...

    [/报价]

    就我选择的 IDE 而言、目前我们使用 CCSv7进行 TM4C 编程。

    感谢您提到 IAR Kickstarter。

    一般而言、我并不关心 IDE 是什么、因为大部分时间都是编辑代码、我从未使用 IDE。 我在已经使用了近二十年的付费文本编辑器 UltraEdit 中进行所有源代码编辑。

    原因是、除了在少数 MCU 平台上进行嵌入式编程外、我们还在三个平台上维护桌面软件、就 IDE 而言、我个人使用各种不同的实现方式、分别是 MS Visual Studio、Eclipse (包括 CCS)、Xcode、Code:::blocks、 以及各种较小的较旧 IDE、有时甚至是在同一天! 对于类似的操作、每个键盘都有自己的略有不同的击键组合、有些键盘可以执行其他键盘无法执行的操作、而 Eclipse 中的"清理"在 MS Visual Studio 中被称为"全部重建"。 让自己的头旋转就够了! 因此、无论 IDE 或平台如何、IDE 的用途仅限于构建、闪存编程和调试。

    不过、如果我能够弄清楚调试属性(在 Project Properties 中)的作用以及我们的设置如何影响闪存编程/调试、那会更好。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    (较小) IDE (单独)可能会导致您的延迟和沮丧这一简单事实已被避免。 "回避"从未被置于高优先位置-似乎(很大程度上)远离您的"规范"。 (此处检测到-直至您最近一次写入。)

    工具至关重要-影响"有"的选择很少证明是"明智和/或富有成效的"选择...
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我可以告诉您不是 CCS 的粉丝。 我可以告诉您、我看到过更糟的... 更糟。 我也见过更好的结果、也就是说、我更喜欢小型、简单、易于使用的 IDE、以及那些其项目文件格式适合置于版本控制之下的 IDE。 CCS 基于 Eclipse、因此它非常庞大、具有所有优缺点。 我并不是说这必然是好事或坏事、只是说它就是它的样子。 幸运的是(或者不幸的是、根据您的观点)我从2007年前后就使用过 Eclipse、因此我知道如何处理 Eclipse。

    工具至关重要。 我完全同意。

    但是... 我要避免的是在中流中切换马匹。 选择一组工具、语言等非常容易、启动项目、遇到问题(无论工具如何、问题都是不可避免的)、并开始转换匹配电系统。 我已经使用了足够大的软件包、知道所有工具都附带了警告。 当然、我们可以进行切换、但我们使用这个、因为我们确实进行了切换! 因此、我的原理是、我们可以使用工具、将程序加载到芯片中、并且调试器中的单步执行工作正常。 将会出现不可避免的问题、我们只需解决这些问题、缓解问题或以某种方式处理这些问题。 当我们开始下一个项目时、我们可以评估其他可能性。

    对于导致此主题的 IDE、这是可能的、但尚未得到证实。 我满意地证明、无论程序启动时内核或芯片的状态如何、我的代码都无法确保初始化到足够干净的状态。 我认为这比指着 IDE 或其他工具更加重要。 就我而言、我不在乎开发系统是什么样子的。 无论产品是冷启动、热重启、固件升级还是其他情况、我都只关心产品是否能够正常运行。 (该单步执行有效。 这是我最大的宠物前峰、单步执行不起作用。 是的、我知道您应该使用-O0和调试信息进行编译。 我所说的是某些 IDE、其中它在一半时间内仍然无法正常工作!)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12PM">我可以告诉您不是 CCS 的粉丝。 我可以告诉您、我看到过更糟的... 更糟。 我也见过更好的结果、也就是说、我更喜欢小型、简单、易于使用的 IDE、以及那些其项目文件格式适合置于版本控制之下的 IDE。 CCS 基于 Eclipse、因此它非常庞大、具有所有优缺点。[/quot]

    *喜欢*喜欢*喜欢*喜欢*喜欢*喜欢*喜欢*

    我完全同意你的意见。

    好消息是、如果您将 IDE 用于交互式调试器、那么您唯一需要 IDE 的事情是(我可能会离开这里、因为很少使用 IDE)。 否则、任何合适的编译器都可以从 make 等编译系统运行、然后您可以使用熟悉的编辑器和其他高效工具。

    除非以其他方式受到限制、否则我始终首先从命令行运行工具。 它通常很简单、让您完全控制。

    Robert

    我发现唯一需要 IDE 的时间是 C 编译器、它与 C 的相似性主要是偶然的。

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

    [引用用户="Robert Adsett72"]

    12时12分
    我可以告诉您不是 CCS 的粉丝。 我可以告诉您、我看到过更糟的... 更糟。 我也见过更好的结果、也就是说、我更喜欢小型、简单、易于使用的 IDE、以及那些其项目文件格式适合置于版本控制之下的 IDE。 CCS 基于 Eclipse、因此它非常庞大、具有所有优缺点。

    我完全同意你的意见。

    好消息是、如果您将 IDE 用于交互式调试器、那么您唯一需要 IDE 的事情是(我可能会离开这里、因为很少使用 IDE)。 否则、任何合适的编译器都可以从 make 等编译系统运行、然后您可以使用熟悉的编辑器和其他高效工具。

    除非以其他方式受到限制、否则我始终首先从命令行运行工具。 它通常很简单、让您完全控制。

    Robert

    我发现唯一需要 IDE 的时间是 C 编译器、它与 C 的相似性主要是偶然的。

    [/报价]
    我们可能必须采用命令行构建系统。 据我所知,如果您使用 CI (连续集成),则实际上是强制性的。 目前、我们会手动完成一个过程、即构建 各种构建配置、在多个平台上运行自动测试等 CI 可以实现自动化、但显然需要付出一些努力才能启动和运行。
    说到自动化测试和调试器... 在我们的应用中、使用调试器通常是不可行的、因为程序无法停止。 因此、我们最大限度地减少了对调试器的需求:我们通过两种方法来仪器化代码、使其能够在计算机上显示"实时"数据、并且我们拥有一个用于所有平台独立(算法)代码的自动测试套件。 我们使用各种编译器构建这些测试、并在多个平台上运行。 当所有编译器和所有平台上的所有测试都通过时、这并不能保证测试的正确性、但它提供了一定程度的可信度。 多年来、我们通过自动测试发现了许多模糊的错误。 在这两个方面之间、我们只需在低级平台特定的情况下使用调试器、例如提示此线程的情况。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12pm]\n 我们可能必须采用命令行构建系统。 据我所知,如果您使用 CI (连续集成),则实际上是强制性的。 [/报价]

    我认为、您必须为 GUI 编写脚本。

    [引用 user="12ve12pm]]目前,我们手动完成一个过程,即构建 各种构建配置,在多个平台上运行自动测试等 CI 可以自动执行该操作,但显然需要付出一些努力才能启动和运行。

    我当前的构建过程。

    • 制造。 我一直在关注其他系统、但到目前为止、似乎没有一个更好的系统。 我有一个系统会导致小型 makefile 文件来管理构建过程、但它确实需要构建支持文件。
    • PC 内部 可以使用其他静态分析工具、但 PC-Lint 非常有效(具有强大的键入和值跟踪功能)、而且价格不贵。
    • 单元测试(当前为 Google 测试和 FFF)
    • 编译器

    make 强制执行 lint、test、compile 顺序。 除非代码通过 lint,否则不会测试代码。 在通过单元测试之前不编译代码、如果缺少单元测试、编译将失败。 任何自动生成的代码都在线性之前完成。 有项目和系统级 make 配置文件、用于设置规则和选择合适的编译器和选项。

    lint 也用作依赖关系生成器(以及一些 sed 和 awk 脚本)。 make 的一个缺点是跟踪头文件。 这很好地解决了这个问题。 lint 还具有系统(这些是默认规则)和项目(这些是此项目的例外情况)。 供应商库等) 配置文件。

    在要添加的心理队列中。

    • 对测试用例进行线性处理
    • 添加硬件单元测试。

    如果您没有使用 PC-Lint 或等效的 PC、我强烈推荐它。 它将检测未通过其他测试的错误、尤其是类型错误。 令人惊讶的是、它将发现基本上属于设计错误的误差。 不是直接的、而是简单地作为它发现的错误的结果。 如果使用一致、它将更好地更改您编写的代码、尤其是在您加热时。 #PC-Lint范围和值检查

    [引用 user="12ve12pm"]在这两种情况之间,我们只需在低级平台特定的情况下使用调试器,例如提示此线程的情况。

    我也不会为此使用调试器。 一般而言、我只会因为艰难的比赛条件和类似情况而对它感到不安(我们是如何达到这一不可能的点的?)。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我们自2006年以来一直在使用 PC-Lint、但不是您使用它的方式。 它会产生大量的输出、其中大部分不适用于我们。 是的、我知道可以指示它禁止某些消息、我们可能必须这样做。 我想提出几种配置、其中一种配置只显示最重要的消息并自动运行、而另一种配置具有不同级别的详细信息、可不时手动运行。

    目前、我们以手动方式使用它、并且有很多详细信息、我们会费尽周辛劳地浏览输出、寻找任何令人震惊的东西。 它是一个宝贵的工具、过去曾遇到一些棘手的问题。

    为了使我们的代码更可靠、我们做的最大事情之一是将大部分代码结构化到自包含库中、我们使用 svn:externals 将这些库拉入我们的工作副本中。 此代码与固件项目的其余部分一起编译。 这消除了我们过去遇到的一个巨大问题、即许多常用函数从一个固件项目复制粘贴到另一个固件项目、最终它们之间的代码变化不可避免。 一个固件中修复了一些错误、但另一个固件中没有修复。 这是一场噩梦。 有一次、我们花时间收集所有这些函数、对所有这些函数进行协调、并将它们结构到我们的库中、该库作为自己的 Subversion 项目进行管理、具有自己的版本编号等、就像外部供应商提供的库那样。 它在我们编写的测试套件中经过了大量测试、我们使用 MSVC、GCC、LLVM、TI 的编译器以及其他多个工具进行编译、 不同版本的 C 标准、并可在多个硬件平台上运行。 所有测试均通过。 我们知道它很好并且工作正常。 我们还获得的优势是、如果以某种方式扩展库、我们的固件项目不会中断、因为 svn:externals 会拉取一个标记非常具体的库"发布"、直到我们明确地告诉它使用更新的版本。 因此、我们可以随意破解该库、而无需担心任何中断、然后在测试后创建"发布"、并仅在准备好执行此操作时才将每个固件项目更新为新版本。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用 user="12ve12pm]2006年以来,我们一直使用 PC-Lint,但不是您使用它的方式。 它会产生大量的输出、其中大部分不适用于我们。 是的、我知道可以指示它禁止某些消息、我们可能必须这样做。 我想提出几种配置、其中一种配置只显示最重要的消息并自动运行、而另一种配置具有不同级别的详细信息、可不时手动运行。

    我通常发现、大多数"不适用于我们"的消息要么是配置错误、要么确实适用、但您尚未识别、至少在较低的警告级别。 我必须关闭一个合理的数字、然后我也运行在-W4。

    lint 会捕获大量内容、其消息比我使用的任何编译器都要好得多。 它还捕获了至少一些项目、例如错误的参数值(我没有看到任何编译器可以管理这些值)、并且在该过程中比测试更早。

    [引用 user="12ve12pm"]现在,我们使用它的手动方式具有大量的详细信息,并且我们费尽周折地浏览输出,寻找任何令人震惊的东西。

    这实际上保证了您不会定期使用它、而且您肯定不会获得全部好处。

    这是我的 std.lnt、它包含在所有项目中、而不考虑处理器

    //标准(非特定于处理器的 lint 选项
    //由特定于处理器的文件
    au-misra2.lnt
    -esym (960、16.9)包含//与错误540直接矛盾, 在
    函数前面选择540 no 和//作为指针
    -elib (960)//库可能不符合 MISRA
    
    的-a// ANSI 合规
    性+stack//跟踪堆栈用法
    -estring (974、RECURSIVECI*)//最坏情况下函数堆栈用法关闭 MISRA 兼容*/
    -passes (6、-v)// 6通过, 报告呼叫和步行
    -W4//打开警告级别
    -rw (*ms)//无 ms 关键字
    -Strong (AizXJcmdz)//在 init 上忽略强类型
    //允许与0进行比较和分配
    //维度一切
    //忽略与常量组合
    //忽略乘法运算符(依赖于维度检查)
    -Strong(B)、bool)//布尔
    //基本类型不强
    -Strong(,uint32_t)
    -Strong(,int32_t)
    -Strong(,uint16_t)
    -Strong(,uint8_t)-Strong(,uint_least8_t)
    
    -Strong(,uint_8_t)-fastore/(+fast_br/en_br)-fast_br/(/en_br/fast_zh_br)
    
    
    
    
    
    +fSC//字符串是 const
    +fxa//指针/数组匹配的 args
    -vfs#h-// lint 执行时显示的内容
    -vh
    -hsFa|3//消息表示
    格式-format=%("%f"、%l\s%%)%t\n:\s%m
    
    -e537/太吵。 有效地分解嵌套的包含。
    //打开可选消息。 标记为实验的消息被 TRICE909
    //隐式转换为 bool
    -E910//允许0等效为 NULL
    -e911//将较短的整数类型提升为较大隐式
    -e912//操作中隐式转换为较大类型
    -estring (915、赋值)//赋值
    时隐式转换+e916// 隐式指针赋值
    -e920//转换为 void。 引发关于使用 void 来
    //忽略返回值的投诉。
    -e921//允许将显式整型转换为整型。
    -e925// MISRA C++指向指针转换的指针
    -e935// int 用作结构成员
    的类型+e936// K&R 样式函数定义
    +e937// K&R 样式函数声明
    +e938//未显式声明的参数
    +e940//返回类型默认为 int
    +e941//操作计算为0
    +e942// 布尔
    运算符的可能截断加法+e944 //参数计算为与
    extern (可移植性)
    +e950一起使用的固定值+e945 //未定义结构//非 ISO/ANSI 保留字
    -e952//参数可以声明为 const (但 C 是按值传递的)
    +e953//变量可被声明为 const
    +e954//指针变量可被声明为 const
    +e955//原型
    +e956中缺少参数名称//实验-非 const、非易失性外部(线程检查)
    +e957//函数定义不需要原型
    -e958//填充。
    -e959//结构大小不是对齐的倍数
    +e960// MISRA 需要
    +e961// MISRA Advisory
    -esym (961,19.7)//允许函数类宏
    +e962//符号重新定义
    -e964//头文件不直接使用,但包含文件 TAHT。
    -e970// MISRA 不使用裸类型? 6.3
    -e971//使用 char w/o signed Traps 用作字符串指针
    -e974//最坏情况堆栈使用始终失败 lint
    -e1960//
    
    禁止 MISRA C++错误(我们没有任何 C++)-esym (829、string.h)//允许使用内存函数-esym (829、limits.h)/允许 使用(MISRA)大小(允许使用)/允许使用(允许使用)
    -esym (829、stddef.h)//允许使用标准定义(MISRA C++禁止)
    -header (c:/lint/unit_check.h)
    

    您可以看到、它相当短。 它不会关闭太多、实际上会打开其他警告。

    和我的 project.lnt 它设置了特定于 Tivaware 和 tm4c 的选项以及特定于项目/处理器的其他问题

    // TivaWare 特定选项。
    +libdir ("C:/TIVA")
    --elibmacro ((923))// int 到指针转换
    -elib (960)//预计没有 MISRA 兼容
    性--elibmacro (960)//预计没有 MISRA 兼容
    性--elibmacro (960)//预计没有 MISRA 兼容
    性--elibmacro (960)//预计没有未签名的宏(917 Base)/liblas*,应该被声明为无符号偏移量。
    --emacro ((835)、ADC_CTL_*)//某些 CTL 宏为零(然后进行 orred 以产生控制)。
    --emacro ((912)、CAN_INT_*)//声明为有符号的 CAN_INT 宏应该是无符号的。
    --emacro ((912)、GPIO_*)//声明为有符号的 GPIO 宏应该是无符号的。
    --emacro ((915)、GPIO_*)//声明为有符号的 GPIO 宏应该是无符号的。
    --emacro ((917),GPIO_*)//声明为有符号的 GPIO 宏应该是无符号的。
    --emacro ((917),INT_*)//声明为有符号的 INT 宏应该是无符号的。
    --emacro ((912)、MSG_OBJ_*)//声明为有符号的 MSG_OBJ 宏应该是无符号的。
    --emacro ((915)、MSG_OBJ_*)//声明为有符号的 MSG_OBJ 宏应该是无符号的。
    --emacro ((912)、NVIC_*)//声明为有符号的 NVIC 宏应该是无符号的。
    --emacro ((835),sysctl_*)//在0值宏为正时升高。
    --emacro ((912)、sysctl_*)//声明为有符号的 sysctl 宏应该是无符号的。
    --emacro ((915)、sysctl_*)//声明为有符号的 sysctl 宏应该是无符号的。
    --emacro ((917),sysctl_*)//声明为有符号的 sysctl 宏应该是无符号的。
    esym (960、5.1)// Tiva 使用长名称
    -elib (950)// Tiva 非 ANSI 结构、尤其是单行注释
    -elib (659)//行终止结构/union/enum 定义上没有任何后续操作}。
    -"esym (793、模块中的宏)"//模块中1024个宏的 ANSI/ISO 限制被 Tiva 头文件超出
    -"esym (793、外部标识符中的有效字符)"//ANSI 标识符长度限制为6对于外部标识
    符-e966//间接包含的标头未使用
    -doffof (x、y)=((((size_t))/lint 在0中不起作用/设置
    用于设置数据结构的偏移量。
    
    //新的 lint 错误看起来提供标准响应
    -elib (9026)//函数与宏
    -elib (9022)类似// Unb括 号化宏参数
    -elib (9021)//使用#undef bedbed
    -elib (9024)//在宏
    -elib (9023)中使用####//多重使用#elib (
    9020)/90优先级/#运算符
    使用非标准字符\
    -elib (9057)//小写 L fells u in 后缀
    -elib (9059)// C 注释包含 c++注释
    -elib (9048)//无符号字面量 w /o U 后缀
    --emacro ((9048)、sysctl_*)// sysctl 宏命令具有无符号后缀 w /u。
    --emacro ((9048)、NVIC_CPAC)// sysctl 宏命令具有无符号字面量、不带 U 后缀。
    -e9048// NVIC 宏具有不带 U 后缀的无符号字面量。 返回至 FIX
    -e9044//修改的函数参数
    -e9058//仅在 typedef 中使用的标记(包括匿名标记)
    -e9016//是我们使用指针算术
    -e9017//是我们使用带有增量/减量的指针算术
    
    //启动具有一些类似库的代码。
    +libm (startup.c)
    
    //特定于项目的状态生成的代码
    //+fCT
    -isrc-gen
    +libdir (src-gen)
    +libh (src-gen/fan.h)
    +libm (src-gen/libgen.c)
    +libh (src-pars/src/canerror.h)
    +libh (src/glibgen.c
    
    
    
    
    
    
    
    
    
    )+libmen/src/glibgen.org.org/en.hrm/sr.r.r./libh
    (src/glibm.org/en/sr.hrm.org/esr.r.r.r.r.r.r.r.r.r.rc/c/sr.r.rc/c/sr.r.rc/glibm_spr-m.r.r.org/libh)+libh (spr-m.org/libm.org/libm.org/libm.org/libm.org/libm.org/libm.org/libm.org/esr.r.r.r.r.r.r.r
    
    
    
    
    
    引用
    的-elib (818)//参数可以声明为 const
    -elib (
    
    布尔值)的指针//函数末尾前返回-elib (915)//布尔型和布尔型常数不相同(有符号/无符号)-elib (506)//逻辑中的常量值(&&)
    -elib (944)//逻辑中的右手型常数不相同&始终计算 True &参数
    -elib (774)//如果始终为 true,则&&中右边的布尔
    值-elib (917)//原型强制 int 为 unsigned int (再次为布尔类型)
    -elib (632)//指定为强类型 sc_integer
    -elib (766)//未使用头文件(string.h)
    -elib (9012)//子语句应为复合语句
    //从 Yakindu 2016/03/28
    -elib (605)添加//增加指针能力
    -conb (9007)//
    
    
    对特定项目的非副作用/eli956 非易失性全局变量。 依赖于线程语义
    -e9026//函数(如宏
    
    //状态图表代码生成器特定
    -Strong (、sc_integer)//基本类型,而不是强类型
    -idlen (110)// EEEp!
    -esym (937、cANErrorIface_getTimems)//如果没有参数,则未生成原型
    -esym (746、cANErrorIface_getTimems)//如果
    没有参数-esym (628、cANErrorIface_getTimem),则未生成原型;如果没有参数
    -esym (
    
    
    937、cANErrorIface_getTimem),则未生成原型设计原型/tranIdimum/如果没有生成则未生成原型设计原型如果没有参数
    -esym (746、cANeliIface_initCAN)、则不生成原型//如果没有参数
    -esym (957、cANIface_initCAN)、则不生成原型//如果没有参数
    -esym (Error、cANErrorIface_initCAN)、则不生成原型
    //
    
    没有生成原型/volatile convitem (
    900)/b =/esimine/pregulator (9)/volatile convetrule/est ex/b (example/pregulator)/b = 900(ex/b)/volatile convisty convit/b)/esst (exit_example/t
    -elib (740)//转换使 const/volatile
    -elib (923)//将指针转换为 long (转换为事件 ID)
    -elib (946)//关系或减去指针
    -elib (416)//可能创建一个超出范围的指针
    -elib (638)// sc_intpte_t 的强类型不匹配, 用于指针范围检查
    -elib (639)// size_t 的强类型不匹配,用于指针范围检查
    -elib (737)//标志丢失,用于长整型到无符号长整型,指针范围检查。
    -elib (574)//关系中有符号/无符号混合、指针范围检查。
    -elib (640)// bool 上下文中的预期 bool 类型。
    -strong>bl、sc_boolean)//库中的布尔类型
    //-parent (bool、sc_boolean)
    
    //在此处进行调试,要删除这些
    -e793// ANSI/ISO 将枚举常量限制为127
    
    
    //在此处进行调试, 想要删除这些
    -e843// lint 认为 ms_tick 可能由于某种原因而变得常亮*/
    -esym (759、ms_tick)
    -esym (765、ms_tick)
    -esym (552、ms_tick)
    -e768// Lint 认为任务成员未被引用
    -e697//准值应仅与零布尔值进行比较。 需要了解什么才能使 lint 识别 bool。
    
    //IAR 标头特定
    -ident(@)+rw
    (_gobble)
    -d"@=_gobble"
    
    -d_get_SP ()=0
    // math.h 有重新定义内容
    的不良习惯-esym (14、__IAR_Dcomp)
    -esym (14、__IAR_FDcomp)
    -elib (1916)有一些库函数/省略号。 在 ctype.h
    -esym (762、_LocaleC_Toumper*、_LocaleC_tolower*、_LocaleC_isalph*、_LocaleC_iscntrl*)
    -esym (762、_LocaleC_Islower*、_LocaleC_ispunt*、 _LocaleC_isspace*、_LocaleC_isupper*)
    -esym (9004、_LocaleC_Toupper*、_LocaleC_tolower*、_LocaleC_isalph*、_LocaleC_iscntrl*)
    -esym (9004、_LocaleC_islower*、 _LocaleC_ispunct*、_LocaleC_isspace*、_LocaleC_isupper*)
    -efile (451、stdlib.h)// IAR 具有额外的 bumpf,因此无法识别包括防护
    装置-SEM (isdigit,pure)//无副作用
    -sem (isalpha, pure)//无副作用
    -esym、isupper、is*、ischower*、 isalnum*)
    -esym (14、isalph*、isdigit*、ISBLANK*、iscntrl*、isprint*、 tolCtl*、isspace*)
    
    //添加检查某些函数
    的 Sematics -SEM (SysCtlPeripheralReady、PURE)//无副作用
    
    //暂时未使用
    的-esym (552、RTD2_temperature)
    
    //模块组合
    -esym (769、KD_Request_flag::::KD*)时的选项//并非所有位都显式引用。
    -esym (769、KD_STATUS_FLAG:::KD*)//并非所有位都显式引用。
    
    //RTA TEMP
    -e9141
    -e9117
    -e9146
    -e9126
    -e9132
    -e9130
    -e9075
    -e9078
    -e9105
    -e9067
    
    -e9148
    -e9105
    -e9131 -e9113
    
    -e9133
    -e9147
    -e9080
    -e9106 -e9118
    -e9138 -e9092
    
    -e9118 -e9138 -e9118 -e9138 -e9118 -e9138 -e9118 -e9138 -e9138 -e9138 -e9138 -e9092 -e9138 -e9138 -e9138 -e9138 -e9092 -e9138 -e9138 -e9138 -e9138 -e9092 -e9138 -e9138 -e9138 -e9138 -e9138 -e9092 -e9138 -e9138 -e
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    

    这确实会关闭更多。 有很多专门针对库 (我正在查看 TI)和不太干净的代码生成器的关闭错误消息。 最后是一组最近添加的 lint 消息,需要对这些消息进行彻底的排序以确定其使用情况。 不确定它们是否实际上会低于 W4。

    此外、还有一个编译器自适应文件、其大小、编译器特定定义等... 一个示例。 由于 lint 会半自动生成此文件,因此更容易将其分开。

    Robert

    自1986年左右开始使用 PC-Lint 用户。

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

    ***喜欢! ***(远远超过我们的“PC-Lint User Guide!”)    非常感谢、Robert -非常感谢...

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

    BTW、任何试图在非线性工作项目中尝试此操作的人都应谨慎一些。 拧紧螺钉。 但是,如果您不断地不起作用,则此级别既可行又有益。

    Robert
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    (两个)购买"狗和猫"后、我们(意识到)"不断地"-"不断地"-"新的"休息地...