71 lines
4.5 KiB
C
71 lines
4.5 KiB
C
#include "set_boot.h"
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
static uint8_t flash[1024];
|
|
static bool valid, fail_write, fail_verify, fail_invalidate;
|
|
static unsigned erases, activations;
|
|
static bool invalidate(void *u) { (void)u; if(fail_invalidate) return false; valid=false; return true; }
|
|
static bool erase(void *u,uint32_t n) { (void)u; assert(!valid); assert(n<=sizeof(flash)); ++erases; memset(flash,255,sizeof(flash)); return true; }
|
|
static bool write(void *u,uint32_t off,const uint8_t *p,uint16_t n) { (void)u; if(fail_write) return false; memcpy(flash+off,p,n); return true; }
|
|
static bool verify(void *u,uint32_t n,uint32_t crc) { (void)u; return !fail_verify && setp_crc32(flash,n)==crc; }
|
|
static bool commit(void *u,uint32_t n,uint32_t crc) { (void)u; assert(verify(0,n,crc)); valid=true; return true; }
|
|
static void activate(void *u) { (void)u; assert(valid); ++activations; }
|
|
int main(void) {
|
|
setp_boot b;
|
|
const setp_boot_ops ops={invalidate,erase,write,verify,commit,activate};
|
|
uint8_t image[517],p[512]; unsigned i; size_t n;
|
|
setp_fw_begin_t begin={0}; setp_fw_end_t end={0};
|
|
for(i=0;i<sizeof(image);++i) image[i]=(uint8_t)i;
|
|
begin.image_size=sizeof(image); begin.image_crc32=setp_crc32(image,sizeof(image));
|
|
begin.base_address=0x08010000; begin.block_size=256; begin.flags=SETP_FW_FLAG_ERASE_SLOT;
|
|
setp_boot_init(&b,&ops,0,begin.base_address,sizeof(flash));
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_ACTIVATE,0,0)==SETP_STATUS_WRONG_STATE);
|
|
begin.base_address=0x08000000; n=setp_fw_begin_encode(&begin,p,sizeof(p)); valid=true;
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_BEGIN,p,(uint16_t)n)==SETP_STATUS_INVALID_ARGUMENT);
|
|
assert(valid && erases==0);
|
|
begin.base_address=b.base; begin.flags|=SETP_FW_FLAG_RESUME;
|
|
n=setp_fw_begin_encode(&begin,p,sizeof(p));
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_BEGIN,p,(uint16_t)n)==SETP_STATUS_UNSUPPORTED);
|
|
assert(valid && erases==0); begin.flags=SETP_FW_FLAG_ERASE_SLOT;
|
|
n=setp_fw_begin_encode(&begin,p,sizeof(p)); fail_invalidate=true;
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_BEGIN,p,(uint16_t)n)==SETP_STATUS_INTERNAL);
|
|
assert(valid && erases==0); fail_invalidate=false;
|
|
assert(!setp_boot_command(&b,SETP_MSG_FW_BEGIN,p,(uint16_t)n)); assert(!valid);
|
|
n=setp_fw_data_encode(1,0,image,256,p,sizeof(p));
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_DATA,p,(uint16_t)n)==SETP_STATUS_SEQUENCE);
|
|
n=setp_fw_data_encode(0,0,image,256,p,sizeof(p)); p[12]^=1;
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_DATA,p,(uint16_t)n)==SETP_STATUS_CRC);
|
|
assert(b.status.next_offset==0);
|
|
end.image_size=sizeof(image); end.image_crc32=begin.image_crc32;
|
|
n=setp_fw_end_encode(&end,p,sizeof(p));
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_END,p,(uint16_t)n)==SETP_STATUS_SEQUENCE);
|
|
for(i=0;i<sizeof(image);i+=256) {
|
|
uint16_t count=(uint16_t)(sizeof(image)-i); if(count>256) count=256;
|
|
n=setp_fw_data_encode(i,0,image+i,count,p,sizeof(p));
|
|
assert(!setp_boot_command(&b,SETP_MSG_FW_DATA,p,(uint16_t)n));
|
|
}
|
|
assert(!valid); n=setp_fw_end_encode(&end,p,sizeof(p));
|
|
flash[20]^=1;
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_END,p,(uint16_t)n)==SETP_STATUS_VERIFY_FAILED);
|
|
assert(!valid);
|
|
/* A reset loses the session, never promotes a partially written image. */
|
|
setp_boot_init(&b,&ops,0,begin.base_address,sizeof(flash));
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_END,p,(uint16_t)n)==SETP_STATUS_WRONG_STATE);
|
|
n=setp_fw_begin_encode(&begin,p,sizeof(p)); assert(!setp_boot_command(&b,SETP_MSG_FW_BEGIN,p,(uint16_t)n));
|
|
for(i=0;i<sizeof(image);i+=256) {
|
|
uint16_t count=(uint16_t)(sizeof(image)-i); if(count>256) count=256;
|
|
n=setp_fw_data_encode(i,0,image+i,count,p,sizeof(p));
|
|
assert(!setp_boot_command(&b,SETP_MSG_FW_DATA,p,(uint16_t)n));
|
|
}
|
|
n=setp_fw_end_encode(&end,p,sizeof(p)); assert(!setp_boot_command(&b,SETP_MSG_FW_END,p,(uint16_t)n));
|
|
assert(valid && !memcmp(image,flash,sizeof(image)));
|
|
assert(!setp_boot_command(&b,SETP_MSG_FW_ACTIVATE,0,0)); assert(activations==1);
|
|
n=setp_fw_begin_encode(&begin,p,sizeof(p)); assert(!setp_boot_command(&b,SETP_MSG_FW_BEGIN,p,(uint16_t)n));
|
|
fail_write=true; n=setp_fw_data_encode(0,0,image,256,p,sizeof(p));
|
|
assert(setp_boot_command(&b,SETP_MSG_FW_DATA,p,(uint16_t)n)==SETP_STATUS_INTERNAL);
|
|
assert(!valid && b.status.state==SETP_FW_FAILED);
|
|
puts("SET boot: validation, sequence, CRC, readback, interrupted update and Flash failure passed");
|
|
return 0;
|
|
}
|