一、BootLoader的作用:BootLoader是固化在PFlash中的一個程序,其作用可以分為兩部分:boot和load。
(1)boot:MCU上電時首先會運行BootLoader程序(因為它一般位於PFlash最前面的啟動區,接下來會談到啟動區Boot location的概念),BootLoader程序會初始化系統時鍾、看門狗等以保證系統的正常運行,此外還會初始化CAN(也可以是串口、SPI等)以實現和上位機的通信。
(2)load:系統初始化完成后,程序會進入等待狀態,如果在預定時間內沒有接收到上位機的程序下載請求信號(CAN幀),則跳轉並執行MCU內部原有的用戶應用程序(位於PFlash的其他啟動區)。如果在預定時間內接收到來自上位機的程序下載請求信號,則BootLoader程序進入新程序下載狀態。下載過程中,上位機與BootLoader程序之間采用一問一答的方式逐行的下載S19文件(用戶應用程序的可執行文件)並進行解析,得到程序地址和程序數據,從而將每一行程序數據按照程序地址寫入到PFlash中。程序下載完成后,清除RAM,關閉CAN等BootLoader用到的外設,跳轉到新的用戶應用程序並開始執行。
二、Boot location的概念:Boot location就是每次MCU復位后運行BAM(Boot Assist Module)時尋找合法復位配置半字RCHW(Reset Configuration Harf-Word)和應用程序開始地址(Application Start Address,也可以叫做應用程序復位向量地址(Reset Vector)的區域。復位后CPU將從Boot location0~7依次查找由正確Boot_ID--0x5A組成的合法復位配置半字和應用程序開始地址,從而執行用戶應用程序。MPC5744P有8個Boot location,在Flash Memory Map中標明了哪些block可以作為Boot location,如下圖:
Boot location的組成如下圖所示:
Boot location的起始位置是復位配置半字(RCHW),其結構如下所示。
只有設置了真確的BootID,該Boot location才被識別為可啟動的,如BootLoader程序和用戶應用程序生成的S19文件:
在BootLoader程序的S19文件第二行中,0x00F98000為Boot location_0的起始地址,也就是RCHW的地址,其中存放的數據為0x01_5A,RCHW的VLE位置1,BOOT_ID為0x5A,即配置該Boot location為可啟動的。reserve的16-31位默認為0x00
從用戶應用程序的S19文件第三行可以看到,0x00FA0004為用戶應用程序開始地址(應用程序復位向量地址),其中記錄的數據0x0100000為應用程序的復位函數地址,也就是應用程序真正開始執行的地址。因此,一般用如下方法實現到用戶應用程序的跳轉:
#define APP_StartAddr (*(uint32_t*)0x00FA0004) (*(void (*)(void))(APP_StartAddr))();
三、BootLoader程序和用戶應用程序App在PFlash中的位置關系(Flash分配)
對BootLoader程序和用戶應用程序的 link_file做如下設置:
MEMORY //BootLoader { /*16 KB low flash memory block 2 (boot location 0) from 0x00F98000 to 0x00F9BFFF*/ /*16 KB low flash memory block 3 (boot location 1) from 0x00F9C000 to 0x00F9FFFF*/ /* use the low flash memory block 2 and 3(32KB in total) as bootloader area */ flash_rchw : org = 0x00F98000, len = 0x4 cpu0_reset_vec : org = 0x00F98004, len = 0x4 m_text : org = 0x00F99000, len = 28K /*code flash for bootloader interrupt vector table, startup and boot codes*/ m_data : org = 0x40000000, len = 384K /*system SRAM*/ local_dmem : org = 0x50800000, len = 64K /*CPU core data tightly coupled memory*/ }
MEMORY //User App { flash_rchw : org = 0x00FA0000, len = 0x4 cpu0_reset_vec : org = 0x00FA0004, len = 0x4 m_text : org = 0x1000000, len = 2048K m_data : org = 0x40000000, len = 384K local_dmem : org = 0x50800000, len = 64K }
則BootLoader和App的在PFlash中的關系如下:
四、S19文件結構:
五、數據對齊問題:
例程中的對齊函數主體及注釋如下:
stafno = (srcd_t->addr&0x7)>>1; /* number of uint16_t need to be pre-staffed */ //if addr is not a multiple of 8-Bytes, get the surplus bytes then >>1 srcd_t->addr &= 0xFFFFFFF8; /* align data base address at 4W */ //about why >>1(divided by 2 regardless odd num addr): maybe there isn't odd address if(stafno) { for(i=srcd_t->dtlen; i>0; i--) srcd_t->data[i+stafno-1] = srcd_t->data[i-1]; // move forward data in number of stafno srcd_t->dtlen += stafno; // update dtlen while(stafno--) srcd_t->data[stafno] = 0xFFFF; // pre-staff 0xFFFF } while((srcd_t->dtlen&0x000003)!=0) // need to append post-staffing uint16_t //if data num is a multiple of 4(each data is uint_16, so it's a judge of 64bits - 8bytes) srcd_t->data[srcd_t->dtlen++] = 0xFFFF; //if not enough 4*uint_16 - 8bytes, padding with 0xFFFF behind data's tail } // conclusion: address is aligned with 8bytes by &0xFFFFFFF8, but data field will not move accordingly, // it just padding with 0xFF in the front of array, so as to accord with origin address(0x0004) correctly // // address data(uint16) address data(uint16) // |0x0000| |0x0000|<-- 0xFF // |0x0002| after |0x0002| 0xFF // |0x0004|<-- 0x55(data[0]) =======>> |0x0004| 0x55 // |0x0006| 0x66 address |0x0006| 0x66 // |0x0008| 0x77 align |0x0008| 0x77 // |0x000A| 0x88 |0x000A| 0x88 // |0x000C| |0x000C| // // note: (1) i guess that 0xFF will not be recognized as a instruction by CPU, so CPU fetch instruction from 0x0000 // but execute from 0x0004 in fact. // (2) and note that the graph above is base on the struct SRecord_t, // so that data[0] is always correspond with base address(SRecord->addr)
其中srcd_t的結構如下:
typedef struct { uint32_t addr; uint32_t dtlen; // num of valid data uint16_t data[20]; } SRecord_t;
另外,關於數據對齊問題,可以參考博文:https://blog.csdn.net/maxlovezyy/article/details/70231804
六、其他:下圖為建立多核工程時的Flash和RAM資源的分配,可以用來參考以加深對程序在內存中的存儲的理解