41

在开发嵌入式系统时,您认为应该遵循哪些“最差实践”?

我对不该做什么的一些想法是:

  • 避免抽象硬件层,而是在整个代码中分散硬件访问。
  • 没有任何类型的仿真环境,只有实际的硬件可以执行/可爱。
  • 避免单元测试,可能是由于以上两点
  • 不以分层结构开发系统,因此较高层可能依赖于已调试和工作的较低层功能
  • 选择硬件而不考虑将使用它的软件和工具
  • 使用为易于调试而设计的硬件,例如无测试点、无调试 LED、无 JTAG 等。

    我敢肯定有很多关于不该做什么的好主意,让我们听听!

  • 4

    21 回答 21

    58
    • 未初始化的异常向量(你知道,对于那些“永远不会到达”的异常向量)
    • 跟我说:全局变量。尤其是在没有保护的情况下在 ISR 和任务(或前台循环)之间共享的那些。
    • 没有在必要时使用“volatile”。
    • 将 DisableInterrupts() 和 EnableInterrupts() 配对的例程。了解?不是RestoreInterrupts(),而是ENABLE。是的,嵌套。
    • 测试时无需切换 GPIO。
    • 船上没有测试点。
    • 没有用于查看运行时系统状态的 LED 或串行端口。
    • 无法测量 CPU 的繁忙/空闲程度。
    • 除了最可怕的情况外,对所有情况都使用内联汇编。写一个快速标注。
    • 使用 for (i = 0; i < 1000; i++) { } 来“延迟一点”。是的,那不会以一百种不同的方式咬你....
    • 尽可能不使用 const 来保留 RAM 并减少启动时间(不复制/初始化变量)

    我还有很多,但这应该让我们开始......

    于 2008-10-31T00:59:17.223 回答
    30

    在我伤害自己之前有人阻止我。

    顺便说一句,我意识到并非所有这些都严格特定于嵌入式开发,但我相信它们中的每一个在嵌入式世界中至少与现实世界一样重要。

    • 在制定时间表时,请继续并假设一切都会在第一次工作。

    • 无需示波器和/或逻辑分析仪即可启动电路板。特别是。范围,那永远没用。

    • 设计时不要考虑电源。热量、效率、纹波对 ADC 读数和系统行为的影响、EMF 辐射、启动时间等问题并不重要。

    • 无论您做什么,都不要使用复位控制器(5 美分 IC 类型),只需使用 RC 电路(希望其中耦合有大量高频交流噪声)

    • 拥抱大爆炸!!!不要逐步开发小块并经常集成,傻瓜!!!只需与同事一起编写几个月的代码,然后在大型贸易展演示的前一天晚上将它们全部放在一起!

    • 不要使用调试/跟踪语句检测代码。能见度很差。

    • 在你的 ISR 中做很多事情。冒泡排序、数据库查询等......嘿,可能没有人会打扰你,你有发言权,好好享受吧,伙计!

    • 忽略设计中的电路板布局。让自动布线器在那些匹配的阻抗走线和大电流、高频电源上发挥作用。嘿,你还有更重要的事情要操心,伙伴!!!

    • 使用全新的、测试版的、未发布的、早期采用者的芯片,特别是如果它对安全至关重要(航空、医疗)或大批量(召回 100 万个单元很有趣)。当 4 核 300 MHz 7 级流水线芯片上有新的硅采样时,为什么还要去拉斯维加斯?

    于 2008-10-31T19:53:07.900 回答
    25

    好的第 2 轮....还有一些:

    • 不要使用看门狗定时器(尤其是内置的!)

    • 当缩放整数数学就足够时使用浮点类型和例程

    • 在没有保证时使用 RTOS

    • 真正有意义时不要使用 RTOS

    • 永远不要查看生成的汇编代码来了解幕后发生的事情

    • 编写固件,使其无法在现场更新

    • 不要记录你所做的任何假设

    • 如果您在测试/调试时看到奇怪的东西,请忽略它,直到它再次发生;这可能不是什么重要的事情,比如掉电、错过的中断、堆栈损坏的迹象或其他一些短暂和间歇性的问题

    • 在调整堆栈大小时,最好的理念是“从小处着手并不断增加,直到程序停止崩溃,然后我们可能就可以了”

    • 不要利用像 Micrium 的 uC/Probe 这样的运行时分析工具(我相信还有其他工具)

    • 在运行主应用程序之前不要包括硬件的开机自检 - 嘿,启动代码正在运行,什么可能不工作?

    • 绝对不要在您不会实施的 POST(上图)中包含 RAM 测试

    • 如果目标处理器有一个 MMU,尽管如此,不要使用那个可怕的 MMU!尤其是不要让它保护您免受对代码空间的写入、从数据空间的执行等...

    • 如果您一直在测试、调试和集成一组特定的编译器选项(例如无/低优化),请务必在最终版本构建之前打开全面优化!!!!但只有在您不打算测试时才打开优化。我的意思是,您已经测试了几个月 - 会出什么问题?!??!

    于 2008-10-31T19:36:16.530 回答
    14

    初始化后的动态内存分配。系统启动并运行后,内存池应保持静态。

    于 2008-10-30T19:34:32.853 回答
    12
    • 跳过伐木设施。嵌入式系统很难调试,您需要大量的日志记录。
    • 无法允许日志记录级别。许多系统中的一个会表现出奇怪的行为,您需要将该系统的日志记录的调试级别设置为更详细的级别。
    • 不允许某种输出端口允许登录到例如控制台。
    • 没有能力“单步执行”代码。
    • 无法分析代码,因此您可以查看哪些位需要优化,例如在汇编程序中。
    • 不开发某种“健全性测试”,因此您可以在加载后和发货前快速检查设备是否正常工作。
    • 基于一些“本土”操作系统的设计
    于 2008-10-30T19:53:42.427 回答
    8

    尝试在不访问您正在开发的实际硬件的情况下进行开发。

    于 2008-10-30T19:40:08.617 回答
    4

    在您的解决方案中使用多个处理器并确保它们具有相反的字节序。然后确保它们之间的接口是其中一个可以直接访问另一个内存。

    是的,我之前已经对这种架构进行了编程。

    于 2008-11-22T21:37:28.580 回答
    3

    假设字节序将永远相同。

    (将其扩展到寄存器的大小以及有关硬件规格的任何内容)

    (评论中的案例解释)。

    于 2008-10-30T19:44:37.140 回答
    3

    如果没有更多地定义“嵌入式编程”,那么就不可能说出什么是好的或坏的做法。

    例如,在 CE 或 XPe 平台上,您可能使用的许多技术在 CE 或 XPe 平台上完全不适合使用狡猾的非标准方言“C”对 8 位微控制器进行编程。

    在许多情况下,抽象是一种(过度)昂贵的奢侈品,因此“避免它”可能是好事而不是坏事。

    于 2008-10-30T19:55:10.940 回答
    3

    这里有几个:

    • 不要设计一个您的开发人员、经理和客户都能理解的易于解释的架构。

    • 嵌入式系统几乎总是对成本敏感的平台。不要计划硬件变得更慢(更便宜),也不要计划关键数据路径中的新功能。

    • 大多数嵌入式系统是“无头的”(没有键盘或鼠标或任何其他 HID)。不要在你的日程安排中计划编写调试工具。并且不要资源至少一名开发人员来维护它们。

    • 请务必低估获得提示所需的时间。这就是让核心 CPU 达到可以与您和您与它对话的程度所需的时间。

    • 始终假设硬件子系统可以开箱即用,例如内存、时钟和电源。

    于 2008-10-30T21:13:10.347 回答
    2

    不:

    • 留下没有指向任何地方的未使用的中断向量(毕竟,它们永远不会被触发,所以这有什么危害......),而不是让它们跳转到一个默认的未使用的中断处理程序,它会做一些有用的事情。

    • 不熟悉您正在使用的处理器的细节,特别是如果您正在编写任何低级驱动程序。

    • 选择闪存量最少的处理器系列版本,理由是您始终可以“稍后升级”,除非成本无法避免。

    于 2009-01-30T19:27:35.310 回答
    1
    • 假设微机按照数据表所说的做了/没有按照数据表的承诺做。
    • 将看门狗服务程序置于高优先级定时中断中,这样无论发生什么其他事情,看门狗都不会失败。
    • 使用在 Internet 上看到的任何代码,尤其是来自 Arduino/Pic 站点的代码。
    • 假设从一个组件到另一个组件都有任何标准定义,例如 Tx/Rx(我们这里有一个 Sony 单元,上面有 2 个通信端口,一个 Tx/Rx 相对于另一个反转)。
    • 认为客户会费心检查/测试任何东西,直到他们售出至少 100 个单位
    • 假设该领域的任何其他参与者实际上都知道他们在做什么(我们有一份标准文档,上面写着“我们认为这是我们的旧协议所做的,但没有人真正记得”)
    于 2012-08-10T08:51:59.223 回答
    0

    一些额外的注意事项:

    • 将硬件相关部件的开发和测试留到最后才发现硬件不能正常工作、不能按预期工作或有一些软件无法修复的缺陷(例如,不需要的非线性失真中断所有进一步的信号处理)。
    • 简单地设计模拟-数字电路,而不考虑数字部分中发生的事情如何影响模拟部分(例如,串扰,导致从 ADC 读取错误数据)。
    于 2012-03-07T03:47:40.743 回答
    0
    • 将您的固件模块编写为完全通用的,接受每个可能的参数作为变量,即使您上面的层总是使用相同的参数调用。

    • 即使系统中有 DMA 引擎(为什么要打扰硬件),在代码中的任何地方都使用memcpy 。

    • 设计一个复杂的分层固件架构,然后让模块直接访问更高级别模块拥有的全局变量。

    • 选择一个 RTOS,但不要费心去测试它的实际性能(我们不能相信供应商给出的数字吗?)

    于 2008-11-04T13:45:07.220 回答
    0

    嵌入式系统中的一件重要事情是独立于您的应用程序评估技术,包括软件(编译器、库、操作系统)和硬件(芯片组)。避免使用这些测试台是危险的。一个人应该要么购买评估套件,要么建立他/她自己的测试台。

    于 2008-10-30T19:43:57.623 回答
    0

    打印。

    如果您的跟踪工具需要上下文切换和/或中断,那么您将永远无法调试任何与时间相关的内容。

    写入内存缓冲区(memcpy'ing enums 而不是 s(n)printf 的奖励点),并在其他时间读取它。

    于 2008-11-27T10:28:26.413 回答
    0

    这可能更像是一个硬件解决方案——但对于从头开始的新项目,低估资源需求是一个大问题,尤其是在使用没有简单方法扩展代码/存储大小的小型独立微控制器时。

    于 2008-12-08T22:58:10.920 回答
    0

    从软件的角度来看,没有花时间学习硬件。

    于 2012-03-07T03:17:08.293 回答
    0

    这不仅适用于嵌入式系统,而且将所有这些时间都花在寻找错误(调试)上,而不是通过诸如代码审查之类的酷东西来避免错误,这绝对是一种最常见的最坏做法。

    另一种方法是让一个巨大的处理器完成所有工作,而不是将问题分解为小问题,例如使用更多的小处理器。还记得可可吗?

    于 2009-05-18T12:08:02.040 回答
    0

    这在很大程度上取决于您正在为其编程的控制器类型。有时成本是最重要的事情,你试图用尽可能少的钱过日子。那是我通常乘坐的船。以下是我使用过的一些最糟糕的做法:

    • 不要专注于改进您的流程。下次再努力一点。稍后当我们不忙于匆忙发布新产品同时支持该领域的所有这些错误时,我们可以担心这些东西。
    • 避免设计一种工程工具来让您的生活更轻松,如果您确实构建了一个,请不要让它向设备发送无效输入
    • 不要质疑优化。这是魔法。编译器知道它在做什么。永远不会有编译器错误,尤其是对于您的客户 7 位 PIC 子微控制器。太多人会注意到吧?
    • 像运行物理引擎一样进行除法和乘法运算,不用担心溢出、精度损失、四舍五入到零。
    • 如果您的时间安排似乎有效,请不要检查您是否偏离了 1 分或是否随时间漂移。您在高中时演奏打击乐,您会注意到 7200000 时钟周期和 7200001 之间的差异。
    • 依靠对您的固件一无所知的小组进行的系统级测试
    • 在尽可能多的不同设备上工作。有几个调试器会话与不同的开发环境一起使用。开发一种产品,同时对另一种产品进行基准测试,并尝试在第三个产品上重现现场问题。
    • 匆忙发布新版本的代码,因为您只更改了一件事,而且您可能没有破坏它。生产线下线了,我们不能浪费任何时间!
    • 如果优化已关闭,请不要进行任何类型的测试来警告您。应该不会对吧?您刚刚安装的新 IDE 版本不可能破坏该设置。
    • 把代码写得足够好才能工作。花 75% 的时间把它弄到一半。
    • 不要对功能的设计有任何投入。允许任何功能收集几天的状态信息。无法为测试注入此状态信息。这将使您在尝试重现人们在现场看到的错误时有空闲时间,生产人员也会很感激他们的休息时间
    于 2009-09-07T16:19:19.747 回答
    0

    我在嵌入式系统工作超过 8 年并教授嵌入式系统的经验中的一些最糟糕的做法:

    1. 数据类型的选择——嵌入式系统资源稀缺。如果数据的范围是 5-200,则没有必要将其声明为 int。所需的只有 8 位,而使用的是 32 位。浪费24位。

    错误的数据类型也可能是灾难性的。

    1. 在 ISR 中做大量工作- ISR 应该尽可能短。我见过一些人在 ISR 中实现了整个逻辑,这非常非常糟糕。太糟糕了,它应该被列为犯罪。改用标志

    2. 使用整数作为标志- 这更像是第 1 点的扩展。您只需要一位。不要为此使用 16 位或 32 位。

    3. 但我所见过的最糟糕的是一遍又一遍地思考算法以获得最好和最完美的方法。停止!!牢记最佳实践,让系统首先运行。

    还有很多。你可以在这里阅读其中的一些

    于 2019-11-08T08:47:14.427 回答