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)