Boot 手把手教你写BootLoader_bootloader怎么写,面试学习

95 阅读12分钟

img img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

也就是说part ID是用来区分S12X系列芯片的的唯一ID,因为每个芯片内存不同所有我们要找到自己用的芯片的part ID

 

代码里定义成宏定义

 

 

还有一个要关注的参数如下图所示 ROM 空间划分了 2个块, 分别是 B1S,B0每个128K加起来256K这也就是芯片命名xet256的意义。 这个值可以从 PARTID 对应的寄存器 PARTIDH and PARTIDL (addresses 0x001A and 0x001B)读出来, 这个在P-Flash 擦除和编程的时候要用到。

然后我们去看256K芯片内存细分

 

0x7E_0000-0x7F_FFFF的128K对应P-Flask的B0;

0x78_0000-0x79_FFFF的128K对应P-Flash的B1;

接下来我们要关注Flash的配置命令寄存器它位于地址的最后

const unsigned char flash_array[] @0xFF08 = {0xFF,0xFF,0xFF,0xFF,0xCC,0xFF,0xFF,0xFE}; 对于xet256芯片我们这样来配置,依次看下几个寄存器代表的含义;

0xFF08-0xFF0B - reserved
0xFF0C - P-Flash Protection byte = 0xCC (Bootloader at 0xF000-0xFFFF is protected)   

0xCC对应寄存器值为

所以保护类型为高保护

而保护区域为

 

其他寄存器就按照默认配置

0xFF0D - EEE Protection byte = 0xFF (default state, protection is disabled)

0xFF0E - Flash Nonvolatile byte = 0xFF (default state, watchdog is disabled)
0xFF0F - Flash Security byte = 0xFE (default unsecured state)

关于P-Flash操作的命令可以在这里查到

关于D-Flash操作命令可以在这里查到

 

先明确一个概念在编译环境中我们操作的都是逻辑地址而真实芯片上是全局地址要访问真实的全局地址我们就要把逻辑地址转换成全局地址,s12x系列为16位芯片所以他的访问范围只有0x0000-0xFFFF的64K空间,那么如何访问更大的内存地址呢?比如我们现在用的256K空间甚至更大呢?对!没错给它加更多位 而这个芯片加位的方式是通过三个分页寄存器EPAGE,RPAGE,PPAGE来是实现的,也就是说分页寄存器+原有16位寻址的方式组成更多位来访问更大空间。好了把datasheet翻到206页我们来看图

 

用EEPROM 来举例说明。 先划分 0x0800 - 0x0bff 这 1K 的空间来作为活动分页页窗,然后在 PRM 文件中把全局 EEPROM 内存空间 256K 的地址划分成 256 页, 比如: EEPROM_00= READ_ONLY DATA_FAR IBCC_FAR 0x000800 TO 0x000BFF; 第一页对应的全局地址就是0x10_0000 - 0x10_BFF, 此时 EPAGE = 0X00。

 

按所含的信息的不同.prm 文件有六个组成部分构成, 这里仅讨论和内存空间映射关系紧密的三个部分,其他的不做讨论

 

SEGMENTS … END

定义和划分芯片所有可用的内存资源, 包括程序空间和数据空间。 一般我们将程序空间定义成ROM, 把数据空间定义成 RAM, 但这些名字都不是系统保留的关键词, 可以由用户随意修改.用户也可以把内存空间按地址和属性随意分割成大小不同的块,每块可以自由命名。 例如同样RAM, 可以使用不同的属性,使其有复位后变量清零和不清零之分。关于内存划分的具体方法在后面详解。

PLACEMENT … END

将指派源程序中所定义的各种段如数据段DATA_SEG、CONST_SEG和代码段CODE_SEG 被具体放置到哪一个内存块中。它是将源程序中的定义描述和实际物理内存挂钩的桥梁。

STACKSIZE

定义系统堆栈长度, 其后给出的长度字节数可以根据实际应用需要进行修改.堆栈的实际定位取决于 RAM 内存的划分和使用情况。默认的情况下,堆栈放在 RAM 区域的起始部分。当然堆栈的定义不只有这种方式, 还可以使用 STACKTOP 关键字。

由 SEGMENTS 开始到 END 为止, 中间可以添加任意多行内存划分的定义, 每一行用分号结尾。 定义行的语法型式为:

[块名] = [属性 1] [属性 2] , …  [属性 n] [起始地址] TO [结束地址];

其中“块名” 的定义和 C 语言变量定义相同, 是以英文字母开头的一个字符串, 用户可以自己任意定义块名。“属性” 用户是不能自己定义的, 因为属性名指定了上面所说的“块名” 所对应的不同的

