Arduino 引导加载程序详细信息

电器工程 Arduino avr 引导加载程序
2022-01-17 08:01:02

有人可以解释一下Arduino 引导程序是如何工作的吗?我不是在这里寻找高水平的答案,我已经阅读了代码并且我明白了它的要点。我还通读了一篇文章(我什至是它的响应者之一)。

在 Arduino IDE 和引导加载程序代码之间发生了一堆协议交互,最终导致许多内联汇编指令对闪存进行自编程,程序通过串行接口传输。

我不清楚的是第 270 行:

void (*app_start)(void) = 0x0000; 

...我认为这是函数指针的声明和初始化为 NULL。在引导加载程序打算委托执行用户加载代码的地方,随后会调用 app_start。

当然,app_start在某些时候需要以某种方式获得一个非 NULL 值才能将它们组合在一起。我在引导加载程序代码中没有看到......它是否被引导加载程序加载的程序神奇地链接了?我认为引导加载程序的 main 是芯片复位后进入软件的入口点。

包含在大约 70 条组装线中的一定是秘密解码器环,它告诉主程序 app_start 到底在哪里?或者可能是 Arduino IDE 利用了一些隐含的知识?我所知道的是,如果有人不将 app_start 更改为指向 0 以外的某个位置,则引导加载程序代码将永远自转……那么诀窍是什么?

单独说明一下,引导加载程序代码是否有可能依赖中断,或者这是一个禁忌?

编辑

我有兴趣尝试将引导加载程序移植到没有用于引导加载程序代码的单独内存空间的 Tiny AVR(特别是 ATtiny44A)。对我来说很明显引导加载程序代码依赖于某些保险丝设置和芯片支持,我想我真正感兴趣的是如何将引导加载程序移植到没有这些保险丝和硬件的芯片上支持(但仍具有自编程能力)?

我在想我可以使用 AVR307 的实现将 USI 用作半双工 UART(使用 Timer0 中断和引脚更改中断)。任何人都可以提供有关如何为没有硬件支持引导加载程序的芯片编写/移植引导加载程序代码的指导吗?

我想我会将引导加载程序代码放在地址 main 的正常位置(例如 0x029e 或编译器放置 main 的任何位置)。然后我会这样做,以便引导加载程序代码中的“地址”添加一个偏移量,使我刚好超过 main 的末尾,并将“app_start”设置为该地址。我是否正确地考虑了这一点,或者我完全错过了什么?谢谢!

编辑 2

FWIW,我发现了如何将 Arduino 草图加载到 ATTiny85 上的记录过程,这是我最初提出这个问题的地方......我认为非常整洁

1个回答
void (*app_start)(void) = 0x0000; 

这不是 NULL 指针。这确实是引导加载程序跳转到的应用程序代码的起始地址。链接器安排您的应用程序代码从地址 0 开始。请参见 ATMEGA168 数据表中的表 26-6。

引导加载程序代码在闪存中启动得更高。确切的位置取决于引导加载程序熔断器。