了解 Arduino 引导加载程序的闪存组成

Understanding flash composition of Arduino bootloader

我正在尝试了解 Arduino 引导加载程序。我在这里找到了一些介绍:Arduino Bootloader,但我需要更多详细信息,因此我正在寻求帮助。

在我的研究过程中,我找到了一个起点:好吧,Arduino(atmega 系列)有一个特定的闪存块专用于引导加载程序。一旦 mcu 有了引导加载程序,它就可以通过串口下载新程序并将其存储在闪存中,地址为 0x00。

让我们为这道题分配atmega328p。


#1 - 如果您查看数据表第 343 页,您会看到一个 table,显示有关引导加载程序大小的一些信息:

通过这个table我明白了:如果我将BOOTSZ1/0设置为0/0,我可以有一个2K的bootloader,它将存储在闪存堆栈中:0x3800 ~ 0x3FFF。


#2 - 如果您打开 Arduino 生成的 ATMEGA328_BOOTLOADER 的 hex 文件,您将看到存储在以下位置的引导加载程序:

:10**7800**000C94343C0C94513C0C94513C0C94513CE1 

:10**7FF0**00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF91

如果您考虑 7FF0 - 7800,您将得到 7F0(2K 字节的程序)


#3 - 如果您打开 makefile (C:\Program Files (x86)\Arduino\hardware\arduino\avr\bootloaders\atmega),您将看到 atmega328 的这个参数:

atmega328: LDSECTION  = --section-start=.text=0x7800

其中 0x7800 与来自引导加载程序的 hexa 文件匹配。


问题:

1- 为什么数据表告诉我引导加载程序有一个特殊的位置,而 Arduino 的 makefile 强制它存储在不同的地方?

2- hexa 文件的行是什么意思?

:10E000000D9489F10D94B2F10D94B2F10D94B2F129

:10    : (?) 
E000   : Address
00     : (?)
0D9489F10D94B2F10D94B2F10D94B2F1   : data (?)
29     : CRC (?)

首先,我不确定我们有相同的 atmel 数据表;你的 table 我的是 27-7,但无论如何数据是一样的。

免责声明:我对此不是 100% 确定,但我非常有信心。

我认为这里的"problem"就是那个"words"。阅读他们写的核心概述

Most AVR instructions have a single 16-bit word format. Every program memory address contains a 16- or 32-bit instruction

这意味着指令是 2 字节宽。所以你的地址0x3800对应的是从内存开始的0x7000字节,而bootloader的结尾0x3FFF对应的是字节0x7FFE和0x7FFF。

这可以从内存大小上得到证实:0x7FFF对应32k,也就是可用的flash。由于引导加载程序位于内存的末尾(如 DS 中的图片所示),这意味着 0x3FFF 应该是最后一个内存单元。

编辑:

我回答的时候没有看问题的第二部分。该格式就是所谓的 Intel Binary 格式。有关详细信息,请参阅 Wikipedia。这是一个简短的总结。

您正确识别了字段划分:

:      : Start code
10     : Number of data bytes (in this case: 16)
E000   : Starting address of the data bytes
00     : Record type (in this case: data)
0D9489F10D94B2F10D94B2F10D94B2F1 : data payload (in this case: 16 bytes)
29     : CRC

记录类型可以是

  • 00: 数据
  • 01: 文件结束
  • 02:扩展段地址
  • 03:起始段地址
  • 04:扩展线性地址
  • 05:起始线性地址

CRC是对所有字节求和(从长度1开始,所以最开始),然后得到LSB,最后进行2补码。在这种情况下,总和为 2519,即十六进制的 0x9D7。低位字节D7对应215,其2的补码可以计算为256-x,所以41,也就是16进制的0x29。