内存类型和访问方式, 而不同物理内存的类型和访问方式是一定的。对于“属性 1” , Codewarrior 5.0 中可以有三种不同的类型, 对于只读的 Flash-ROM 区属性一定是 READ_ONLY,对于可读写的 RAM 区属性可以是 READ_WRITE,也可以是 NO_INIT。它们两者的关键区别是 ANSI-C 的初始化代码会把定位在 READ_WRITE 块中的所有全局和静态变量自动清零, 而 NO_INIT 块中的变量将不会被自动清零。 当然只是复位时不清零,掉电时还是清零的后面的属性可能是DATA_FAR”、“DATA_NEAR”、“IBCC_FAR”、“IBCC_NEAR”四种类型。 其中,“DATA_FAR”和“DATA_NEAR” 相对应,当内存区域包含变量或者是常量时(通常是 RAM、 Flash 和EEPROM)必须指明上面两种属性中的一种, 由于涉及到内存的分页, 可以这样理解:“DATA_FAR” 属性指定的内存块为可以保存数据的非固定页, 而“DATA_NEAR” 属性指定的内存块为可以保存数据的固定页; 同理“IBCC_FAR” 和“IBCC_NEAR” 相对应, 当内存区域包含代码时(Flash 和 EEPROM) 必须指明上面两种属性中的一种, ”IBCC_FAR” 属性指定的内存块为可以保存代码的非固定页, 而“IBCC_NEAR” 属性指定的内存块为可以保存代码的固定页。

举个例子

例 1 RAM = READ_WRITE DATA_NEAR 0x2000 TO 0x3FFF;

上面这句话的意思是: 分配 0x2000-0x3FFF 的区域的块名为“RAM” (当然可以定义别的名称) 这一区域的物理内存的性质为 RAM, 属性应该为“READ_WRITE”并且这一区域中的两页都为固定页,为“DATA_NEAR”

好了终于把内存问题交代清楚了最后我们来划分内存,在CW环境中打开.Prm文件如图划分好

 

CAN通信驱动和协议

 

前面说过boot要选一种对外的通信方式,这里我们用CAN通信,当然你也可以选择其他通信方式它只要能把数据发下去就行。

CAN初始化

 

CAN发送函数

 

 

 

CAN接收函数

我用的协议很简单一帧用来握手,然后5个数据帧发完S19一行数据(为什么是5帧?后面解释)

 

启动部分汇编代码

内存划分好了,通信链路也通了就剩下关于启动部分的代码编写了,这个是第二种方式每次上电都进入boot

 

升级完成执行APP

 

S19文件的理解

 

S-record每行最大是78个字节,156个字符

S-record format:

type(类型):2个字符。用来描述记录的类型 (S0,S1,S2,S3,S5,S7,S8,S9)。

count(计数):2个字符。用来组成和说明了一个16进制的值,显示了在记录中剩余成对字符的计数。

address(地址):4或6或8个字节。用来组成和说明了一个16进制的值,显示了数据应该装载的地址, 这部分的长度取决于载入地址的字节数。2个字节的地址占用4个字符,3个字节的地址占用6个字符,4个字节的地址占用8个字符。

data(数据):0—64字符。用来组成和说明一个代表了内存载入数据或者描述信息的16进制的值。

checksum(校验和):2个字符。这些字符当被配对并换算成16进制数据的时候形成了一个最低有效字符节,该字符节用来表达作为补充数据,地址和数据库的字符对所代表的(字节的)补码的byte总和。即计数值、地址场和数据场的若干字符以两个字符为一对,将它们相加求和,和的溢  出部分不计,只保留最低两位字符NN,checksum =0xFF-0xNN。

S0 Record:记录类型是“S0” (0x5330)。地址场没有被用,用零置位(0x0000)。数据场中的信息被划分为以下四个子域(此行表示程序的开始,不需烧入memory):

name(名称):20个字符,用来编码单元名称

ver(版本):2个字符,用来编码版本号

rev(修订版本):2个字符,用来编码修订版本号

description(描述):0-36个字符,用来编码文本注释。

S1 Record:记录类型是“S1” (0x5331)。地址场由2个字节地址来说明。数据场由可载入的数据组成。

S2 Record:记录类型是“S2” (0x5332)。地址场由3个字节地址来说明。数据场由可载入的数据组成。

S3 Record:记录类型是“S3” (0x5333)。地址场由4个字节地址来说明。数据场由可载入的数据组成。

S5 Record:记录类型是“S5” (0x5335)。地址场由2字节的值说明,包含了先前传输的S1、S2、S3记录的计数。没有数据场。

S7 Record:记录类型是“S7” (0x5337)。地址场由4字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。

S8 Record:记录类型是“S8” (0x5338)。地址场由3字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。

S9 Record:记录类型是“S9” (0x5339)。地址场由2字节的地址说明,包含了开始执行地址。没有数据场。此行表示程序的结束,不需烧入memory。

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。 img img

如果你需要这些资料,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!