From c5e7c709e53535bcdfe6c1399aec812953fddf93 Mon Sep 17 00:00:00 2001 From: Maksymilian Wojczuk Date: Sat, 10 Nov 2018 14:23:04 +0100 Subject: [PATCH 1/2] Remote Flashing Added possibility to flash target STM32F4Discovery remotely --- .../wakaama_client/objects/object_target.h | 6 +- Inc/fatfs.h | 2 + Inc/target.h | 10 + Src/communication/binary_download.c | 2 +- .../wakaama_client/objects/object_target.c | 175 ++++++++++++------ Src/fatfs.c | 25 +++ Src/main.c | 3 +- Src/target.c | 37 ++++ 8 files changed, 196 insertions(+), 64 deletions(-) diff --git a/Inc/communication/wakaama_client/objects/object_target.h b/Inc/communication/wakaama_client/objects/object_target.h index 8cfee81..8ec9353 100644 --- a/Inc/communication/wakaama_client/objects/object_target.h +++ b/Inc/communication/wakaama_client/objects/object_target.h @@ -2,6 +2,8 @@ #define __OBJECT_TARGET_H +#include "target.h" + /* * Multiple instance objects can use userdata to store data that will be shared between the different instances. * The lwm2m_object_t object structure - which represent every object of the liblwm2m as seen in the single instance @@ -17,13 +19,15 @@ typedef struct _target_instance_ uint16_t shortID; // matches lwm2m_list_t::id uint8_t flash_state; - uint32_t * target_type; + char * target_type; char * firmware_url; uint8_t download_state; int16_t download_error; uint32_t firmware_version; char * binary_filename; uint8_t download_progress; + uint8_t flash_error; + TARGET_t *target; } target_instance_t; diff --git a/Inc/fatfs.h b/Inc/fatfs.h index 91b370f..a3abaaa 100644 --- a/Inc/fatfs.h +++ b/Inc/fatfs.h @@ -70,6 +70,8 @@ void MX_FATFS_Init(void); /* USER CODE BEGIN Prototypes */ void usb_ls(); +int usb_close_file(FIL *fp); +int usb_open_file(const char *filename, FIL *fp, BYTE mode); int usb_write(const void *bytes, const char *filename, size_t size); /* USER CODE END Prototypes */ #ifdef __cplusplus diff --git a/Inc/target.h b/Inc/target.h index 0d709e7..19c38b9 100644 --- a/Inc/target.h +++ b/Inc/target.h @@ -3,6 +3,14 @@ #include "fatfs.h" +// Flash States +#define NO_FLASH_DATA 0 +#define FLASH_IN_PROGRESS 1 +#define FLASH_ERROR 2 +#define FLASH_COMPLETED 3 + +#define USB_FS_ERROR 1 + // TODO: define real functions with real arguments typedef struct TARGET_OPS_s { int (*flash_target)(void *priv, FIL *file); @@ -19,6 +27,8 @@ typedef struct TARGET_s { } TARGET_t; void register_target(void *priv, TARGET_OPS_t *ops, char *name); +void reset_target_task(void *object); +void flash_target_task(void *object); // Head of targets list extern TARGET_t target_list; diff --git a/Src/communication/binary_download.c b/Src/communication/binary_download.c index 1b9f10f..79fe4ec 100644 --- a/Src/communication/binary_download.c +++ b/Src/communication/binary_download.c @@ -121,6 +121,6 @@ int startDownload(target_instance_t *targetP) { targetP->download_error = NO_ERROR; lwip_close(socket); lwm2m_free(url_str); - vTaskDelete(); + vTaskDelete(NULL); } \ No newline at end of file diff --git a/Src/communication/wakaama_client/objects/object_target.c b/Src/communication/wakaama_client/objects/object_target.c index 4fa73b1..6d1c403 100644 --- a/Src/communication/wakaama_client/objects/object_target.c +++ b/Src/communication/wakaama_client/objects/object_target.c @@ -9,7 +9,7 @@ * Supported Multiple * Name | ID | Operations | Instances | Mandatory | Type | Range | Units | Description | * -----------------|----|------------|-----------|-----------|---------|-------|-------|-------------------------------| - * target_type | 1 | R/W | No | Yes | | | | type of the programmable board| + * target_type | 1 | R/W | No | Yes | string | | | type of the programmable board| * firmware_url | 2 | R/W | No | Yes | string | | | url to the binary | * download_state | 3 | R | No | Yes | integer | 0-255 | | state of the download | * firmware_version | 4 | R | No | Yes | integer | | | timestamp of the latest binary| @@ -17,7 +17,8 @@ * flash_state | 6 | R | No | Yes | integer | 0-100 | % | progress of flashing the board| * reset_target | 7 | E | No | Yes | | | | resets the target | * download_error | 8 | R | No | Yes | integer | | | download error | - * download_progres | 9 | R | No | Yes | integer | 0-100 | % | progress of binary download | + * download_progress| 9 | R | No | Yes | integer | 0-100 | % | progress of binary download | + * flash_error | 10| R | No | Yes | integer | | | flashing error | * */ @@ -81,7 +82,7 @@ static uint8_t target_read(uint16_t instanceId, if (*numDataP == 0) { - *dataArrayP = lwm2m_data_new(7); + *dataArrayP = lwm2m_data_new(8); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; *numDataP = 4; (*dataArrayP)[0].id = 1; @@ -91,6 +92,7 @@ static uint8_t target_read(uint16_t instanceId, (*dataArrayP)[4].id = 6; (*dataArrayP)[5].id = 8; (*dataArrayP)[6].id = 9; + (*dataArrayP)[7].id = 10; } for (i = 0 ; i < *numDataP ; i++) @@ -98,7 +100,7 @@ static uint8_t target_read(uint16_t instanceId, switch ((*dataArrayP)[i].id) { case 1: - lwm2m_data_encode_int(targetP->target_type, *dataArrayP + i); + lwm2m_data_encode_string(targetP->target_type, *dataArrayP + i); break; case 2: lwm2m_data_encode_string(targetP->firmware_url, *dataArrayP + i); @@ -122,6 +124,9 @@ static uint8_t target_read(uint16_t instanceId, case 9: lwm2m_data_encode_int(targetP->download_progress, *dataArrayP + i); break; + case 10: + lwm2m_data_encode_int(targetP->flash_error, *dataArrayP + i); + break; default: return COAP_404_NOT_FOUND; } @@ -140,7 +145,7 @@ static uint8_t target_discover(uint16_t instanceId, // is the server asking for the full object ? if (*numDataP == 0) { - *dataArrayP = lwm2m_data_new(9); + *dataArrayP = lwm2m_data_new(10); if (*dataArrayP == NULL) return COAP_500_INTERNAL_SERVER_ERROR; *numDataP = 8; (*dataArrayP)[0].id = 1; @@ -152,6 +157,7 @@ static uint8_t target_discover(uint16_t instanceId, (*dataArrayP)[6].id = 7; (*dataArrayP)[7].id = 8; (*dataArrayP)[8].id = 9; + (*dataArrayP)[9].id = 10; } else { @@ -168,6 +174,7 @@ static uint8_t target_discover(uint16_t instanceId, case 7: case 8: case 9: + case 10: break; default: return COAP_404_NOT_FOUND; @@ -194,17 +201,6 @@ static uint8_t target_write(uint16_t instanceId, { case 1: return COAP_405_METHOD_NOT_ALLOWED; - /* we do not support writing the target_type yet - { - int64_t value; - - if (1 != lwm2m_data_decode_int(dataArray + i, &value)) - { - return COAP_400_BAD_REQUEST; - } - targetP->target_type = (uint32_t) value; - } - break;*/ case 2: { if (targetP->download_state == DOWNLOAD_IN_PROGRESS) { @@ -240,6 +236,8 @@ static uint8_t target_write(uint16_t instanceId, return COAP_405_METHOD_NOT_ALLOWED; case 9: return COAP_405_METHOD_NOT_ALLOWED; + case 10: + return COAP_405_METHOD_NOT_ALLOWED; default: return COAP_404_NOT_FOUND; } @@ -319,30 +317,38 @@ static uint8_t target_exec(uint16_t instanceId, return COAP_412_PRECONDITION_FAILED; } fprintf(stdout, "\r\n-----------------\r\n" - "Execute flash_target on %hu/%d/%d\r\n" + "Executing flash_target on %hu/%d/%d\r\n" + "Target Name: %s\n" " Parameter (%d bytes):\r\n", - objectP->objID, instanceId, resourceId, length); + objectP->objID, instanceId, resourceId, targetP->target_type, length); prv_output_buffer((uint8_t*)buffer, length); fprintf(stdout, "-----------------\r\n\r\n"); - -// TODO: FLASH TARGET AND Update flash progress + targetP->flash_state=FLASH_IN_PROGRESS; + // targetP->flash_progress=0; + xTaskCreate(flash_target_task, "Flash_Target", 2000, targetP, 2, NULL); return COAP_204_CHANGED; case 6: return COAP_405_METHOD_NOT_ALLOWED; case 7: - if (targetP->flash_state != 100 && targetP->flash_state != 0) { - return COAP_503_SERVICE_UNAVAILABLE; + if (targetP->flash_state == FLASH_IN_PROGRESS) { + return COAP_412_PRECONDITION_FAILED; } fprintf(stdout, "\r\n-----------------\r\n" "Execute reset_target on %hu/%d/%d\r\n" + "Target Name: %s\n" " Parameter (%d bytes):\r\n", - objectP->objID, instanceId, resourceId, length); + objectP->objID, instanceId, resourceId, targetP->target_type, length); prv_output_buffer((uint8_t*)buffer, length); fprintf(stdout, "-----------------\r\n\r\n"); + xTaskCreate(reset_target_task, "ResetTarget", 300, targetP, 2, NULL); // TODO: RESET TARGET return COAP_204_CHANGED; case 8: return COAP_405_METHOD_NOT_ALLOWED; + case 9: + return COAP_405_METHOD_NOT_ALLOWED; + case 10: + return COAP_405_METHOD_NOT_ALLOWED; default: return COAP_404_NOT_FOUND; } @@ -351,48 +357,97 @@ static uint8_t target_exec(uint16_t instanceId, lwm2m_object_t * get_target_object(void) { lwm2m_object_t * targetObj; + targetObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); + + if (NULL != targetObj) { + target_instance_t * targetP; + int i = 1; + memset(targetObj, 0, sizeof(lwm2m_object_t)); + targetObj->objID = 31025; + + TARGET_t *target = target_list.next; + while(target != NULL) { + printf("Add targetObject: %d\n", i); + targetP = (target_instance_t *)lwm2m_malloc(sizeof(target_instance_t)); + if (NULL == targetP) return NULL; + memset(targetP, 0, sizeof(target_instance_t)); + targetP->shortID = i; + targetP->target_type = target->name; + targetP->firmware_url = NULL; + targetP->download_state = NO_DOWNLOAD_DATA; + targetP->firmware_version = 0; + targetP->flash_state = NO_FLASH_DATA; + targetP->download_progress = 0; + targetP->download_error = NO_ERROR; + targetP->binary_filename = lwm2m_malloc(25); + targetP->target = target; + + targetObj->instanceList = LWM2M_LIST_ADD(targetObj->instanceList, targetP); + + target = target->next; + i++; + } - targetObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); - if (NULL != targetObj) - { - int i; - target_instance_t * targetP; + /* + * From a single instance object, two more functions are available. + * - The first one (createFunc) create a new instance and filled it with the provided informations. If an ID is + * provided a check is done for verifying his disponibility, or a new one is generated. + * - The other one (deleteFunc) delete an instance by removing it from the instance list (and freeing the memory + * allocated to it) + */ + targetObj->readFunc = target_read; + targetObj->writeFunc = target_write; + targetObj->executeFunc = target_exec; + targetObj->createFunc = target_create; + targetObj->deleteFunc = target_delete; + targetObj->discoverFunc = target_discover; + } + return targetObj; - memset(targetObj, 0, sizeof(lwm2m_object_t)); - targetObj->objID = 31025; - - targetP = (target_instance_t *)lwm2m_malloc(sizeof(target_instance_t)); - if (NULL == targetP) return NULL; - memset(targetP, 0, sizeof(target_instance_t)); - targetP->shortID = 1; - targetP->target_type = 3124; - targetP->firmware_url = NULL; - targetP->download_state = NO_DOWNLOAD_DATA; - targetP->firmware_version = 0; - targetP->flash_state = 0; - targetP->download_progress = 0; - targetP->download_error = NO_ERROR; - targetP->binary_filename = lwm2m_malloc(25); - - targetObj->instanceList = LWM2M_LIST_ADD(targetObj->instanceList, targetP); - /* - * From a single instance object, two more functions are available. - * - The first one (createFunc) create a new instance and filled it with the provided informations. If an ID is - * provided a check is done for verifying his disponibility, or a new one is generated. - * - The other one (deleteFunc) delete an instance by removing it from the instance list (and freeing the memory - * allocated to it) - */ - targetObj->readFunc = target_read; - targetObj->writeFunc = target_write; - targetObj->executeFunc = target_exec; - targetObj->createFunc = target_create; - targetObj->deleteFunc = target_delete; - targetObj->discoverFunc = target_discover; - } - return targetObj; + + // lwm2m_object_t * targetObj; + // targetObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); + // if (NULL != targetObj) + // { + // target_instance_t * targetP; + + // memset(targetObj, 0, sizeof(lwm2m_object_t)); + + // targetObj->objID = 31025; + + // targetP = (target_instance_t *)lwm2m_malloc(sizeof(target_instance_t)); + // if (NULL == targetP) return NULL; + // memset(targetP, 0, sizeof(target_instance_t)); + // targetP->shortID = 1; + // targetP->target_type = "STM32"; + // targetP->firmware_url = NULL; + // targetP->download_state = NO_DOWNLOAD_DATA; + // targetP->firmware_version = 0; + // targetP->flash_state = 0; + // targetP->download_progress = 0; + // targetP->download_error = NO_ERROR; + // targetP->binary_filename = lwm2m_malloc(25); + + // targetObj->instanceList = LWM2M_LIST_ADD(targetObj->instanceList, targetP); + // /* + // * From a single instance object, two more functions are available. + // * - The first one (createFunc) create a new instance and filled it with the provided informations. If an ID is + // * provided a check is done for verifying his disponibility, or a new one is generated. + // * - The other one (deleteFunc) delete an instance by removing it from the instance list (and freeing the memory + // * allocated to it) + // */ + // targetObj->readFunc = target_read; + // targetObj->writeFunc = target_write; + // targetObj->executeFunc = target_exec; + // targetObj->createFunc = target_create; + // targetObj->deleteFunc = target_delete; + // targetObj->discoverFunc = target_discover; + // } + + // return targetObj; } void free_target_object(lwm2m_object_t * object) diff --git a/Src/fatfs.c b/Src/fatfs.c index a389bef..ba6757c 100644 --- a/Src/fatfs.c +++ b/Src/fatfs.c @@ -127,6 +127,31 @@ void usb_ls() { return (er); \ } + +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); + sprintf(path, "0:/%s", filename); + result = f_open(fp, path, mode); + vPortFree(path); + if(result != FR_OK) { + f_mount(NULL, "", 0); + } + CHECK_FRESULT(result, "open failed", -1); + } else { + CHECK_FRESULT(result, "mount failed", -1); + } + return 0; +} + +int usb_close_file(FIL *fp) { + FRESULT result = f_close(fp); + f_mount(NULL, "", 0); + CHECK_FRESULT(result, "close failed", -1); + return 0; +} + int usb_write(const void *bytes, const char *filename, size_t size) { FRESULT result; diff --git a/Src/main.c b/Src/main.c index 0e7e396..eb31a29 100644 --- a/Src/main.c +++ b/Src/main.c @@ -347,11 +347,10 @@ void StartDefaultTask(void const * argument) // Initialize Wakaama LWM2M Client lwip_socket_init(); - int socket = createUDPSocket(LOCAL_PORT, AF_INET); if(socket != -1){ printf("Start wakaama task\r\n"); - int res = xTaskCreate(taskWakaama, "wakaama", 3000, (void *) socket, 2, NULL); + int res = xTaskCreate(taskWakaama, "wakaama", 3000, (void *) socket, 3, NULL); if (res != pdPASS) { printf("\r\nerror creating taskWakaama: %d\n", res); } diff --git a/Src/target.c b/Src/target.c index 66ea49f..51e9355 100644 --- a/Src/target.c +++ b/Src/target.c @@ -1,6 +1,8 @@ #include "stm32f4xx_it.h" #include "cmsis_os.h" #include "target.h" +#include "fatfs.h" +#include "object_target.h" TARGET_t target_list = {0, 0, 0}; @@ -13,4 +15,39 @@ void register_target(void *priv, TARGET_OPS_t *ops, char *name){ new_target->next = target_list.next; target_list.next = new_target; printf("Registered target \"%s\"\n", name); +} + +void flash_target_task(void *object) { + target_instance_t * target_object = (target_instance_t *) object; + + FIL file; + int result; + + result = usb_open_file(target_object->binary_filename, &file, FA_READ); + if (result != 0) { + target_object->flash_error = USB_FS_ERROR; + target_object->flash_state = FLASH_ERROR; + vTaskDelete(NULL); + } + + result = target_object->target->ops->flash_target(target_object->target->priv, &file); + if (result != 0) { + target_object->flash_error = result; + target_object->flash_state = FLASH_ERROR; + } else { + target_object->flash_state = FLASH_COMPLETED; + } + + result = usb_close_file(&file); + if (result != 0) { + target_object->flash_error = USB_FS_ERROR; + vTaskDelete(NULL); + } + vTaskDelete(NULL); +} + +void reset_target_task(void *object) { + target_instance_t * target_object = (target_instance_t *) object; + target_object->target->ops->reset_target(target_object->target->priv); + vTaskDelete(NULL); } \ No newline at end of file From ad8154939a5bf42c10d741122376e18e5e3f659f Mon Sep 17 00:00:00 2001 From: Maksymilian Wojczuk Date: Sat, 10 Nov 2018 14:25:34 +0100 Subject: [PATCH 2/2] Remote Flashing Removed unnecessary comments --- .../wakaama_client/objects/object_target.c | 44 ------------------- 1 file changed, 44 deletions(-) diff --git a/Src/communication/wakaama_client/objects/object_target.c b/Src/communication/wakaama_client/objects/object_target.c index 6d1c403..96bb5b3 100644 --- a/Src/communication/wakaama_client/objects/object_target.c +++ b/Src/communication/wakaama_client/objects/object_target.c @@ -404,50 +404,6 @@ lwm2m_object_t * get_target_object(void) targetObj->discoverFunc = target_discover; } return targetObj; - - - - - // lwm2m_object_t * targetObj; - // targetObj = (lwm2m_object_t *)lwm2m_malloc(sizeof(lwm2m_object_t)); - // if (NULL != targetObj) - // { - // target_instance_t * targetP; - - // memset(targetObj, 0, sizeof(lwm2m_object_t)); - - // targetObj->objID = 31025; - - // targetP = (target_instance_t *)lwm2m_malloc(sizeof(target_instance_t)); - // if (NULL == targetP) return NULL; - // memset(targetP, 0, sizeof(target_instance_t)); - // targetP->shortID = 1; - // targetP->target_type = "STM32"; - // targetP->firmware_url = NULL; - // targetP->download_state = NO_DOWNLOAD_DATA; - // targetP->firmware_version = 0; - // targetP->flash_state = 0; - // targetP->download_progress = 0; - // targetP->download_error = NO_ERROR; - // targetP->binary_filename = lwm2m_malloc(25); - - // targetObj->instanceList = LWM2M_LIST_ADD(targetObj->instanceList, targetP); - // /* - // * From a single instance object, two more functions are available. - // * - The first one (createFunc) create a new instance and filled it with the provided informations. If an ID is - // * provided a check is done for verifying his disponibility, or a new one is generated. - // * - The other one (deleteFunc) delete an instance by removing it from the instance list (and freeing the memory - // * allocated to it) - // */ - // targetObj->readFunc = target_read; - // targetObj->writeFunc = target_write; - // targetObj->executeFunc = target_exec; - // targetObj->createFunc = target_create; - // targetObj->deleteFunc = target_delete; - // targetObj->discoverFunc = target_discover; - // } - - // return targetObj; } void free_target_object(lwm2m_object_t * object)