Contents html
一、Blhost : 2 算法
二、Excute 3app
二、BCA 4ide
一、TAG 5函数
二、Enable and disable peripherals 5工具
四、USB pid&vid 6flex
七、CAN configure1 & configure2 7
二、Fill memory to a big block 12
三、Write memory with high speed 12
一、Kibble_CRC_01 checkinvalid 15
二、Kibble_CRC_01 checkinactive 16
四、Kibble_CRC_02 CheckFailed 17
Blhost是PC跟板子进行通讯的软件,查看RD提供的文件中是否有blhost ,路径\Kinetis_Bootloader_2_0_0_d1\bin
Blhost的使用手册路径
Desktop\Kinetis_Bootloader_2_0_0_d1\doc\Kinetis_blhost_User-s_Guide_review
一、Get-property命令能够查看板子的属性值,属性值能够在datasheet中找到,查看是否跟datasheet中同样
二、set-property能够配置板子可写的属性值,命令格式以下
Blhost -p COM*/-u -- set-property 10/13/22 0/1
当即跳转到app
Demo写到指定 地址
blhost -u -- write-memory 0x8000 app_led_demo.bin
读取写入内容
blhost -u -- read-memory 0x8000 10
The first word is the address of <stackpointer>, but with Little endian ,The second word is the address of <addr>
例如读出来的前八byte值以下
0000a411 1fffe230
Stack pointer
地址单位是字,四个字节。(MCU是32位)
使用excute命令调到app
blhost -u -- execute sencond_word_address 0 first_word_address
使用错误的地址,看是否跳不到app。如上两个红色参数分别设置错误
PC错误,不可跳到app。Stack错误,能跳到
Blhost -p com43 -- excute 0x1fffe230 0 0x0000a411
Blhost -p com43 -- excute 0x1fffe230 0 错误stack
Blhost -p com43 -- flash-erase-region 0x0 100 // 返回kStatusMemoryRangeInvalid
Blhost -p com43 -- write-memory 0x0 100 //写值到reserved区域,kStatusMemoryRangeInvalid
Blhost -p com43 -- read-memory 0x0 1000000 //按住ctrl+c看是否中断读取
BCA (bootloade rconfiguration area)是能够配置bootloader的一段区域。它位于应用程序起始地址+0x3c0处。
Bootloader启动的时候会使用默认的配置,当启动完成后。能够在如上的地址处修改bootloader的配置
BCA开始四个字节称为tag,必须设置为'kcfg'。
详细描述请参考\Kinetis_Bootloader_2_0_0_d1\doc\reference_manual中chapter 2
Kcfg in hex are 6B 63 66 67
Flash –resident 中offset为0x3c0
ROM中offset 为0x3c0
A、在offset处写入tag为kcfg,同时关闭外设(置00),重启。发现UART 、I2C等外设都不能使用。
此时要想使外设可以使用,惟一的方法就是用j-link中的unlock kinetis命令擦除
Blhost -u -- write-memory $BCA_OFFSET "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF 00}}"
B、在offset处写入错误的tag(kcxg),同时关闭外设,重启。发现全部外设还能正常工做
Blhost -u -- write-memory $BCA_OFFSET "{{6B 63 78 67 FF FF FF FF FF FF FF FF FF FF FF FF 00}}"
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 78 67 FF FF FF FF FF FF FF FF FF FF FF FF 00}}"
//all the peripherals can work
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF 00}}"
//correct TAG all the peripherals can not work ,need to use jlink unlock the device
以下截图在用户手册中截取,bit位置1表示使能,置0表示禁用
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF 01}}"
Blhost -p com43 -- reset
Disable uart only
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF FE}}"
I2C
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF 02}}"
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF FD}}"
SPI
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF 04}}"
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF FB}}"
USB
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF 10}}"
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF EF}}"
CAN
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF 08}}"
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF F7}}"
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 FF FF FF FF FF FF FF FF FF FF FF FF FF 35}}"
Blhost -p com43 -- reset
// it doesn't work
Blhost -p com42 -b i2c -- get-property 1
//it works normally
Blhost -p com42 -b i2c,0x35 -- get-property 1
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 }}"
// {{usbVidLByte usbVidHByte usbPidLByte usbPidHByte}}"
Blhost -p com43 -- write-memory 0x10003d0 "{{ff ff ff ff a2 15 75 00 }}"
blhost -u usbVid,usbPid
Blhost -u 0x15a2,0x0075 -- get-property 1//it works normally
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67 }}"
// stings pointer
Blhost -p com43 -- write-memory 0x10003d8 "{{65 66 67 68 }}"
Blhost -p com43 -- reset
Blhost -u -- get-property 1
先下载led_demo到板子中,而后执行以下的命令,看灯是否10s后闪烁
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67}}"
Blhost -p com43 -- write-memory 0x10003d0 "{{FF FF 10 27}}" //0x2710ms=10s
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67}}"
Blhost -p com43 -- write-memory 0x10003d0 "{{FF FF 10 27}}" //设置app启动延时
Blhost -p com43 -- write-memory 0x10003d8 "{{ff ff ff ff ff ff 00 ff}}" //直接跳转flag
CAN
写死速率为0,若只是配置tag,则速率均可以使用,且不须要复位
125K 250K 500K 1M
0 1 2 4
3e9 :can-config1
3ea-3eb : can-config2
CAN RX/TX ID
Default :canTxId=0xffff ,txId=0x123;Else : txId= canTxId & 0x7ff.//cantxid 跟TXID不是一回事,blhost使用的是txid,同理rx也是这个状况
Default :canRxId=0xffff ,rxId=0x321;Else : rxId= canRxId & 0x7ff.
3ec-3ed canTxId
3ee-3ef canRxId
函数:flexcan_peripheral_init
Canconfig1 & 0x08,若为真,也就是canconfig1 bit[3] = 1的状况下,则根据canconfig2配置speed
若为假,则根据canconfig1 bit[0:2]的值计算速率
从下面的代码中能够看出,bit[0:2]的值>=3就默认使用default,也就是1M
计算方式以下:
switch (s_flexcanInfo.baudrate)
{
case 0:
config.baudRate = 125000;
break;
case 1:
config.baudRate = 256000;
break;
case 2:
config.baudRate = 500000;
break;
case 3:
case 4:
default:
config.baudRate = 1000000;
break;
}
一、配置BCAtag,不设置速率,则0,1,2,4速率均可以使用
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67}}"
Blhost -p com13 -b can,1 -- get-property 1
二、配置3e9处速率,测试只能在该速率下通讯
Blhost -p com43 -- write-memory 0xa3e0 "{{ ff ff ff ff ff ff ff ff ff f0 ff ff ff ff ff ff }}"
Blhost -p com13 -b can,0 -- get-property 1
三、配置config2内容
(Clock is based on 24Mhz.Baud rate 1M ,propseg = 4,pseg1 = 2, pseg2 = 2,pre_divider = 1,rjw = 2)
3e9 :can-config1
3ea-3eb : can-config2
Blhost -p com43 -- get-property 1
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{ 6b 63 66 67 }}"
Blhost -p com43 -- write-memory 0xa3e8 "{{ ff c8 4a 00 }}"
Blhost -p com13 -b can,4 -- get-property 1 //只用速率4pass
一、测试默认状态rxid&txid
Blhost -p com13 -b can,4,0x321,0x123 -- get-property 1 //pass
Blhost -p com13 -b can,4,0x321,0x133 -- get-property 1
Blhost -p com13 -b can,4,0x123,0x321 -- get-property 1
二、不设置速率,设置id
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67}}"
Blhost -p com43 -- write-memory 0xa3e0 "{{ ff ff ff ff ff ff ff ff ff ff ff ff ff 03 6f 66 }}"//txid = 0x03ff&0x7fff = 0x03ff rxid = 0x666f&0x7fff = 0x6ff
Rx tx
Blhost -p com43 -- reset
Blhost -p com13 -b can,2,0x66f,0x3ff -- get-property 1 //pass
Blhost -p com13 -b can,2,0x66f,0x123 -- get-property 1
Blhost -p com13 -b can,2,0x321,0x3ff -- get-property 1
Blhost -p com13 -b can,2,0x321,0x123 -- get-property 1
三、配置速率跟ID
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67}}"
Blhost -p com43 -- write-memory 0xa3e0 "{{ ff ff ff ff ff ff ff ff ff f1 ff ff ff 03 6f 66 }}"
Blhost -p com43 -- reset
Blhost -p com13 -b can,1,0x66f,0x3ff -- get-property 1 //pass
Blhost -p com13 -b can,0,0x66f,0x3ff -- get-property 1
Blhost -p com13 -b can,4,0x66f,0x3ff -- get-property 1
Blhost -p com13 -b can,2,0x66f,0x3ff -- get-property 1
Configure BCA clockDivider, also disable the peripheral of USB and set in high-speed mode
而后查看bootloader是否能正常工做
简单来讲就是usb使能的话就必定是工做在high speed mode,因此必须是48M,要想配置24M这种必须将usb关掉。
一、Configure core clock to 24MHz.
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67 ff ff ff ff ff ff ff ff ff ff ff ff 07 ff ff ff ff ff ff ff ff ff ff ff fe fe ff ff}}"
Blhost -p com43 -- get-property 1
二、Configure core clock to 8MHz.
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67 ff ff ff ff ff ff ff ff ff ff ff ff 07 ff ff ff ff ff ff ff ff ff ff ff fe fa ff ff}}"
三、Configure core clock to 4MHz.
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67 ff ff ff ff ff ff ff ff ff ff ff ff 07 ff ff ff ff ff ff ff ff ff ff ff fe f4 ff ff}}"
Bus就是总线,是链接各个部件的一组信号线。咱们测试的总线有以下几种:UART、I2C、SPI、USB、CAN
测试不一样速率下的总线是否能正常工做
UART:
Blhost -p com43 -- reset
Blhost -p com43,4800 -- get-property 1
Blhost -p com43,9600 -- get-property 1
Blhost -p com43,19200 -- get-property 1
Blhost -p com43,25600 -- get-property 1
Blhost -p com43,38400 -- get-property 1
Blhost -p com43,57600 -- get-property 1
Blhost -p com43,115200 -- get-property 1
USB:
blhost -u -- get-property 1
SPI:
Blhost -p com42 -b spi,5 -- get-property 1
Blhost -p com42 -b spi,10 -- get-property 1
Blhost -p com42 -b spi,20 -- get-property 1
Blhost -p com42 -b spi,50 -- get-property 1
Blhost -p com42 -b spi,100 -- get-property 1
Blhost -p com42 -b spi,200 -- get-property 1
Blhost -p com42 -b spi,500 -- get-property 1
Blhost -p com42 -b spi,1000 -- get-property 1
Blhost -p com42 -b spi,2000 -- get-property 1
I2C:
blhost -p com42 -b i2c -- get-property 1
blhost -p com42 -b i2c,0x10,5 -- get-property 1
blhost -p com42 -b i2c,0x10,50 -- get-property 1
blhost -p com42 -b i2c,0x10,100 -- get-property 1
blhost -p com42 -b i2c,0x10,400 -- get-property 1
CAN:
125K
Blhost -p com13 -b can -- flash-erase-all
Blhost -p com13 -b can -- write-memory 0x3c0 "{{ 6b 63 66 67 }}"
Blhost -p com13 -b can -- write-memory 0x3e0 "{{ ff ff ff ff ff ff ff ff ff f0 ff ff ff ff ff ff }}"
Blhost -p com13 -b can -- reset
Blhost -p com13 -b can,0 -- fill-memory 0x0 0x1000 0xfe byte
Blhost -p com13 -b can,0 -- read-memory 0x0 0x1000
250k:
Blhost -p com13 -b can -- flash-erase-all
Blhost -p com13 -b can -- write-memory 0x3c0 "{{ 6b 63 66 67 }}"
Blhost -p com13 -b can -- write-memory 0x3e0 "{{ ff ff ff ff ff ff ff ff ff f1 ff ff ff ff ff ff }}"
Blhost -p com13 -b can -- reset
Blhost -p com13 -b can,1 -- fill-memory 0x0 0x1000 0xfe byte
Blhost -p com13 -b can,1 -- read-memory 0x0 0x1000
500k:
Blhost -p com13 -b can -- flash-erase-all
Blhost -p com13 -b can -- write-memory 0x3c0 "{{ 6b 63 66 67 }}"
Blhost -p com13 -b can -- write-memory 0x3e0 "{{ ff ff ff ff ff ff ff ff ff f2 ff ff ff ff ff ff }}"
Blhost -p com13 -b can -- reset
Blhost -p com13 -b can,2 -- fill-memory 0x0 0x1000 0xfe byte
Blhost -p com13 -b can,2 -- read-memory 0x0 0x1000
1M:
Blhost -p com13 -b can -- flash-erase-all
Blhost -p com13 -b can -- write-memory 0x3c0 "{{ 6b 63 66 67 }}"
Blhost -p com13 -b can -- write-memory 0x3e0 "{{ ff ff ff ff ff ff ff ff ff f4 ff ff ff ff ff ff }}"
Blhost -p com13 -b can -- reset
Blhost -p com13 -b can,4 -- fill-memory 0x0 0x1000 0xfe byte
Blhost -p com13 -b can,4 -- read-memory 0x0 0x1000
To check all the bus driver
向内存写入大量数据后读出来比对是否正确,来判断驱动是否正常
UART:
Blhost -p com43 -- flash-erase-all
blhost -t 100000 -p com43,115200 -- fill-memory 0x0 20000 0x10
blhost -t 100000 -p com43,115200 -- read-memory 0x0 20000
SPI:
blhost -t 10000 -p com42 -b spi,2000,1,1,msb -- fill-memory 0xb000 0x10000 0xfe
blhost -t 10000 -p com42 -b spi,2000,1,1,msb -- read-memory 0xb000 0x10000
I2C:
blhost -t 10000 -p com42 -b i2c,0x10,400 -- fill-memory 0xb000 0x10000 0xfe
blhost -t 10000 -p com42 -b i2c,0x10,400 -- read-memory 0xb000 0x10000
CAN:
blhost -t 10000 -p com42 -b can -- fill-memory 0xb000 0x10000 0xfe
blhost -t 10000 -p com42 -b can -- read-memory 0xb000 0x10000
配置peripheral高速模式下写入大量数据
UART:
blhost -t 10000 -p com43 -- flash-erase-all
blhost -t 10000 -p com43,115200 -- get-property 1
blhost -t 10000 -p com43,115200 -- write-memory 0x0 文件
blhost -t 10000 -p com43,115200 -- read-memory 0x0 0x10000
I2C:
blhost -t 10000 -p com42 -b i2c,0x10,400 -- flash-erase-all
blhost -t 10000 -p com42 -b i2c,0x10,400 -- write-memory 0xb000 0x10000
blhost -t 10000 -p com42 -b i2c,0x10,400 -- read-memory 0xb000 0x10000
SPI:
blhost -t 10000 -p com42 -b spi,2000,1,1,msb -- write-memory 0xb000 0x10000
blhost -t 10000 -p com42 -b spi,2000,1,1,msb -- read-memory 0xb000 0x10000
CAN :
blhost -t 10000 -p com13 - b can -- write-memory 0x3c0 "{{ 6b 63 66 67 }}"
blhost -t 10000 -p com13 - b can -- write-memory 0x3e0 "{{ ff ff ff ff ff ff ff ff ff f4 ff ff ff ff ff ff }}"
blhost -t 10000 -p com13 -b can,4 -- write-memory 0xb000 0x10000
blhost -t 10000 -p com13 -b can,4 -- read-memory 0xb000 0x10000
测试拔除通讯线的状况下是否能通讯或者不能通讯的状况下占用通讯通道
UART:
拔除uart RX线:
blhost -t 10000 -p com43 -- get-property 1 //fail
blhost -t 10000 -p com13 -b spi -- get-property 1 //pass
reset
blhost -t 10000 -p com43 -- get-property 1 //fail
插线
blhost -t 10000 -p com43 -- get-property 1 //pass
I2C:
拔除I2C SDA线
blhost -t 10000 -p com13 - b i2c -- get-property 1 //fail
blhost -t 10000 -p com13 - b spi -- get-property 1 //pass
reset
blhost -t 10000 -p com13 - b i2c -- get-property 1 //fail
插线
blhost -t 10000 -p com13 - b i2c -- get-property 1 //pass
SPI:
拔除SPI sin线
blhost -t 10000 -p com13 - b spi -- get-property 1 //fail
blhost -t 10000 -p com13 - b i2c -- get-property 1 //pass
reset
blhost -t 10000 -p com13 - b spi -- get-property 1 //fail
插线
blhost -t 10000 -p com13 - b spi -- get-property 1 //pass
CAN:
拔除CAN 任意一根线
blhost -t 10000 -p com13 - b can -- get-property 1 //fail
blhost -t 10000 -p com13 - b i2c -- get-property 1 //pass
reset
blhost -t 10000 -p com13 - b can -- get-property 1 //fail
插线
blhost -t 10000 -p com13 - b can -- get-property 1 //pass
BCA起始地址0x0(start address of user application)+0x3c0(offset)
3c4-3c7 : crcStartaddress 都是4byte
3c8-3cb : crcByteCount
3cc-3cf : crcExpectedValue
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67 ff ff ff ff ff ff ff ff ff ff ff ff }}"
Blhost -p com43 -- reset
Blhost -p com43 -- get-property 8
设置tag,不设置PC值,可是非所有ff
Blhost -p com43 -- write-memory 0x3c0 "{{6B 63 66 67}}"
//BCA is valid and and crc parameters are set (not all 0xff bytes).
//开启Tag,可是其他值所有设为0
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67 00 00 00 00 00 00 00 00 00 00 00 00}}"
//BCA中CRC相关值写为0
Blhost -p com43 -- reset
Blhost -p com43 -- get-property 8 //返回值应该为kStatus_AppCrcCheckInactive
必须设置PC值
BCA is valid and and crc byte count is equal to zero.
A、
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67 00 00 00 00 00 00 00 00 ff ff ff ff}}"
Blhost -p com43 -- write-memory 0x0 "{{ff ff ff ff 01 00 00 00}}"
// set a PC pointer which is used for the bootloader check process。。a000处开始的四个字节是stack
Blhost -p com43 -- reset
Blhost -p com43 -- get-property 8
//except return value shoul be kStatus_AppCrcCheckOutOfRange
BCA is valid and and crc start address + count > END address
B、
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{ 6b 63 66 67 ff ff ff ff 00 00 00 02 ff ff ff ff}}"
//Blhost -p com43 -- write-memory 0x3c0 "{{ 6b 63 66 67 ff ff ff ff 00 00 00 00 00 00 00 00}}"
Blhost -p com43 -- write-memory 0x0 "{{ff ff ff ff 01 00 00 00}}"
// set a PC pointer which is used for the bootloader check process
Blhost -p com43 -- reset
Blhost -p com43 -- get-property 8
//except return value shoul be kStatus_AppCrcCheckOutOfRange
BCA is valid and and crc end address exceeds 4G address space
C、
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{ 6b 63 66 67 00 00 08 00 00 00 00 02 ff ff ff ff }}"
Blhost -p com43 -- write-memory 0x0 "{{ff ff ff ff 01 00 00 00}}"
// set a PC pointer which is used for the bootloader check process
Blhost -p com43 -- get-property 8
//except return value shoul be kStatus_AppCrcCheckOutOfRange
BCA is valid and everything is right but crc expect value is wrong
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67 00 a4 00 00 08 00 00 00 00 00 00 12}}"
//start 地址为0xa400 count为8 excepted value为0x12000000 错误值
Blhost -p com43 -- write-memory 0xa400 "{{11 22 33 44 55 66 77 88}}"
//检查的字节数目为8
Blhost -p com43 -- write-memory 0x0 "{{ff ff ff ff 0 a4 00 00}}"
// set a PC pointer which is used for the bootloader check process
Blhost -p com43 -- reset
Blhost -p com43 -- get-property 8
//except return value shoul be kStatus_AppCrcCheckFailed
Blhost -p com43 -- flash-erase-all
Blhost -p com43 -- write-memory 0x3c0 "{{6b 63 66 67 00 a4 00 00 01 00 00 00 8B 3E 83 E9}}"
//配置crc计算的起始地址为0x0000a400 ,从0xa400处取一个byte ,checksum为8B 3E 83 E9
Blhost -p com43 -- write-memory 0xa400 {{cd}}
//0xa400处写入一个byte,内容为0xcd
Blhost -p com43 -- write-memory 0x0 "{{ff ff ff ff 00 01 00 00}}"
// set a PC pointer which is used for the bootloader check process,PC 能够设置为除了0x0 0xffff reset——handle 的PC值外的任意值
设置PC的目的是,bootloader运行时,会检测app的PC is_application_ready_for_executing
Blhost -p com43 -- reset
Blhost -p com43 -- get-property 8
啸天上的case
DCD 0x6766636B ;240 /*0x3c0*/咱们写的顺序是从高到低位,可是内存中读出来是是从低位开始的,看上去像是反过来, 小端模式
DCD 0x0000A000 ;241
DCD 0x0000084E ;242
DCD 0xFFFFFFFF ;243 /*with radom value at first*/
DCD 0xFFFFFFFF ;244
DCD 0xFFFFFFFF ;245
DCD 0xFFFFFFFF ;246
DCD 0xFFFFFFFF ;247
DCD 0xFFFFFFFF ;248
DCD 0xFFFFFFFF ;249
DCD 0xFFFFFFFF ;250
DCD 0xFFFFFFFF ;251 /*0x3fc*/
CRC的检测是在init函数中get_active_peripheral
static bool is_application_ready_for_executing(uint32_t applicationAddress)
#if BL_FEATURE_CRC_CHECK
// Validate application crc only if its location is valid
if (result)
{
result = is_application_crc_check_pass();
}
Flash configuration area 0x400-0x40f
0x400处是flash configuration area
0x40D FOPT[BOOTSRC_SEL] bit[7:6] = 0b10表示ROM启动同时配置QSPI
0x400 – 0x40F这十六个字节的空间是flash configure区域。Reset后,flash secure寄存器FSEC,FOPT等会从这个地方加载相关的数据。从而实现flash secure状态的配置,boot的配置等等。
IFR是独立于program的一段空间。
Can't erase IFR
Program once ID field的index是:0x0-0x0f, 每一个index 4bytes
Program once XACC & SACC 是:0x10-0x13,每一个index 8 bytes
如上的96 bytes只能够program once可是不可擦
erase IFR
0x20-0x23能够写擦可是不可读
0x30-0x33 能够读写擦
每一个index能够写4bytes
这个case设计的目的是为了测试backdoor key是否能工做。使用flash-erase-all以后0x40C就会变写成0xff 从而bit[1:0]变成11处于secure的状态
Flash configuration area中0X40C存放的是FSEC。
当板子reset后,FSEC的内容会拷贝到FTFA_FSEC寄存器中(0x4002_0002h),此寄存器可读不可写,reset状态其内容不可知.每一个bit位的定义如上图所示。
bit[7:6] 表明是否enable backdoorkey (10表明enable,其他都是disable)
bit[1:0]表明MCU的状态是否为secure(10表明unsecure,其他都是secure)
blhost -p com43 -- get-property 17
Expected Result:Flash Security State=UNSECURE.
blhost -p com43 -- flash-erase-all
blhost -p com43 -- read-memory 0x400 16
Expected Result:For no flash reserved(K80) bootloader, all the bytes are 0xff.
//enable backdoorkey 0x40C bit[7:6] = 10 and set secure status 0x40C bit[1:0] = 11
blhost -p com43 -- write-memory 0x400 "{{ 01 02 03 04 05 06 07 08 ff ff ff ff bf ff ff ff}}"
blhost -p com43 -- reset
blhost -p com43 -- get-property 17
Expected Result: Flash Security State=SECURE.
blhost -p com43 -- flash-security-disable 0102030405060709 (Wrong Key)
Expected Result:kStatus_FlashAccessError
blhost -p com43 -- reset
blhost -p com43 -- flash-security-disable 0102030405060708 (Right Key)
Expected Result:Success
blhost -p com43 -- get-property 17
Expected Result: Flash Security State=UNSECURE
blhost -p com43 -- flash-erase-all
blhost -p com43 -- reset
blhost -p com43 -- get-property 17
Expected Result: Flash Security State=SECURE.
blhost -p com43 -- flash-erase-all-unsecure
blhost -p com43 -- get-property 17
Expected Result:Flash Security State=UNSECURE.
这个case的目的是为了验证0x40c处的配置,看flash security是否能生效。
bit[1:0]表明MCU的状态是否为secure(10表明unsecure,其他都是secure)
仅当FSEC bit[1:0]为10时,unsecure。因此,以下只有case4会生效,其他都不能够读写擦
blhost -p com43 -- flash-erase-all-unsecure
case 1:
blhost -p com43 -- get-property 1
blhost -p com43 -- flash-erase-all
blhost -p com43 -- write-memory 0x400 "{{ff ff ff ff ff ff ff ff ff ff ff ff f0 ff ff ff}}"
blhost -p com43 -- reset
blhost -p com43 -- read-memory 0x0 1024
case 2:
blhost -p com43 -- get-property 1
blhost -p com43 -- flash-erase-all
blhost -p com43 -- write-memory 0x400 "{{ff ff ff ff ff ff ff ff ff ff ff ff f1 ff ff ff}}"
blhost -p com43 -- reset
blhost -p com43 -- read-memory 0x0 1024
case 3:
blhost -p com43 -- get-property 1
blhost -p com43 -- flash-erase-all
blhost -p com43 -- write-memory 0x400 "{{ff ff ff ff ff ff ff ff ff ff ff ff f3 ff ff ff}}"
blhost -p com43 -- reset
blhost -p com43 -- read-memory 0x0 1024
case 4:
blhost -p com43 -- get-property 1
blhost -p com43 -- flash-erase-all
blhost -p com43 -- write-memory 0x400 "{{ff ff ff ff ff ff ff ff ff ff ff ff fe ff ff ff}}"
blhost -p com43 -- reset
blhost -p com43 -- read-memory 0x0 1024
将写的flash区域所有写满,而后读取,查看写入值是否正确
3 è flash start address
4 è flash size
12 èreserved region
blhost -p com43 -- flash-erase-all
blhost -t 30000 -p com43 -- fill-memory 0x5000 0x3b000 0xfe byte
blhost -t 30000 -p com43 -- read-memory 0x5000 0x3b000 C:\Users\B57252\Desktop\1.txt
blhost -p com43 -- flash-erase-all
blhost -t 30000 -p com43 -- fill-memory 0x5000 0x3b000 0xfe short
blhost -t 30000 -p com43 -- read-memory 0x5000 0x3b000 C:\Users\B57252\Desktop\1.txt
blhost -p com43 -- flash-erase-all
blhost -t 30000 -p com43 -- fill-memory 0x5000 0x3b000 0xfe word
blhost -t 30000 -p com43 -- read-memory 0x5000 0x3b000 C:\Users\B57252\Desktop\1.txt
使用fill-memory的方法将flash写满,而后读取到一个txt文档里面。再经过write-memory的方式将flash写满
blhost -p com43 -- flash-erase-all
blhost -t 30000 -p com43 -- fill-memory 0x5000 0x3b000 0xfe short
blhost -t 30000 -p com43 -- read-memory 0x5000 0x3b000 C:\Users\B57252\Desktop\1.txt
blhost -p com43 -- flash-erase-all
blhost -t 30000 -p com43 -- write-memory 0x5000 C:\Users\B57252\Desktop\1.txt
blhost -t 30000 -p com43 -- read-memory 0x5000 0x3b000
Read once命令对应的读取96bit reserved区域。
读取的内容位于flash哪里?为什么跟read-memory读取出来的值不同?
能读取到IFR区域的值就ok
blhost -p com43 -- flash-read-once 0 4 //read the program once field
blhost -p com43 -- flash-read-resource 0x000000 256 0x00//read the IFR
blhost -p com43 -- flash-read-resource 0x000000 8 0x01 //read the Version ID
Read and write invalid address of flash
一、Read/Write reserved regions
blhost -p com43 -- read-memory 0x0 10 //pass
blhost -p com43 -- write-memory 0x0 {{11111111}} //kStatusMemoryRangeInvalid.
二、 Read/Write address extend the whole flash
blhost -p com43 – get-property 4 //get-flash-size
blhost -p com43 -- read-memory 0x0 0x40004 //exceed flash size
blhost -p com43 -- write-memory 0x40000 {{111111}} //write value beyond the flash size
三、Read/Write address more than a sector
blhost -p com43 – get-property 5 //get-sector-size
blhost -p com43 -- read-memory 0x0 0x1004 //read more than a sector
blhost -p com43 -- fill-memory 0x0 0x1004 0xfe //fill than a sector size
四、Read/Write address not aligned, which include not aligned number and not aligned address
blhost -p com43 -- read-memory 0x0123,7 //success
blhost -p com43 -- write-memory 0xa123 "{{123}}"// kStatus_FlashAlignmentError
bit位00对齐,100 、1000 1100换成16进制末尾是四、八、0、12
关于对齐:
对齐有两种:一、数据对齐 二、地址对齐
Reference manual中找到Flash Memory Module ==》functional description==》flash command description ==》read 1s section command
如上表示4字节对齐(对内存的操做以字节为单位)
因此地址根数据必须是0x10的整数倍
为何要对齐:
http://blog.163.com/crazy20070501@126/blog/static/12865946520112131313900/
执行call命令
建立IAR工程,生成bin文件的代码以下:
#include "stdint.h"
#define RAM_BASE (0x20002000ul)
int call_command()
{
volatile uint32_t *ram_reg = (volatile uint32_t*) RAM_BASE;
*ram_reg +=1;
return 0;
}
IAR环境 配置
1 select binary in "Output Converter" .
2 select " Cortex-M0+" in "General Option->Target->Core"
3 fill "call_command" in Linker->Library->Override default program entry
blhost -p com43 -- read-memory 0x20002000 1
blhost -p com43 -- write-memory 0x20000000 L5k_call.bin
blhost -p com43 -- call 0x20000001 0
blhost -p com43 -- read-memory 0x20002000 1
the value in 0x20002000 should plus 1
PF size肯定了flash的大小,计算后查表而后与get-property 4对比
"System Integration Module(SIM)" ->Memory map and register definition -> SIM -> SIM_FCFG1. Find the absolute address of SIM_FCFG1. [27-24]bits of SIM_FCFG1 stands for the PFSize.
例子:
blhost -p com# -- read-memory 0x4007504c 4 //读取四个字节
The blhost returns:00 00 00 0b . So the value of SIM_FCFG1 is 0x0b000000
step2: [27-24]bits of SIM_FCFG1 stands for the PFSize, so the PFSize of L5K is 1011
PFSize flash size
"0000 8K
"0001 16K
"0010 24K
"0011 32K
"0100 48K
"0101 64K
"0110 96K
"0111 128K
"1000
"1001 256K
"1010
"1011 512K
"1100
"1101 1M
"1110
"1111 2M
FAC(XACC)是用来控制flash某个segment访问权限的寄存器。
以K82为例:
Flash会分为64个相等的segment.
1. 40020018 开始的地址XACCH0-3,XACCL0-3 共8个寄存器控制64个segment = flash size/64,segment size也能够经过get-property 0x20获得。板子复位后,该地址处会自动加载IFR index 0x10跟0x11按位与的结果。
2. XACC由IFR 0x10跟0x11按位与获得结果
3. IFR 0xa0-0xaf(index 10对应A0-A7)能够经过read resource 0xa0 8 0获得,写入能够经过program once写入
4. IFR每四个字节小端存储
IFR 0x10 8个bytes
IFR 0x11 8个bytes
例子:
Flash-program-once 0x10 1122334455667788
Flash-program-once 0x10 1122334455667788
88与88按位与,获得的结果对应0-7 segment, 即flash 0地址开始的segment
77与77按位与,获得的结果对应8-15 segment
11与11按位与,获得结果对应56-63 segment
详细的对应关系以下:
以下表格是计算好的IFR:
For example (segment 0 – 7):
segment number |
XA[7:0] |
progam flash IFR address A |
program flash IFR address B |
0 |
11111110 |
ffff_ffff_ffff_fffe |
ffff_ffff_ffff_fffe |
ffff_ffff_ffff_fffe |
ffff_ffff_ffff_ffff |
||
ffff_ffff_ffff_ffff |
ffff_ffff_ffff_fffe |
||
1 |
11111101 |
ffff_ffff_ffff_fffd |
ffff_ffff_ffff_fffd |
ffff_ffff_ffff_ffff |
ffff_ffff_ffff_fffd |
||
ffff_ffff_ffff_fffd |
ffff_ffff_ffff_ffff |
||
2 |
11111011 |
ffff_ffff_ffff_fffb |
ffff_ffff_ffff_fffb |
ffff_ffff_ffff_fffb |
ffff_ffff_ffff_ffff |
||
ffff_ffff_ffff_ffff |
ffff_ffff_ffff_fffb |
||
3 |
11110111 |
ffff_ffff_ffff_fff7 |
ffff_ffff_ffff_fff7 |
ffff_ffff_ffff_fff7 |
ffff_ffff_ffff_ffff |
||
ffff_ffff_ffff_ffff |
ffff_ffff_ffff_fff7 |
||
4 |
11101111 |
ffff_ffff_ffff_ffef |
ffff_ffff_ffff_ffef |
ffff_ffff_ffff_ffff |
ffff_ffff_ffff_ffef |
||
ffff_ffff_ffff_ffef |
ffff_ffff_ffff_ffff |
||
5 |
11011111 |
ffff_ffff_ffff_ffdf |
ffff_ffff_ffff_ffdf |
ffff_ffff_ffff_ffdf |
ffff_ffff_ffff_ffff |
||
ffff_ffff_ffff_ffff |
ffff_ffff_ffff_ffdf |
||
6 |
10111111 |
ffff_ffff_ffff_ffbf |
ffff_ffff_ffff_ffbf |
ffff_ffff_ffff_ffff |
ffff_ffff_ffff_ffbf |
||
ffff_ffff_ffff_ffbf |
ffff_ffff_ffff_ffff |
||
7 |
01111111 |
ffff_ffff_ffff_ff7f |
ffff_ffff_ffff_ff7f |
ffff_ffff_ffff_ff7f |
ffff_ffff_ffff_ffff |
||
ffff_ffff_ffff_ffff |
ffff_ffff_ffff_ff7f |
Case:
blhost -p com# -- flash-erase-all-unsecure
blhost -p com# -- flash-program-once 0x10 8 fffffffffffffffe
Or blhost -p com# -- flash-program-once 0x08 8 fffffffffffffffe
blhost -p com# -- flash-program-once 0x11 8 fffffffffffffffe
Or blhost -p com# -- flash-program-once 0x09 8 fffffffffffffffe
blhost -p com# -- reset
the segment 0 is in execute-only mode, it can't be read and programmed.
blhost -p com# -- read-memory 0x00 16
expected result: kStatus_FlashRegionExecuteOnly
blhost -p com# -- write-memory 0x00 {{1122334455667788}}
expected result: kStatus_FlashRegionExecuteOnly
RAM测试跟flash的测试相似,将ram写满,而后读取,比较读取的内容跟写入的是否一致
blhost -u -- get-property 15 //get ram size
blhost -u -- get-property 14 //get ram start address
blhost -u -- get-property 12 //get ram reserved region
blhost -t 3000 -u -- fill-memory 0x1fff1298 126312 0xfe byte //fill the whole memory with 0xfe
blhost -t 3000 -u -- read-memory 0x1fff0000 131072 //read the whole memory
blhost -u -- get-property 15 //RAM Size = 128 KB
blhost -u -- get-property 14 //RAM Start Address = 0x1FFF0000
blhost -u -- get-property 12 // RAM: 0x1FFF0000-0x1FFF1297
blhost -t 30000 -u -- fill-memory 0x1fff1298 126312 0xfe byte //fill the whole memory with 0xfe
blhost -t 30000 -u -- read-memory 0x1fff1298 131072 C:\Users\public.ZCHLABB46681-12\Desktop\Kinetis_Bootloader_2_0_0_d1\bin\Tools\blhost\win\test.txt //read memory to test_ram.txt
blhost -t 10000 -u -- write-memory 0x1fff1298 C:\Users\public.ZCHLABB46681-12\Desktop\Kinetis_Bootloader_2_0_0_d1\bin\Tools\blhost\win\test_ram.txt //write data to RAM
blhost -t 10000 -u -- read-memory 0x1fff1298 131072 //read the writed memory
1 、read and write reserved region
blhost -p com43 -- read-memory 0x0 0x1004
blhost -u -- read-memory $RAM_Reserved_Start Reserved_Size, will read the value successfully.
blhost -u -- write-memory $RAM_Reserved_Start "{{1122}}", will return kStatusMemoryRangeInvalid.
二、read not aligned
blhost -u -- read-memory 0x1FFFE123 7,0x123 will read successfully
blhost -u -- write-memory 0x20001234 "{{123}}", will write successfully
三、read extend thewhole memory
blhost -u -t 100000 -- read-memory $RAM_Reserved_Start $RAM_Size+4
blhost -u -t 100000 -- read-memory $RAM_Reserved_End $RAM_Size
// kStatusMemoryRangeInvalid
注意:给QSPI flash供电1.8V,J5
K80的启动:
Bootpin option bit: BOOTPIN_OPT = 1的前提下:
BOOTSREC_SEL(0x40D bit[7:6])决定启动源:
Operate to QSPI, but without configure
0x68000000是K80 QSPI的base address
blhost -u -- read-memory 0x68000000 8
blhost -u -- write-memory 0x68000000 "{{112233}}"
blhost -u -- fill-memory 0x68000000 10 0xfe byte
blhost -u -- flash-erase-region 0x68000000 1024
return value: QSPI not configured
配置文件在release包中的apps\QCBGenerator\binaries内
blhost -p com43 -- write-memory 0x20000000qspi_cfg_block_quad.bin
blhost -p com43 -- configure-quadspi 1 0x20000000
blhost -p com43 -- read-memory 0x68000000 0x100
blhost -p com43 -- write-memory 0x68000000 "{{112233}}"
blhost -p com43 -- flash-erase-region 0x68000000 1024
all the commands should be executed successfully
向QSPI flash不一样地址写入不一样长度字节的数据,而后读取出来看是否写成功
8bit对齐,0x100
Get-property 25 1能够查看qspi flash相关的信息,包括QSPI flash的大小,sector的大小等
blhost -u -- flash-erase-region 0x68000000 0x10000
blhost -t 100000 -u -- write-memory 0x68000000 {{00}}
blhost -t 100000 -u -- write-memory 0x68000100 {{0000}}
blhost -t 100000 -u -- write-memory 0x68000200 {{00000000}}
blhost -t 100000 -u -- write-memory 0x68000300 {{0000000000000000}}
blhost -t 100000 -u -- write-memory 0x687ff000 {{00}}
blhost -t 100000 -u -- write-memory 0x687ff100 {{0000}}
blhost -t 100000 -u -- write-memory 0x687ff200 {{00000000}}
blhost -t 100000 -u -- write-memory 0x687ff300 {{0000000000000000}}
blhost -t 100000 -u -- read-memory 0x687ff300 16
Xiaotian上面的case里面使用的.dat文件是定义一个sector为256KB(0x40000)
blhost -t 100000 -u -- write-memory 0x68000000 1_sector.dat
blhost -t 100000 -u -- read-memory 0x68000000 16
blhost -t 100000 - u -- read-memory 0x6803ff00 16
blhost -t 100000 - u -- write-memory 0x68040000 "qspi_two_sector.dat"
blhost -t 100000 - u -- read-memory 0x68040000 16
blhost -t 100000 - u -- read-memory 0x680bff00 16
blhost -t 100000 -u -- write-memory 0x68700000 "qspi_one_sector.dat"
blhost -t 100000 -u -- read-memory 0x68700000 16
blhost -t 100000 -u -- read-memory 0x687f3ff00 16
blhost -t 100000 -u -- write-memory 0x68740000 "qspi_two_sector.dat"
blhost -t 100000 -u -- read-memory 0x68740000 16
blhost -t 100000 -u -- read-memory 0x687bff00 16
写满QSPI flash一半的空间\所有空间,而后分别在写入空间的先后处读取数据,看写入的内容是否正确
blhost -t 100000 -u -- write-memory 0x68000000 "qspi_one_half.dat"
blhost -t 100000 -u -- read-memory 0x68000000 16
blhost -t 100000 -u -- read-memory 0x683fff00 16
blhost -t 100000 -u -- write-memory 0x68000000 "qspi_full.dat"
blhost -t 100000 -u -- read-memory 0x68000000 16
blhost -t 100000 -u -- read-memory 0x687fff00 16
Get-property 25 1查看QSPI信息
Page对齐
写对齐,分别使用不一样长度的对齐来写数据,结果只有0x100长度对齐的能pass,其他的返回alignment error
blhost -t 100000 -u -- write-memory 0x68000004 "{{00}}"
blhost -t 100000 -u -- write-memory 0x68000008 "{{00}}"
blhost -t 100000 -u -- write-memory 0x68000010 "{{00}}"
blhost -t 100000 -u -- write-memory 0x68000040 "{{00}}"
blhost -t 100000 -u -- write-memory 0x68000080 "{{00}}"
blhost -t 100000 -u -- write-memory 0x68000100 "{{00}}"
Fill相关的操做参照如上write的思想,以下是fill不一样字节长度的数据,分别在能够的QSPI flash的开头跟结尾
blhost -t 100000 -p COMx -- flash-erase-region 0x68000000 0x10000
blhost -t 100000 -p COMx -- flash-erase-region 0x68fe0000 0x10000
blhost -t 100000 -p COMx -- fill-memory 0x68000000 1 0x00 byte
blhost -t 100000 -p COMx -- read-memory 0x68000000 16
blhost -t 100000 -p COMx -- fill-memory 0x68000100 2 0x00 byte
blhost -t 100000 -p COMx -- read-memory 0x68000100 16
blhost -t 100000 -p COMx -- fill-memory 0x68000200 4 0x00 byte
blhost -t 100000 -p COMx -- read-memory 0x68000200 16
blhost -t 100000 -p COMx -- fill-memory 0x68000300 8 0x00 byte
blhost -t 100000 -p COMx -- read-memory 0x68000300 16
blhost -t 100000 -p COMx -- fill-memory 0x68fff100 1 0x00 byte
blhost -t 100000 -p COMx -- read-memory 0x68fff100 16
blhost -t 100000 -p COMx -- fill-memory 0x68fff200 2 0x00 byte
blhost -t 100000 -p COMx -- read-memory 0x68fff200 16
blhost -t 100000 -p COMx -- fill-memory 0x68fff300 4 0x00 byte
blhost -t 100000 -p COMx -- read-memory 0x68fff300 16
blhost -t 100000 -p COMx -- fill-memory 0x68fff400 8 0x00 byte
blhost -t 100000 -p COMx -- read-memory 0x68fff400 16
Erase不一样大小的sector,erase所有\一半QSPI flash
启动的同时配置好QSPI
blhost -p com43 -- write-memory 0x20000000.bin
blhost -p com43 – configure-quadspi 0x20000000
blhost -p com43 -- write-memory 0x400 {{fffffffffffffffffffffffffe80}}
blhost -p com43 -- write-memory 0x68000000 qspi.bin
Led 下载到QSPI中,而后从QSPI启动
此LED demo为特制,代码分布于flash跟QSPI flash中
使用receive-sbfile命令时,加长延时.
Blhost –t 500000
由于使用sbfile配置QCB的时候,若是有涉及到对QCB的操做的话,延时不够板子会无响应
# The sources block assigns file names to identifiers
sources {
# SREC File path
mySrecFile = "led_demo_fpga_qspi.srec";
# QCB file path
qspiConfigBlock = "qcb_S25FL129P01.bin";
}
section (0) {
erase 0..0x4000;
load qspiConfigBlock >0x20000000;
enable qspi 0x20000000;
erase 0x68000000..0x68004000;
load qspiConfigBlock > 0x68000000;
load mySrecFile;
reset;
}
代码分布于QSPI跟QSPI alias memory中
验证是否可以从alias memory中启动成功
sources {
# SREC File path
mySrecFile = "led_demo_fpga_alias_40001000.srec";
# QCB file path
qspiConfigBlock = "qcb_S25FL129P01.bin";
}
section (0) {
erase 0..0x4000;
load qspiConfigBlock >0x20000000;
enable qspi 0x20000000;
erase 0x4000000..0x4004000;
load qspiConfigBlock > 0x68000000;
load mySrecFile;
reset;
}
1. Elftosb.exe
Elftosb其实是一个加密工具,用elftosb.exe生成后缀名为.sb 的文件,而后在blhost工具中经过receive-sb-file command 下载到内存中生成.
2..bd文件
bd是"boot descriptor"缩写,该文件是一个command file,具备这种功能的文件咱们以.bd做为其后缀名。
2.二者之间的关系
.bd文件做为一个command file来告诉elftosb工具如何将.bd文件中的内容转换成相应的sb file。
二. bd文件内容模块的介绍
咱们将.bd文件中的内容分红如下几个大的模块:options ,constants ,sources and sections
这几个部分均可以按照必定的规则进行组合生成可执行的.bd文件。每一个模块都以该模块的关键字来引入,而且其内容用{}来包含。以下面的option模块所示:
#define the options block
options{
#content goes here
}
1.options
该模块与产生ELF文件的工具备关系,工具箱有"GHS","GCC","GUN"和"ADS",咱们通常在options模块中不添加任何内容而采用其默认的生成工具"GHS".
2.constants
该模块中可包含有0个或多个常量定义语句,每条语句都以分号结尾。假设有一个myBinFile 文件,我能够经过这个模块去得到该文件的大小:
constants{
bufsize = sizeof(myBinFile);
}
section (0)
{
if bufsize < 128
{
error"Buffer size is too small!";
}
else
{
info"Buffer size is acceptable";
}
}
3.sources
该模块是用来讲明要加载的源文件的路径,对于led_demo_FRDM-KL25Z_8000.bin文件来讲,有两种获取源文件的方法。
第一种方法:
Sources{
myBinFile = "led_demo_FRDM-KL25Z_8000.bin";
}
不然执行
Sources{
myBinFile = "../app_demo/led_demo_FRDM-KL25Z.bin";
}
第二种方法:
Sources{
demo =extern(0);
}
Cmd line:
elftosb.exe -V -c demo_L5K_flash_call.bd -o demo_L5K_flash_erase.sb led_demo_FRDM-KL25Z_8000.bin
4.sections
该模块能够说是四大模块中最重要的一个模块,整个源文件的加载也是在该模块中实现。在该模块中能够执行包括erase,load,from ,jump ,call等各类语句,在这里主要讲一下load语句。
load语句目前支持的文件格式有.bin 文件.out文件和.elf文件。
下面是针对于KL25Z4和L5K板子加载的两种文件的
加载.bin的文件
section (0) {
erase all;
load myBinFile > 0x8000;
jump 0x83e1;
}
MMCAU或者LTC只会对SB file加密,即生成加密的SB file。。可是对SB内的内容不会加密。
好比在BD里面加入APP,APP仍是明文APP附着在生成的SB file里面
可是OTFAD,里面会用到encrypt()这个段,这里面引入了APP。。此时的APP就是用blob生成的密文APP附着在SB file里面
AES几种加密模式:
http://www.cnblogs.com/starwolf/p/3365834.html
MMCAU是一个用于算法加速的模块。。
AES算法须要BCA指定一个地址存储。。
因此
Memory-Mapped Cryptographic Acceleration Unit(内存映射加密加速单元)
MMCAU是对加密完成后的SB file进行解密。
经过CAU硬件加速模块,进行软件解密。
使用的算法是AES
MMCAU算法在BCA中的配置:MMCAU算法能够被加载到any accessible RAM或flash中。不是每一个MMCAU配置bin文件拿到手就能用的,咱们须要在BCA里配置相应的位,即要告诉bootloader 有一个 pointer指向一个MMCAU设置结构。这边要谈到该bin文件头20个字节的数据,由于这20个字节数据有特殊的意义,不可缺乏。
咱们把这头20个字节数据分为5段。
MMCAU的bin文件,有两种:cm0p Bin和cm4 Bin文件,区别MMCAU_OFFSET_cm0p_aes_init_start =0x14
MMCAU_OFFSET_cm0p_aes_encrypt_start =0xB8
MMCAU_OFFSET_cm0p_aes_decrypt_start =0x200
MMCAU_OFFSET_cm4_aes_init_start =0x14
MMCAU_OFFSET_cm4_aes_encrypt_start =0xEA
MMCAU_OFFSET_cm4_aes_decrypt_start =0x29A
如上3-5填写的地址是须要加上BCA里面指定的地址。
步骤:
Test point:
1. Erase the whole flash
2. Update the BCA data. Make sure the tag is 'kcfg' and the mmcauConfigPointer is the located mmacu data address (0x1000).
3. Reset the target so that the BCA can be used.
4. Modify the MMCAU_DATA_cmXX.bin.
5. Set the mmcau data in flash and make sure the address is at least 4 bytes alignment.
6. Create simple.bd file, the contents are as follows.
options{}
section (0) {
load "hello sb loader world!"> 0x2000;
load {{ 05 20 00 bf 40 1e fc d1 70 47 }} > 0x3000;
}
Note: "05 20 00 bf 40 1e fc d1 70 47" is the opcodes of a tiny function.
7. Create generate_simple.bat file, the contents are as follows. (Please make sure the elftosb.exe exists in the current directory)
elftosb.exe -z -V -c simple.bd -o simple.sb
8. Double click generate_simple.bat file to generate simple.sb file.
9. Send the sb file to the target and it will return success.
10. Read data from memory address, and check if the simple string ("hello sb loader world!") is written in.
11. Call the loaded tiny function and blhost will return success.
blhost -u -t 50000 -- flash-erase-all-unsecure
blhost -u -t 50000 -- write-memory 0x3c0 "{{6B 63 66 67}}"
blhost -u -t 50000 -- write-memory 0x3E0 "{{00 10 00 00}}"
blhost -u -t 50000 -- reset
blhost -u -t 50000 -- write-memory 0x1000 XX.BIN
Note: choose the correct mmcau data file according to the architecture of the ARM core (CM0p, CM4, ...)
blhost -u -t 50000 -- receive-sb-file simple.sb
blhost -u -t 50000 -- read-memory 0x2000 22
blhost -u -t 50000 -- call 0x3001 0
Sb file加密时使用的密文在receive-sb-file以前须要将密文写到Index 0x30处.
若是Index 0x30开始的地方没有写入key,receive-file将报错. kStatusRomLdrKeyNotFound
blhost -u -t 50000 -- flash-erase-all-unsecure
blhost -u -t 50000 -- write-memory 0x3c0 "{{6B 63 66 67}}"
blhost -u -t 50000 -- write-memory 0x3E0 "{{00 20 00 00}}"
blhost -u -t 50000 -- reset
blhost -u -t 50000 -- write-memory 0x2000 mmcau_cm4.bin
blhost -u -t 50000 -- write-memory 0x3c0 bca_mmcau_cm4.bin
//若是使用带BCA的bin文件,则上面bca的配置所有不须要,可是地址写到0x3c0处
elftosb.exe -k key.txt -V -c simple.bd -o simple.sb
blhost -u -t 50000 -- flash-program-once 0x30 4 11111111
blhost -u -t 50000 -- flash-program-once 0x31 4 11111111
blhost -u -t 50000 -- flash-program-once 0x32 4 11111111
blhost -u -t 50000 -- flash-program-once 0x33 4 11111111
blhost -u -t 50000 -- receive-sb-file case.sb
blhost -u -t 50000 -- read-memory 0x2000 22
blhost -u -t 50000 -- call 0x3001 0
以下图所示,红色分隔符里面的内容分别是:
typedef struct mmcau_function_info
{
uint32_t tag; // 'kcau' = 0x
uint32_t length; // number of bytes to copy, this number will be copied from the start of aes_init
uint32_t aes_init_start;
uint32_t aes_encrypt_start;
uint32_t aes_decrypt_start;
} mmcau_function_info_t;
当BCA里面的指定了MMCAU的pointer以后,对应的init_start、encrypt_start、decrypt_start须要加上BCA里面指定的地址
blhost -u -t 50000 -- flash-erase-all-unsecure
blhost -u -t 50000 -- write-memory 0x3c0 "{{6B 63 66 67}}"
blhost -u -t 50000 -- write-memory 0x3E0 "{{00 20 00 00}}"
blhost -u -t 50000 – reset
blhost -u -t 50000 -- write-memory 0x2000 mmcau_cm4.bin
blhost -u -t 50000 -- flash-program-once 0x30 4 11111111
blhost -u -t 50000 -- flash-program-once 0x31 4 11111111
blhost -u -t 50000 -- flash-program-once 0x32 4 11111111
blhost -u -t 50000 -- flash-program-once 0x33 4 11111111
blhost -u -t 50000 -- receive-sb-file case.sb
LTC是硬件解密。使用的也是AES解密,与MMCAU不一样的是,他是经过硬件完成的。
因此不须要算法代码,也就是MMCAU.bin
测试步骤跟MMCAU同样。不须要配置BCA跟烧写MMCAU.bin
使用SB file的方式进行image的烧写。。由于image的vector table出在internal flash中,boot data处于QSPI中。若是使用blhost的方式去烧写,很差作。
使用key blob对QSPI image加密后,SB file中image就被加密了。Elftosb这个工具是用来作加密的
Kblob在SB中
0x20-0x23 处的kek对key blob加密。
以下的写法就是将加密的keyblob写到BCA中指定的key blob地址。
Encrypt(0)中就是将使用keyblob加密的QSPI image写到internalflash跟QSPI flash中
OTFAD是对QSPI进行解密的硬件,使用keyblob变运行边解密
Keywrap (0) {
load {{000102030405060708090a0b0c0d0e0f}} > 0x1000;
}
SB中这段操做是使用kek对blob加密,而后加密后的blob写入0x1000.0x1000须要在BCA中指定
若是须要对SB 加密的话,还能够对SB加密一次。。具体方式参照MMCAU或者LTC
当更新firmware的时候,忽然断电或者板子连线出了问题的时候。致使firmware的损坏或者设备没响应。reliable update的存在就是为了解决这个问题。
Reliable update将设备的memory分为两块:main application region & backup application region。只有备份应用区能够用来更新image。一旦备份应用区里面有image的更新,bootloader会检测image的有效性跟完整性,而后将image拷贝到主应用区。
Reliable update的触发有两种方式:
Reliable update的实现有两种方式:
二者很明显的区别就是
软件实现须要将backup application region里面的东西拷贝到main application region
硬件实现是将bootloader跟image分别在main跟backup region里面占用一部分,
[5/12/2016 2:39 PM] Jie Heng:
测试boot ROM而且是 HW reliable update话,image size要大于0x410,可是CRC计算长度是任意的
除了这种类型的测试外,其余测试 image size没有规定,不须要考虑flash config
[5/12/2016 2:43 PM] Jie Heng:
只要是测试 SW reliable update,CRC计算长度必须包含BCA
总结下来,
HW reliable:
一、ROM上面app size要大于0x410,其余类型app size 无论。
二、CRC计算的长度计算image前八个字节
SW reliable:
一、Image size没规定
二、CRC计算长度须要包含BCA
static uint32_t get_application_base(specified_application_type_t applicationType)
目的是获得app的存储地址
一、reset后init函数里面使用:
kReliableUpdateOption_Normal = 0
二、Blhost执行reliable update命令:
kSpecifiedApplicationType_Backup = 1
一、ROM: PFlash_size/2
二、FLASH: PFlash_size/2 + APP_VECTOR_TABLE_ADDRESS
三、ROM跟FLASH宏都没有打开:定义于bootloader_config.h中的BL_BACKUP_APP_START
PPT:
Reliable update
类型:硬件(须要硬件支持)/ 软件
媒介:flash/ROM
执行手段:重启/命令
可能的配对方式2*2*2 = 8种
Backup address of reliable update
HW |
SW |
|||
Flash |
ROM |
Flash |
ROM |
|
Reset |
Flash size/2 + app vector address |
Flash size/2 |
BL_BACKUP_APP_START |
Flash size/2 |
Command |
Flash size/2 + app vector address |
Flash size/2 |
Address by command |
Address by command |
命令方式执行reliable后面跟的地址
软件叫作:
Backup app address
硬件叫作
Indicator address
Reliable update代码详解:
Test point:
1. Inactive
设置错误的BCA
2 invalid
CRC start address 全为FF
3 update success
正确的APP
4 reset method to execute reliable update
正确的BCA存放到代码里面指定的地址,而后reset
Backup address能够参考如上的表格
A、static bool is_reliable_update_active(uint32_t backupApplicationBase):
从app的存储地址获得APP的PC跟BCA的tag
知足以下条件则pass:
不然返回:
kStatus_ReliableUpdateInacive
B、static bool is_specified_application_valid(uint32_t applicationBase)
这个函数PASS的两个条件:
不然返回:
kStatus_ReliableUpdateBackupApplicationInvalid
C、status_t software_reliable_update(uint32_t backupApplicationBase)
get_result_after_copying_application(backupApplicationBase, mainApplicationBase, applicationSizeInByte);
一、擦除:起始地址为main flash app address,长度为:application count?
二、复制backup application到main flash中
kStatus_ReliableUpdateBackupBootloaderNotReady
CRC 起始地址修正为reliable update后面的地址,重载BCA,对app进行CRC校验
擦除:backup flash里面的app
return (updateResult) ? kStatus_ReliableUpdateSuccess : kStatus_ReliableUpdateFail;
Blhost -p com43 -- flash-erase-all-unsecure
Blhost -p com43 -- reset
Blhost -p com43 -- get-property 0x1a
Blhost -p com43 -- reliable-update 0xa000
Test point:
1. Swap system not ready
未进行过reliable update的状况下,在backup区放置一个符合要求的app,reset后使用get-property 0x1a,查看状态
2 still in main region
擦干净backup区,在app address处写入一个符合要求的app
3 inactive
错误的BCA,存放到backup区,进行reliable update
4 invalid
CRC起始地址配置为全ff
5 success
正确的APP放到backup区
6 indicator address invalid
成功进行过reliable update后,使用不同的indicator address
7 reset method to execute reliable update
正确进行过reliable update后,将app address处的demo擦除,在backup区写入app,而后reset
A、reset方式
一、判断main flash中是否存在app,若存在app,则中断update,跳转到app
二、从IFR获得indicator address(第一次硬件reliable update必须使用命令的方式将值传送到IFR中)
而后执行后续操做
B、Blhost command方式
一、从blhost 命令获得indicator address
A、static bool is_reliable_update_active(uint32_t backupApplicationBase):
从app的存储地址获得APP的PC跟BCA的tag
知足以下条件则pass:
不然返回:
update_reliable_update_status(kStatus_ReliableUpdateInacive);
B、static bool is_specified_application_valid(uint32_t applicationBase)
这个函数PASS的两个条件:
不然返回:
update_reliable_update_status(kStatus_ReliableUpdateBackupApplicationInvalid);
C、status_t hardware_reliable_update(uint32_t swapIndicatorAddress)
static bool is_backup_bootloader_valid(void)
检查backup bootloader的CRC校验值跟main flash bootloader的CRC校验值是否相等
get_result_after_copying_application(mainBootloaderBase, backupBootloaderBase, bootloaderSizeInByte);
一、擦除:backup bootloader
二、复制main bootloader 到backup bootloader空间
三、重载BCA,对backup bootloader进行CRC校验
kStatus_ReliableUpdateBackupBootloaderNotReady
D、FLASH_Swap(&g_bootloaderContext.flashState, swapIndicatorAddress, kFLASH_SwapFunctionOptionEnable);
Swap the system
FLASH_SwapControl(config, address, kFLASH_SwapControlOptionReportStatus, &returnInfo);
一、0x10对齐
二、swap indicator在main flash区域,且不能位于flash 配置区,即0x400-0x40f
若是如上的两点不知足,返回:
kStatus_ReliableUpdateSwapIndicatorAddressInvalid
swap成功或者失败:
return (updateResult) ? kStatus_ReliableUpdateSuccess : kStatus_ReliableUpdateFail;
#if BL_TARGET_FLASH
status_t hardware_reliable_update(uint32_t swapIndicatorAddress)
is_backup_bootloader_valid()
CRC运算 获得从flash 0地址到app vector table处的校验值
CRC运算获得从flash size/2地址到flash size/2 + app vector table处的校验值。
二者若相等,则往下跑
几个关键的地址:
Back_up_app_address = get_application_base
Bl_main.c里,若是宏BL_FEATURE_RELIABLE_UPDATE = 1,则开启reliable_update功能
#if BL_FEATURE_RELIABLE_UPDATE
bootloader_reliable_update_as_requested(kReliableUpdateOption_Normal, 0);
#endif // BL_FEATURE_RELIABLE_UPDATE
接着往下看:若是这个宏打开,则执行硬件reliable update
#if BL_IS_HARDWARE_SWAP_ENABLED
#define BL_IS_HARDWARE_SWAP_ENABLED (BL_FEATURE_HARDWARE_SWAP_UPDATE && FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP)
接下来进行有效性的检测,所谓有效性,就是CRC校验的count不能大于flash_size/2 – app_vector_table_address。
函数以下:
static bool is_specified_application_valid(uint32_t applicationBase)
如上这些步骤pass后,会返回一个状态
具体的测试case参照kibble自动化测试case,我已经写好测试脚本了。
Bootloader_config.h里面对应的宏打开:
#define BL_FEATURE_RELIABLE_UPDATE (1)
#define BL_FEATURE_HARDWARE_SWAP_UPDATE (1)
#define FSL_FEATURE_FLASH_HAS_PFLASH_BLOCK_SWAP (1)
使用flashtool工具配置app的bca的tag\crc
Step 2: Configure the BCA of backup application by KinetisFlash Tool:
2-1. Enable the tag of BCA
2-2. Enable Crc Check and set the Image Address 0x0
2-3. Save the BCA configuration to app demo.
将app下载到backup区域
Step 3: Load the saved demo to PFlash at 0x10a000.
Step 4: Run the new Blhost to reliable update
reliabe-update 0xffc00 (from 0xB000 to 0x100000 with 0x10 aligned)