/* vim: set sts=4:sw=4:ts=4:noexpandtab simusb.c Copyright 2012 Torbjorn Tyridal This file is part of simavr. simavr is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. simavr is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with simavr. If not, see . */ #include #include #include #include #include #include #include #include #include #include "sim_avr.h" #include "avr_ioport.h" #include "sim_elf.h" #include "sim_hex.h" #include "sim_gdb.h" #include "vhci_usb.h" #include "sim_vcd_file.h" struct vhci_usb_t vhci_usb; avr_t * avr = NULL; avr_vcd_t vcd_file; 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 *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 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(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, flash_data->avr_flash_fd, 0); if (!avr->flash) { fprintf(stderr, "unable to map memory\n"); 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 *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(flash_data->avr_flash_fd); // signal that cleanup is done avr->flash = NULL; } 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(flash_data.avr_flash_path, "simusb_flash.bin"); flash_data.avr_flash_fd = 0; // register our own functions avr->custom.init = avr_special_init; avr->custom.deinit = avr_special_deinit; avr->custom.data = &flash_data; //avr->reset = NULL; avr_init(avr); avr->frequency = 8000000; // this trick creates a file that contains /and keep/ the flash // in the same state as it was before. This allow the bootloader // app to be kept, and re-run if the bootloader doesn't get a // new one { char path[1024]; uint32_t base, size; snprintf(path, sizeof(path), "%s/../%s", pwd, "at90usb162_cdc_loopback.hex"); uint8_t * boot = read_ihex_file(path, &size, &base); if (!boot) { fprintf(stderr, "%s: Unable to load %s\n", argv[0], path); exit(1); } printf("Bootloader %04x: %d\n", base, size); memcpy(avr->flash + base, boot, size); free(boot); avr->pc = base; avr->codeend = avr->flashend; } // even if not setup at startup, activate gdb if crashing avr->gdb_port = 1234; if (0) { //avr->state = cpu_Stopped; avr_gdb_init(avr); } vhci_usb_init(avr, &vhci_usb); vhci_usb_connect(&vhci_usb, '0'); while (1) { avr_run(avr); } }