From 83cff2f9a69cf6ca87d51f235031618afc5009e5 Mon Sep 17 00:00:00 2001 From: Doug Goldstein Date: Tue, 18 Feb 2014 20:06:31 -0600 Subject: [PATCH] Extend special_init/special_deinit API Its pretty common for callback style APIs to include a private pointer to allow the user to pass in contextual data through the callback API (see pthread_create for an example). This change adds that for special_init() and special_deinit() which are designed as callbacks. Effectively this behavior was used in the only two examples that used those callbacks by having global variables, however globals are of limited use for programs that might instantiate multiple avr cores. --- examples/board_simduino/simduino.c | 39 ++++++++++++++++++------------ examples/extra_board_usb/simusb.c | 35 ++++++++++++++++----------- simavr/sim/sim_avr.c | 4 +-- simavr/sim/sim_avr.h | 8 +++--- tests/tests.c | 2 +- 5 files changed, 52 insertions(+), 36 deletions(-) diff --git a/examples/board_simduino/simduino.c b/examples/board_simduino/simduino.c index 9ed9841..3e4b344 100644 --- a/examples/board_simduino/simduino.c +++ b/examples/board_simduino/simduino.c @@ -145,42 +145,46 @@ static void * avr_run_thread(void * oaram) return NULL; } - -char avr_flash_path[1024]; -int avr_flash_fd = 0; +struct avr_flash { + char avr_flash_path[1024]; + int avr_flash_fd; +}; // avr special flash initalization // here: open and map a file to enable a persistent storage for the flash memory -void avr_special_init( avr_t * avr) +void avr_special_init( avr_t * avr, void * data) { + struct avr_flash *flash_data = (struct avr_flash *)data; // open the file - avr_flash_fd = open(avr_flash_path, O_RDWR|O_CREAT, 0644); - if (avr_flash_fd < 0) { - perror(avr_flash_path); + avr_flash_fd = open(flash_data->avr_flash_path, O_RDWR|O_CREAT, 0644); + if (flash_data->avr_flash_fd < 0) { + perror(flash_data->avr_flash_path); exit(1); } // resize and map the file the file - (void)ftruncate(avr_flash_fd, avr->flashend + 1); - ssize_t r = read(avr_flash_fd, avr->flash, avr->flashend + 1); + (void)ftruncate(flash_data->avr_flash_fd, avr->flashend + 1); + ssize_t r = read(flash_data->avr_flash_fd, avr->flash, avr->flashend + 1); if (r != avr->flashend + 1) { fprintf(stderr, "unable to load flash memory\n"); - perror(avr_flash_path); + perror(flash_data->avr_flash_path); exit(1); } } // avr special flash deinitalization // here: cleanup the persistent storage -void avr_special_deinit( avr_t* avr) +void avr_special_deinit( avr_t* avr, void * data) { + struct avr_flash *flash_data = (struct avr_flash *)data; + puts(__func__); - lseek(avr_flash_fd, SEEK_SET, 0); - ssize_t r = write(avr_flash_fd, avr->flash, avr->flashend + 1); + lseek(flash_data->avr_flash_fd, SEEK_SET, 0); + ssize_t r = write(flash_data->avr_flash_fd, avr->flash, avr->flashend + 1); if (r != avr->flashend + 1) { fprintf(stderr, "unable to load flash memory\n"); - perror(avr_flash_path); + perror(flash_data->avr_flash_path); } - close(avr_flash_fd); + close(flash_data->avr_flash_fd); uart_pty_stop(&uart_pty); } @@ -188,6 +192,7 @@ int main(int argc, char *argv[]) { //elf_firmware_t f; //const char * pwd = dirname(argv[0]); + struct avr_flash flash_data; avr = avr_make_mcu_by_name("atmega328p"); if (!avr) { @@ -195,10 +200,12 @@ int main(int argc, char *argv[]) exit(1); } // snprintf(avr_flash_path, sizeof(avr_flash_path), "%s/%s", pwd, "simduino_flash.bin"); - strcpy(avr_flash_path, "simduino_flash.bin"); + strcpy(flash_data.avr_flash_path, "simduino_flash.bin"); + flash_data.avr_flash_fd = 0; // register our own functions avr->special_init = avr_special_init; avr->special_deinit = avr_special_deinit; + avr->special_data = &flash_data; //avr->reset = NULL; avr_init(avr); avr->frequency = 16000000; diff --git a/examples/extra_board_usb/simusb.c b/examples/extra_board_usb/simusb.c index 0bd079c..439c519 100644 --- a/examples/extra_board_usb/simusb.c +++ b/examples/extra_board_usb/simusb.c @@ -43,42 +43,46 @@ avr_t * avr = NULL; avr_vcd_t vcd_file; - -char avr_flash_path[1024]; -int avr_flash_fd = 0; +struct avr_flash { + char avr_flash_path[1024]; + int avr_flash_fd; +}; // avr special flash initalization // here: open and map a file to enable a persistent storage for the flash memory -void avr_special_init( avr_t* avr) +void avr_special_init( avr_t* avr, void *data) { + struct avr_flash *flash_data = (struct avr_flash *)data; //puts(" --=== INIT CALLED ===--"); // release flash memory if allocated if(avr->flash) free(avr->flash); // open the file - avr_flash_fd = open(avr_flash_path, O_RDWR|O_CREAT, 0644); - if (avr_flash_fd < 0) { - perror(avr_flash_path); + flash_data->avr_flash_fd = open(flash_data->avr_flash_path, + O_RDWR|O_CREAT, 0644); + if (flash_data->avr_flash_fd < 0) { + perror(flash_data->avr_flash_path); exit(1); } // resize and map the file the file - (void)ftruncate(avr_flash_fd, avr->flashend + 1); + (void)ftruncate(flash_data->avr_flash_fd, avr->flashend + 1); avr->flash = (uint8_t*)mmap(NULL, avr->flashend + 1, // 32k is multiple of 4096 - PROT_READ|PROT_WRITE, MAP_SHARED, avr_flash_fd, 0); + PROT_READ|PROT_WRITE, MAP_SHARED, flash_data->avr_flash_fd, 0); if (!avr->flash) { fprintf(stderr, "unable to map memory\n"); - perror(avr_flash_path); + perror(flash_data->avr_flash_path); exit(1); } } // avr special flash deinitalization // here: cleanup the persistent storage -void avr_special_deinit( avr_t* avr) +void avr_special_deinit( avr_t* avr, void *data) { + struct avr_flash *flash_data = (struct avr_flash *)data; //puts(" --=== DEINIT CALLED ===--"); // unmap and close the file munmap( avr->flash, avr->flashend + 1); - close( avr_flash_fd); + close(flash_data->avr_flash_fd); // signal that cleanup is done avr->flash = NULL; } @@ -87,16 +91,19 @@ int main(int argc, char *argv[]) { // elf_firmware_t f; const char * pwd = dirname(argv[0]); + struct avr_flash flash_data; avr = avr_make_mcu_by_name("at90usb162"); if (!avr) { fprintf(stderr, "%s: Error creating the AVR core\n", argv[0]); exit(1); } - strcpy(avr_flash_path, "simusb_flash.bin"); + strcpy(flash_data->avr_flash_path, "simusb_flash.bin"); + flash_data->avr_flash_fd = 0; // register our own functions avr->special_init = avr_special_init; avr->special_deinit = avr_special_deinit; + avr->special_data = &flash_data; //avr->reset = NULL; avr_init(avr); avr->frequency = 8000000; @@ -115,7 +122,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "%s: Unable to load %s\n", argv[0], path); exit(1); } - printf("Booloader %04x: %d\n", base, size); + printf("Bootloader %04x: %d\n", base, size); memcpy(avr->flash + base, boot, size); free(boot); avr->pc = base; diff --git a/simavr/sim/sim_avr.c b/simavr/sim/sim_avr.c index 5dcdb09..8eaee52 100644 --- a/simavr/sim/sim_avr.c +++ b/simavr/sim/sim_avr.c @@ -83,7 +83,7 @@ int avr_init(avr_t * avr) avr->frequency = 1000000; // can be overridden via avr_mcu_section avr_interrupt_init(avr); if (avr->special_init) - avr->special_init(avr); + avr->special_init(avr, avr->special_data); if (avr->init) avr->init(avr); // set default (non gdb) fast callbacks @@ -98,7 +98,7 @@ int avr_init(avr_t * avr) void avr_terminate(avr_t * avr) { if (avr->special_deinit) - avr->special_deinit(avr); + avr->special_deinit(avr, avr->special_data); if (avr->gdb) { avr_deinit_gdb(avr); avr->gdb = NULL; diff --git a/simavr/sim/sim_avr.h b/simavr/sim/sim_avr.h index 2cfb244..848773e 100644 --- a/simavr/sim/sim_avr.h +++ b/simavr/sim/sim_avr.h @@ -167,13 +167,15 @@ typedef struct avr_t { * is passed on to the operating system. */ uint32_t sleep_usec; - + // called at init time void (*init)(struct avr_t * avr); // called at init time (for special purposes like using a memory mapped file as flash see: simduino) - void (*special_init)(struct avr_t * avr); + void (*special_init)(struct avr_t * avr, void * data); // called at termination time ( to clean special initializations) - void (*special_deinit)(struct avr_t * avr); + void (*special_deinit)(struct avr_t * avr, void * data); + // value passed to special_init() and special_deinit() + void *special_data; // called at reset time void (*reset)(struct avr_t * avr); diff --git a/tests/tests.c b/tests/tests.c index 3b94cab..112054f 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -54,7 +54,7 @@ cycle_timer_longjmp_cb(struct avr_t *avr, avr_cycle_count_t when, void *param) { static jmp_buf *special_deinit_jmpbuf = NULL; -static void special_deinit_longjmp_cb(struct avr_t *avr) { +static void special_deinit_longjmp_cb(struct avr_t *avr, void *data) { if (special_deinit_jmpbuf) longjmp(*special_deinit_jmpbuf, LJR_SPECIAL_DEINIT); } -- 2.39.5