flash internal: check enforced flash size
parent
d6990728a5
commit
7b90696b6c
|
@ -77,7 +77,7 @@ void main(void)
|
|||
* if the SP is not in this range (e.g. flash has been erased) there is no valid application
|
||||
* the second entry in the vector table is the reset address, corresponding to the application start
|
||||
*/
|
||||
volatile uint32_t* application = &__application_beginning; // get the value of the application address symbol (use a register instead on the stack since the stack pointer will be changed)
|
||||
volatile uint32_t* application = (uint32_t*)&__application_beginning; // get the value of the application address symbol (use a register instead on the stack since the stack pointer will be changed)
|
||||
if (!dfu_force && (((*application)&0xFFFE0000)==0x20000000)) { // application at address seems valid
|
||||
SCB_VTOR = (volatile uint32_t)(application); // set vector table to application vector table (store at the beginning of the application)
|
||||
__asm__ volatile ("MSR msp,%0" : :"r"(*application)); // set stack pointer to address provided in the beginning of the application (loaded into a register first)
|
||||
|
|
10
global.h
10
global.h
|
@ -20,7 +20,7 @@
|
|||
#pragma once
|
||||
|
||||
/** enable debugging functionalities */
|
||||
#define DEBUG false
|
||||
#define DEBUG true
|
||||
|
||||
/** get the length of an array */
|
||||
#define LENGTH(x) (sizeof(x) / sizeof((x)[0]))
|
||||
|
@ -422,11 +422,15 @@
|
|||
/** symbol for beginning of the application
|
||||
* @note this symbol will be provided by the linker script
|
||||
*/
|
||||
extern uint32_t __application_beginning;
|
||||
extern char __application_beginning;
|
||||
/** symbol for end of the application
|
||||
* @note this symbol will be provided by the linker script
|
||||
*/
|
||||
extern uint32_t __application_end;
|
||||
extern char __application_end;
|
||||
/** symbol for end of flash
|
||||
* @note this symbol will be provided by the linker script
|
||||
*/
|
||||
extern char __flash_end;
|
||||
/** flag set when board user button has been pressed/released */
|
||||
extern volatile bool button_flag;
|
||||
/** flag set when user input is available */
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
/** library to read/write internal flash (code)
|
||||
* @file flash_internal.c
|
||||
* @author King Kévin <kingkevin@cuvoodoo.info>
|
||||
* @date 2016
|
||||
* @date 2016-2018
|
||||
* @note peripherals used: none
|
||||
*/
|
||||
/* standard libraries */
|
||||
|
@ -30,20 +30,37 @@
|
|||
#include "flash_internal.h" // flash storage library API
|
||||
#include "global.h" // global definitions
|
||||
|
||||
/** verify if the data is in the internal flash area
|
||||
* @param[in] address start address of the data to read
|
||||
* @param[in] size how much data to read or write, in bytes
|
||||
* @return if the data is in the internal flash area
|
||||
*/
|
||||
static bool flash_internal_range(uint32_t address, size_t size) {
|
||||
if (address>(UINT32_MAX-size)) { // on integer overflow will occur
|
||||
return false;
|
||||
}
|
||||
if (address<FLASH_BASE) { // start address is before the start of the internal flash
|
||||
return false;
|
||||
}
|
||||
if ((uint32_t)&__flash_end>=FLASH_BASE) { // check if the end for the internal flash is enforce by the linker script
|
||||
if ((address+size)>(uint32_t)&__flash_end) { // end address is after the end of the enforced internal flash
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ((address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024)) { // end address is after the end of the advertised flash
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size)
|
||||
{
|
||||
// sanity checks
|
||||
if (address<FLASH_BASE || address>(UINT32_MAX-size) || buffer==NULL || size==0) {
|
||||
if (buffer==NULL || size==0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify if it's in the flash area
|
||||
#if defined(__flash_end)
|
||||
if (address<FLASH_BASE || (address+size)>(uint32_t)&__flash_end)
|
||||
#else
|
||||
if (address<FLASH_BASE || (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024))
|
||||
#endif
|
||||
{
|
||||
if (!flash_internal_range(address, size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -58,17 +75,19 @@ bool flash_internal_read(uint32_t address, uint8_t *buffer, size_t size)
|
|||
bool flash_internal_write(uint32_t address, uint8_t *buffer, size_t size)
|
||||
{
|
||||
// sanity checks
|
||||
if (address<FLASH_BASE || address>(UINT32_MAX-size) || buffer==NULL || size==0 || size%2) {
|
||||
if (buffer==NULL || size==0 || size%2) {
|
||||
return false;
|
||||
}
|
||||
if (!flash_internal_range(address, size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// verify if it's in the flash area
|
||||
#if defined(__flash_end)
|
||||
if (address<FLASH_BASE || (address+size)>(uint32_t)&__flash_end)
|
||||
#else
|
||||
if (address<FLASH_BASE || (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024))
|
||||
#endif
|
||||
{
|
||||
if (address<FLASH_BASE) {
|
||||
return false;
|
||||
} else if ((uint32_t)&__flash_end>=FLASH_BASE && (address+size)>(uint32_t)&__flash_end) {
|
||||
return false;
|
||||
} else if ((uint32_t)&__flash_end<FLASH_BASE && (address+size)>(FLASH_BASE+DESIG_FLASH_SIZE*1024)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -223,12 +223,12 @@ static int usb_dfu_control_request(usbd_device *usbd_dev, struct usb_setup_data
|
|||
// we can only write half words
|
||||
usb_dfu_status = DFU_STATUS_ERR_PROG;
|
||||
usb_dfu_state = STATE_DFU_ERROR;
|
||||
#if defined(__application_end)
|
||||
} else if (flash_pointer+*len>=(uint32_t)&__application_end) {
|
||||
#else
|
||||
} else if (flash_pointer+*len>=(uint32_t)(FLASH_BASE+DESIG_FLASH_SIZE*1024)) {
|
||||
#endif
|
||||
// application data is too large
|
||||
} else if ((uint32_t)&__application_end>=FLASH_BASE && flash_pointer+*len>=(uint32_t)&__application_end) {
|
||||
// application data is exceeding enforced flash size for application
|
||||
usb_dfu_status = DFU_STATUS_ERR_ADDRESS;
|
||||
usb_dfu_state = STATE_DFU_ERROR;
|
||||
} else if ((uint32_t)&__application_end<FLASH_BASE && flash_pointer+*len>=(uint32_t)(FLASH_BASE+DESIG_FLASH_SIZE*1024)) {
|
||||
// application data is exceeding advertised flash size
|
||||
usb_dfu_status = DFU_STATUS_ERR_ADDRESS;
|
||||
usb_dfu_state = STATE_DFU_ERROR;
|
||||
} else {
|
||||
|
|
Loading…
Reference in New Issue