diff --git a/src/target/esp_xtensa_semihosting.c b/src/target/esp_xtensa_semihosting.c index 0dc1954c7e..61b4ed9511 100644 --- a/src/target/esp_xtensa_semihosting.c +++ b/src/target/esp_xtensa_semihosting.c @@ -66,6 +66,7 @@ int esp_xtensa_semihosting_init(struct target *target) if (retval != ERROR_OK) return retval; target->semihosting->get_filename = esp_xtensa_semihosting_get_file_name; + target->semihosting->lseek = lseek; target->semihosting->word_size_bytes = 4; /* 32 bits */ return retval; } diff --git a/src/target/esp_xtensa_semihosting.h b/src/target/esp_xtensa_semihosting.h index c7600d8c1e..3db6ce3d10 100644 --- a/src/target/esp_xtensa_semihosting.h +++ b/src/target/esp_xtensa_semihosting.h @@ -17,6 +17,7 @@ #pragma once +#include #include "target.h" #include "command.h" #include "xtensa.h" diff --git a/src/target/semihosting_common.c b/src/target/semihosting_common.c index 800514d051..879798c7c6 100644 --- a/src/target/semihosting_common.c +++ b/src/target/semihosting_common.c @@ -131,6 +131,7 @@ int semihosting_common_init(struct target *target, void *setup, semihosting->read_fields = NULL; // a place for a possible custom fields api semihosting->write_fields = NULL; // a place for a possible custom fields api semihosting->get_filename = NULL; // a place for a possible get filename custom implementation + semihosting->lseek = NULL; // a place for a possible lseek custom implementation target->semihosting = semihosting; @@ -743,11 +744,16 @@ int semihosting_common(struct target *target) (int)semihosting->result); } } else { + uint32_t flags = open_modeflags[mode]; +#ifdef _WIN32 + /* Windows needs O_BINARY flag for proper handling of EOLs */ + flags |= O_BINARY; +#endif /* cygwin requires the permission setting * otherwise it will fail to reopen a previously * written file */ semihosting->result = open((char *)fn, - open_modeflags[mode], + flags, 0644); semihosting->sys_errno = errno; LOG_DEBUG("open('%s')=%d", fn, @@ -1001,7 +1007,11 @@ int semihosting_common(struct target *target) * Note: The effect of seeking outside the current extent of * the file object is undefined. */ - retval = semihosting_read_fields(target, 2, fields); + + if (semihosting->lseek == NULL) + retval = semihosting_read_fields(target, 2, fields); + else + retval = semihosting_read_fields(target, 3, fields); if (retval != ERROR_OK) return retval; else { @@ -1014,7 +1024,12 @@ int semihosting_common(struct target *target) fileio_info->param_2 = pos; fileio_info->param_3 = SEEK_SET; } else { - semihosting->result = lseek(fd, pos, SEEK_SET); + if (semihosting->lseek == NULL) + semihosting->result = lseek(fd, pos, SEEK_SET); + else{ + int whence = semihosting_get_field(target, 2, fields); + semihosting->result = semihosting->lseek(fd, pos, whence); + } semihosting->sys_errno = errno; LOG_DEBUG("lseek(%d, %d)=%d", fd, (int)pos, (int)semihosting->result); diff --git a/src/target/semihosting_common.h b/src/target/semihosting_common.h index 8858b02451..c575a2ca4b 100644 --- a/src/target/semihosting_common.h +++ b/src/target/semihosting_common.h @@ -24,6 +24,7 @@ #include #include +#include #include /* @@ -157,6 +158,7 @@ struct semihosting { int (*read_fields)(struct target *target, size_t number, uint8_t *fields); int (*write_fields)(struct target *target, size_t number, uint8_t *fields); char *(*get_filename)(struct target *target, uint64_t addr_fn, size_t len, uint32_t * mode); + off_t (*lseek)(int fd, off_t offset, int whence); }; int semihosting_common_init(struct target *target, void *setup, void *post_result); diff --git a/testing/esp/test_apps/gen_ut_app/main/semihost_tests.c b/testing/esp/test_apps/gen_ut_app/main/semihost_tests.c index 7c507893dd..baccd88e8b 100644 --- a/testing/esp/test_apps/gen_ut_app/main/semihost_tests.c +++ b/testing/esp/test_apps/gen_ut_app/main/semihost_tests.c @@ -78,8 +78,15 @@ static void semihost_task(void *pvParameter) } } while(read_bytes > 0); + /***** Checking *****/ + long int f_size = ftell(f_out); + if (count != f_size) { + ESP_LOGE(TAG, "CPU[%d]: Failed to determine file size! (size is %ld)", core_id, f_size); + return; + } + ESP_LOGI(TAG, "CPU[%d]: Read %d bytes", core_id, count); - ESP_LOGI(TAG, "CPU[%d]: Wrote %ld bytes", core_id, ftell(f_out)); + ESP_LOGI(TAG, "CPU[%d]: Wrote %ld bytes", core_id, f_size); /***** De-init *****/ ESP_LOGI(TAG, "Closing the files");