这里有各种各样的答案...主要以各种方式解决该问题。
25年来,我一直使用多种语言(主要是C语言)编写嵌入式低级软件和固件(但后来转移到了Ada,Occam2,PL / M和各种汇编程序中)。
经过长时间的思考和反复试验后,我决定使用一种方法,该方法可以相当快速地获取结果,并且很容易创建测试包装和工具(它们可以增加价值!)
该方法是这样的:
为要使用的每个主要外围设备编写驱动程序或硬件抽象代码单元。还要编写一个以初始化处理器并进行所有设置(这使环境变得友好)。通常在小型嵌入式处理器上(以您的AVR为例),可能会有10到20个这样的单元,全部很小。这些可能是用于初始化,将A / D转换为未缩放内存缓冲区,按位输出,按钮输入(仅采样后不进行反跳),脉宽调制驱动器,UART /简单串行驱动器,使用中断和小型I / O缓冲区的单元。可能还有更多-例如用于EEPROM,EPROM或其他I2C / SPI设备的I2C或SPI驱动程序。
然后,对于每个硬件抽象(HAL)/驱动程序单元,我编写一个测试程序。这依赖于串行端口(UART)和处理器初始化-因此第一个测试程序仅使用这两个单元,并且仅执行一些基本的输入和输出。这可以让我测试是否可以启动处理器以及是否具有基本的调试支持串行I / O。一旦可行(并且只有这样),我才可以开发其他HAL测试程序,并在已知的优秀UART和INIT单元上构建这些程序。因此,我可能有一些测试程序,用于读取按位输入并在串行调试终端上以一种不错的形式(十六进制,十进制等)显示这些输入。然后,我可以进入更大而更复杂的事物,例如EEPROM或EPROM测试程序-我使大多数菜单受驱动,因此我可以选择要运行的测试,运行它并查看结果。我不能脚本,但通常我不
一旦我的所有HAL运行完毕,我便找到一种获取常规计时器刻度的方法。该速率通常在4到20毫秒之间。这必须是常规的,在中断中生成。计数器的翻转/溢出通常是可以做到的。然后,中断处理程序增加一个字节大小的“信号量”。此时,如果需要,您还可以摆弄电源管理。信号量的想法是,如果其值> 0,则需要运行“主循环”。
EXECUTIVE运行主循环。它几乎只是等待该信号量变为非0(我将这个细节抽象掉了)。此时,您可以使用计数器来计算这些报价(因为您知道报价速度),因此您可以设置标志来显示当前执行价是否间隔1秒,1分钟以及其他常见间隔可能要使用。一旦执行人员知道信号量> 0,它就会通过每个“应用程序”进程“更新”功能运行一次。
应用程序进程有效地并排放置,并通过“更新”标记定期运行。这只是执行人员调用的功能。这实际上是穷人的多任务处理,它具有非常简单的本地RTOS,该RTOS依赖于所有进入,执行少量工作和退出的应用程序。应用程序需要维护自己的状态变量,并且不能进行长时间运行的计算,因为没有抢先式操作系统可以强制公平。显然,应用程序的运行时间(总计)应该小于主时钟周期。
上面的方法很容易扩展,因此您可以添加诸如异步运行的通信堆栈之类的东西,然后可以将comms消息传递到应用程序(向每个函数添加一个新函数,即“ rx_message_handler”,然后编写一个消息调度程序,派遣到哪个应用程序)。
这种方法几乎适用于您要命名的任何通信系统-它可以(并且已经完成)用于许多专有系统,开放标准通信系统,甚至可以用于TCP / IP堆栈。
它还具有在具有明确定义的接口的模块化部件中构建的优势。您可以随时拉入和拉出零件,替换为其他零件。在此过程中的每个点上,您都可以添加测试工具或处理程序,这些处理程序或处理程序基于已知的良好底层组件(以下内容)。我发现,大约30%到50%的设计可以通过添加通常很容易添加的特别编写的单元测试而受益。
我已将所有步骤都更进一步了(这个想法我已经从做过此事的其他人那里汲取了灵感),并用等效的PC代替了HAL层。因此,例如,您可以在PC上使用C / C ++和winforms或类似软件,并通过仔细编写代码可以模拟每个接口(例如EEPROM =读入PC内存的磁盘文件),然后在PC上运行整个嵌入式应用程序。使用友好的调试环境的能力可以节省大量的时间和精力。通常只有真正大型的项目才能证明这种努力的合理性。
上面的描述并不是我在嵌入式平台上做事的方式所独有的-我遇到了许多从事类似工作的商业组织。它的完成方式通常在实现上有很大的不同,但是原理通常是相同的。
我希望以上内容能给您带来些帮助...这种方法适用于运行在几kB的小型嵌入式系统中,并具有积极的电池管理能力,甚至可以提供100K或更多永久供电的电源线。如果您在Windows CE等大型操作系统上运行“嵌入式”,则上述所有内容都不重要。但这不是真正的嵌入式编程。