Commit 83cff2f9a69cf6ca87d51f235031618afc5009e5
authorDoug Goldstein <cardoe@cardoe.com>
Wed, 19 Feb 2014 02:06:31 +0000 (20:06 -0600)
committerDoug Goldstein <cardoe@cardoe.com>
Wed, 19 Feb 2014 02:27:24 +0000 (20:27 -0600)
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.

5 files changed:
examples/board_simduino/simduino.c
examples/extra_board_usb/simusb.c
simavr/sim/sim_avr.c
simavr/sim/sim_avr.h
tests/tests.c

index 9ed9841e644aaa95c89af718c08dafdb9974efc3..3e4b3446960052f5f401d2ed8912cb302eecced8 100644 (file)
@@ -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;
index 0bd079c1caa3dbd4728d1bc94a449334e9a9ee66..439c519c1786225e873335d5b29ed029369446a2 100644 (file)
@@ -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;
index 5dcdb0937b997e2843ab120af48692978afc57a3..8eaee52223c72a9813a675c799852c09444a7ea3 100644 (file)
@@ -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;
index 2cfb244db63da4b8c42ec7094f0b0099d5b42b66..848773eccb01be463f2273c1bc0d4d3c219c3be5 100644 (file)
@@ -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);
 
index 3b94cab9c52b8bb669791014ddf725cc27b8d75e..112054f8f6ab039571499180b774dd395e5472e7 100644 (file)
@@ -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);
 }