From 5a1c9280943e4a7e107d642288cb9a6f2528bf84 Mon Sep 17 00:00:00 2001 From: Chimstaz Date: Sat, 10 Nov 2018 18:31:07 +0100 Subject: [PATCH 1/2] Return error from stm32f4_program Now error code from stm32f4_program function has meaning and could be send back to user. --- .../wakaama_client/objects/object_target.h | 2 +- Inc/cortexm/stm32/stm32f4.h | 11 ++++++++++ Inc/target.h | 4 +++- Src/cortexm/stm32/stm32f4.c | 22 +++++++++++-------- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/Inc/communication/wakaama_client/objects/object_target.h b/Inc/communication/wakaama_client/objects/object_target.h index 8ec9353..c78d770 100644 --- a/Inc/communication/wakaama_client/objects/object_target.h +++ b/Inc/communication/wakaama_client/objects/object_target.h @@ -26,7 +26,7 @@ typedef struct _target_instance_ uint32_t firmware_version; char * binary_filename; uint8_t download_progress; - uint8_t flash_error; + uint16_t flash_error; TARGET_t *target; } target_instance_t; diff --git a/Inc/cortexm/stm32/stm32f4.h b/Inc/cortexm/stm32/stm32f4.h index 98fe455..3e27b25 100644 --- a/Inc/cortexm/stm32/stm32f4.h +++ b/Inc/cortexm/stm32/stm32f4.h @@ -42,6 +42,17 @@ #define STM32F4_SIZE_OF_ONE_WRITE 0x1000 +/* + * flash errors returned to flash_target_task + * 0x0 - 0x1000 - reserved for target (we can use this pool here) + * bit 9 (0x200) - error while flash erasing. [8..0] represent FLASH_SR[8..0] + * bit 10 (0x400) - error while flash writing. [8..0] represent FLASH_SR[8..0] + */ +#define STM32F4_ERASE_ERROR_BIT 0x200 +#define STM32F4_FLASH_ERROR_BIT 0x400 +#define STM32F4_ERASE_NEVER_END 0x800 +#define STM32F4_ERROR_ON_FLASH_WRITE_SETUP 0x801 + typedef struct CORTEXM_s CORTEXM_t; typedef struct STM32F4_PRIV_s { diff --git a/Inc/target.h b/Inc/target.h index 19c38b9..4239eeb 100644 --- a/Inc/target.h +++ b/Inc/target.h @@ -9,7 +9,9 @@ #define FLASH_ERROR 2 #define FLASH_COMPLETED 3 -#define USB_FS_ERROR 1 +// Flash Error status +// 0x0 -- 0x1000 reserved for target +#define USB_FS_ERROR 0x1001 // TODO: define real functions with real arguments typedef struct TARGET_OPS_s { diff --git a/Src/cortexm/stm32/stm32f4.c b/Src/cortexm/stm32/stm32f4.c index 6a66290..dbb9e1f 100644 --- a/Src/cortexm/stm32/stm32f4.c +++ b/Src/cortexm/stm32/stm32f4.c @@ -69,7 +69,7 @@ static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv) if(priv->cortex->ops->check_error(priv->cortex->priv)) { // TODO: handle error printf("Error while waiting for erase end\n"); - return 1; + return STM32F4_ERASE_NEVER_END; } } @@ -78,7 +78,7 @@ static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv) if ((sr & STM32F4_SR_ERROR_MASK) || !(sr & STM32F4_SR_EOP)) { // TODO: handle error printf("Error after erase 0x%x\n", sr); - return 1; + return sr | STM32F4_ERASE_ERROR_BIT; } return 0; } @@ -100,7 +100,7 @@ static int stm32f4_flash_write(STM32F4_PRIV_t *priv, uint32_t dest, const uint32 if(priv->cortex->ops->check_error(priv->cortex->priv)) { // TODO: handle error printf("ERROR: Filed to setup write operation\n"); - return 1; + return STM32F4_ERROR_ON_FLASH_WRITE_SETUP; } /* Execute the stub */ @@ -115,7 +115,7 @@ static int stm32f4_flash_write(STM32F4_PRIV_t *priv, uint32_t dest, const uint32 if (sr & STM32F4_SR_ERROR_MASK) { // TODO: handle error printf("ERROR: writing ended with error 0x%x\n", sr); - return 1; + return sr | STM32F4_FLASH_ERROR_BIT; } return 0; @@ -128,14 +128,16 @@ static int stm32f4_program(void *priv_void, FIL *file) uint32_t addr = 0x8000000; // start of flash memory uint32_t *data = pvPortMalloc(STM32F4_SIZE_OF_ONE_WRITE/sizeof(uint32_t)); STM32F4_PRIV_t *priv = priv_void; + uint16_t result; printf("Start flashing STM32F4x\n"); priv->cortex->ops->halt_request(priv->cortex->priv); stm32f4_flash_unlock(priv); - if(stm32f4_erase_all_flash(priv)) { + result = stm32f4_erase_all_flash(priv); + if(result) { vPortFree(data); - return 1; + return result; } do { @@ -151,15 +153,17 @@ static int stm32f4_program(void *priv_void, FIL *file) // add modified bytes to bytes that will be written br++; br <<= 2; - if(stm32f4_flash_write(priv, addr, data, br)) { + result = stm32f4_flash_write(priv, addr, data, br); + if(result) { vPortFree(data); - return 1; + return result; } // Unaligned read is always smaller then SIZE_OF_ONE_WRITE. // This is EOF so we have done here. break; } - if(stm32f4_flash_write(priv, addr, data, br)) { + result = stm32f4_flash_write(priv, addr, data, br); + if(result) { vPortFree(data); return 1; } From fdd91c39a470133292294bbb7553e6331eb6350e Mon Sep 17 00:00:00 2001 From: Chimstaz Date: Sat, 10 Nov 2018 22:34:08 +0100 Subject: [PATCH 2/2] Add progress to flash command This patch adds progress to flash command. It will be used in future by Wakaama. For STM32F4xx flash erase progress is counted approximately. When JTAG speed will change or block of data that is writen by one operation there is need to change STM32F4_ERASE_TIME_IN_WRITES define. It may differ on different devices from that family. Additionaly commands 'r' and 'b' are added to UART interface to allow fast check flashing command of red.bin and blue.bin file on first detected target. --- Inc/cortexm/stm32/stm32f4.h | 3 ++- Inc/target.h | 2 +- Src/cortexm/stm32/stm32f4.c | 32 +++++++++++++++++++++++++++++--- Src/fatfs.c | 11 ++++++----- Src/main.c | 20 ++++++++++++++++++++ Src/target.c | 3 ++- 6 files changed, 60 insertions(+), 11 deletions(-) diff --git a/Inc/cortexm/stm32/stm32f4.h b/Inc/cortexm/stm32/stm32f4.h index 3e27b25..0e04fb8 100644 --- a/Inc/cortexm/stm32/stm32f4.h +++ b/Inc/cortexm/stm32/stm32f4.h @@ -40,7 +40,8 @@ #define STM32F4_DBGMCU_IDCODE 0xE0042000 -#define STM32F4_SIZE_OF_ONE_WRITE 0x1000 +#define STM32F4_SIZE_OF_ONE_WRITE 0x1000 +#define STM32F4_ERASE_TIME_IN_WRITES 10 /* * flash errors returned to flash_target_task diff --git a/Inc/target.h b/Inc/target.h index 4239eeb..166f63f 100644 --- a/Inc/target.h +++ b/Inc/target.h @@ -15,7 +15,7 @@ // TODO: define real functions with real arguments typedef struct TARGET_OPS_s { - int (*flash_target)(void *priv, FIL *file); + int (*flash_target)(void *priv, FIL *file, int *progress); void (*reset_target)(void *priv); void (*free_priv)(void *priv); diff --git a/Src/cortexm/stm32/stm32f4.c b/Src/cortexm/stm32/stm32f4.c index dbb9e1f..c5ffe53 100644 --- a/Src/cortexm/stm32/stm32f4.c +++ b/Src/cortexm/stm32/stm32f4.c @@ -55,9 +55,11 @@ static void stm32f4_flash_unlock(STM32F4_PRIV_t *priv) } } -static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv) +static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv, int *progress, int progress_end) { uint16_t sr; + int time = 0; + int progress_step = progress_end/10; printf("Erase Flash\n"); /* Flash mass erase start instruction */ @@ -71,6 +73,16 @@ static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv) printf("Error while waiting for erase end\n"); return STM32F4_ERASE_NEVER_END; } + osDelay(1); + time++; + // after each 100 loops add one to progress, we asume that whole erase will take 1000 loops + if(time > 100) { + time = 0; + if(*progress < progress_end - progress_step) { + *progress += progress_step; + printf("Flash progress %d\n", *progress); + } + } } /* Check for error */ @@ -80,6 +92,9 @@ static int stm32f4_erase_all_flash(STM32F4_PRIV_t *priv) printf("Error after erase 0x%x\n", sr); return sr | STM32F4_ERASE_ERROR_BIT; } + + // End of erase, update progress + *progress = progress_end; return 0; } @@ -121,7 +136,7 @@ static int stm32f4_flash_write(STM32F4_PRIV_t *priv, uint32_t dest, const uint32 return 0; } -static int stm32f4_program(void *priv_void, FIL *file) +static int stm32f4_program(void *priv_void, FIL *file, int *progress) { UINT br; uint8_t unaligned; @@ -130,16 +145,22 @@ static int stm32f4_program(void *priv_void, FIL *file) STM32F4_PRIV_t *priv = priv_void; uint16_t result; + // these variables are only needed to show progress + int number_of_writes = (f_size(file) + STM32F4_SIZE_OF_ONE_WRITE - 1)/STM32F4_SIZE_OF_ONE_WRITE + STM32F4_ERASE_TIME_IN_WRITES; + float progress_as_float = 100 * STM32F4_ERASE_TIME_IN_WRITES/number_of_writes; + float progress_on_one_write = 100.0/number_of_writes; + printf("Start flashing STM32F4x\n"); priv->cortex->ops->halt_request(priv->cortex->priv); stm32f4_flash_unlock(priv); - result = stm32f4_erase_all_flash(priv); + result = stm32f4_erase_all_flash(priv, progress, progress_as_float); if(result) { vPortFree(data); return result; } + do { f_read(file, data, STM32F4_SIZE_OF_ONE_WRITE, &br); printf("flash 0x%x bytes on 0x%lx\n", br, addr); @@ -169,6 +190,10 @@ static int stm32f4_program(void *priv_void, FIL *file) } addr += br; + progress_as_float += progress_on_one_write; + *progress = (int)progress_as_float; + printf("Flash progress %d\n", *progress); + // EOF is when readed less bytes than requested } while(br == STM32F4_SIZE_OF_ONE_WRITE); @@ -177,6 +202,7 @@ static int stm32f4_program(void *priv_void, FIL *file) printf("Device flashed\nReset device\n"); priv->cortex->ops->restart(priv->cortex->priv); + *progress = 100; return 0; } diff --git a/Src/fatfs.c b/Src/fatfs.c index ba6757c..cbdf653 100644 --- a/Src/fatfs.c +++ b/Src/fatfs.c @@ -87,7 +87,7 @@ FRESULT scan_files ( printf("Scan path \"%s\"\n", path); FRESULT res; DIR dir; - int i; + //int i; static FILINFO fno; res = f_opendir(&dir, path); /* Open the directory */ @@ -98,8 +98,8 @@ FRESULT scan_files ( if (fno.fattrib & AM_DIR) { /* It is a directory */ /*i = strlen(path); sprintf(&path[i], "/%s", fno.fname); - res = scan_files(path); /* Enter the directory */ - /*if (res != FR_OK) break; + res = scan_files(path); // Enter the directory + if (res != FR_OK) break; path[i] = 0;*/ } else { /* It is a file. */ printf("%s%s\n\r", path, fno.fname); @@ -131,7 +131,7 @@ void usb_ls() { int usb_open_file(const char *filename, FIL *fp, BYTE mode) { FRESULT result = f_mount(&USBHFatFS, "", 1); if (result == FR_OK) { - char *path = pvPortMalloc(sizeof filename + 4); + char *path = pvPortMalloc(strlen(filename) + 4); sprintf(path, "0:/%s", filename); result = f_open(fp, path, mode); vPortFree(path); @@ -158,7 +158,7 @@ int usb_write(const void *bytes, const char *filename, size_t size) { result = f_mount(&USBHFatFS, "", 1); if (result == FR_OK) { FIL fp; - char *path = pvPortMalloc(sizeof filename + 4); + char *path = pvPortMalloc(strlen(filename) + 4); sprintf(path, "0:/%s", filename); result = f_open(&fp, path, FA_WRITE | FA_OPEN_APPEND); vPortFree(path); @@ -176,6 +176,7 @@ int usb_write(const void *bytes, const char *filename, size_t size) { CHECK_FRESULT(result, "mount failed", -1); } + return 0; } /* USER CODE END Application */ diff --git a/Src/main.c b/Src/main.c index eb31a29..2a6bb45 100644 --- a/Src/main.c +++ b/Src/main.c @@ -58,6 +58,7 @@ #include "wakaama.h" #include "jtag/jtag_scan.h" #include "binary_download.h" +#include "target.h" /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ @@ -363,6 +364,9 @@ void StartDefaultTask(void const * argument) HAL_GPIO_WritePin(USB_GPIO_OUT_GPIO_Port, USB_GPIO_OUT_Pin, GPIO_PIN_SET); BlinkBlue(); char usrInput[2]; + FIL file; + int result; + int progress; /* Infinite loop */ debug_init(&huart3); for(;;) @@ -385,6 +389,22 @@ void StartDefaultTask(void const * argument) usb_write("asd", "temp", 3); } break; + case 'r': + progress = 0; + if (usb_open_file("red.bin", &file, FA_READ) != 0) { + break; + } + target_list.next->ops->flash_target(target_list.next->priv, &file, &progress); + usb_close_file(&file); + break; + case 'b': + progress = 0; + if (usb_open_file("blue.bin", &file, FA_READ) != 0) { + break; + } + target_list.next->ops->flash_target(target_list.next->priv, &file, &progress); + usb_close_file(&file); + break; } } /* USER CODE END 5 */ diff --git a/Src/target.c b/Src/target.c index 51e9355..68eaf2d 100644 --- a/Src/target.c +++ b/Src/target.c @@ -22,6 +22,7 @@ void flash_target_task(void *object) { FIL file; int result; + int progress; result = usb_open_file(target_object->binary_filename, &file, FA_READ); if (result != 0) { @@ -30,7 +31,7 @@ void flash_target_task(void *object) { vTaskDelete(NULL); } - result = target_object->target->ops->flash_target(target_object->target->priv, &file); + result = target_object->target->ops->flash_target(target_object->target->priv, &file, &progress); if (result != 0) { target_object->flash_error = result; target_object->flash_state = FLASH_ERROR;