嵌入式C程序的生命周期内运行一次代码


8

如何使代码段在程序的生命周期内仅运行一次?它可以关闭和打开很多次。再次运行代码段的唯一选择必须是再次刷新电路板。

该代码是“校准部分”,我不想再次运行。如果我使用EEPROM或闪存,我们将标志设置为true或False。因此,当我们第一次读取该内存位置时,该内存区域中的随机值是多少?

在嵌入式C中实现此功能的最佳方法是什么?


5
使用一个标志并将此标志保存到eeprom(或Flash)。在每个瞬间都从eeprom中读取标志。瞬间的第一次,标志的值将强制函数执行。之后,您可以更改标志的值并将其再次保存到eeprom。所有其他时间,标志值将不会强制执行功能。
hoo2 '16

2
不清楚你在问什么。
old_timer '16

2
阻止代码再次运行的背后动机是什么?不能对代码进行反向工程很重要,在这种情况下,设置一个标志来绕过它可能不够安全吗?第二次运行代码会损坏硬件吗?是UX的事情吗,就像第一次使用系统时显示教程消息一样,在这种情况下,可能需要“工厂重置”功能(如果存在)来触发代码再次运行?
米歇尔·约翰逊

5
通常,最好是在第一次出现混乱时允许进行重新校准,或者需要针对不同的设置重新校准系统或补偿硬件老化等情况。例如,我倾向于将校准混乱第一次,因为我不知道我该怎么做。
米歇尔·约翰逊

3
您如何设置代码,以便有一种命令它运行的方式(即通过串行端口发送一些内容)。这样,就不必担心非易失性存储器,并且可以在生产过程中以受控方式触发校准。
alex.forencich 2016年

Answers:


18

您的微控制器可能具有一些EEPROM,OTP存储器,用户熔丝位,您可以在其中设置标志。

没有“嵌入式C语言中的最佳方法”,在每个微控制器中写入非易失性存储器都是不同的。

编辑:

对器件编程时,闪存内容将被擦除。编程后,所有未写入的字节均包含0xFF。请查阅数据表,以找到可以从正在运行的固件中安全编程的区域。

EEPROM

尽管不能保证数据表中的数据,但到目前为止,我所见过的所有EEPROM出厂时都包含0xFF:s(预先编程有唯一MAC地址的EEPROM除外,但已明确记录)。一些编程设备/软件也能够擦除或编程EEPROM内容。有些可以永久或可逆地受写保护。

一次性密码

一次性可编程存储器始终包含定义明确的初始值,该初始值记录在数据表中。

最好在写入的数据中包含一个良好的校验和,例如CRC32,以防止由于缺陷部件,传输错误,宇宙射线等引起的数据损坏。


如果我使用EEPROM或Flash,我们将Flag设置为true或False,所以当我们第一次读取该内存位置时,该内存区域中的随机值是多少。
ganeshredcobra,2016年

2
在制造过程中,将EEPROM复位(如果可能,请使用编程器,或者通过制作一个愚蠢的小抽头程序,对其进行闪烁,将其正常上电几秒钟,然后加载到生产程序中)。
尼克·T

13

你说:

运行该代码的唯一选项必须再次使开发板闪烁。

其他人则说使用EEPROM来存储一个标志,以指示何时运行run_once()函数。但是,这样做的缺点是,如果您重新刷新微控制器,则EEPROM中的ran_it_once标志已被设置,并且run_once()函数将不会执行。如果您的微控制器已嵌入EEPROM,则在重新刷新微控制器时,如果程序员支持,可以清除ran_it_once标志。

更好的方法是在EEPROM和代码中都包含版本号。当代码从加电运行时,应从EEPROM读取版本号,并将其与代码中存储的版本号进行比较。如果它们不匹配,则调用run_once()函数,并且run_once()代码的最后动作是将固件版本号写入EEPROM。每次您修改固件的源代码时,都必须增加其内嵌的版本号。


1
如果所有用户所做的只是重新刷新微控制器,并且需要再次运行它(在这种情况下),这实际上将具有与布尔标志相同的问题。如果固件已更新且需要重新运行,则肯定可以解决该问题。
Taegost,2016年

8

选择可以写入/擦除自己的程序存储器的微控制器。执行完相关代码后,使代码的最后部分替换为第一条指令,并跳过该指令。(可选)您也可以擦除其余部分(也许用nop代替),以使它再次执行的可能性绝对为零。

此消息将在5..4 ...中自毁...


1
尽管这个答案可能很聪明,但我认为这是不必要的复杂。也许它可以使用一条注释来指定仅在代码存储器之外的持久性存储器不可用时才应使用它?
skrrgwasme 2016年

即使有其他解决方案也是可行的,我认为这比其他解决方案更容易理解。
约书亚

1
即使其他解决方案是可行的,我认为在源代码级别也很难理解。
CVn

大多数PIC只有35条指令...可能出什么问题?;)
rdtsc

5

当您使用此代码进行校准时,我的建议是创建一个爆炸过程,该过程将在第一阶段运行校准代码,甚至不将其放置在电路板的最终生产版本中。这与apalopohapa的答案类似,不同之处在于您将有两个单独的程序加载:具有一个blast程序,该程序会刷新第一个程序加载,运行所有校准并从中加载数据。然后获取该数据并将其合并到第二个程序加载的数据中。

这种方法的一个好处是,您可以绝对减少所需的存储空间-您不需要仅存储一次代码,只需存储它生成的数据即可。通过具有加载两个单独程序的爆炸过程,您还可以使自己与初始化代码中的错误隔离一些,否则这些错误可能会持续存在。如果您想重新运行校准代码,则还具有一些额外的灵活性:您无需重新编写代码以清除表示您的代码已经运行(可能已经意外清除)的任何位,而只需重新运行您的校准代码即可。爆炸过程。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.