diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2017-09-08 20:44:56 +0900 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2017-09-08 20:44:56 +0900 |
commit | 2c9191c4b365e08bf3ee4272a190473a7c372ca1 (patch) | |
tree | 3ee1315a7286e47fb107eda4a53ca29b6e8e2403 | |
parent | af5982507f5f6831b202d1014138a92b8a243183 (diff) |
Implement flash ROM emulation on GNU/LInux.
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | mcu/sys-gnu-linux.c | 121 |
2 files changed, 123 insertions, 2 deletions
@@ -1,3 +1,7 @@ +2017-09-08 NIIBE Yutaka <gniibe@fsij.org> + + * mcu/sys-gnu-linux.c: Flash emulation implemented. + 2017-09-05 NIIBE Yutaka <gniibe@fsij.org> * example-cdc: Use stack-def.h. diff --git a/mcu/sys-gnu-linux.c b/mcu/sys-gnu-linux.c index f7f51b0..b6e88c3 100644 --- a/mcu/sys-gnu-linux.c +++ b/mcu/sys-gnu-linux.c @@ -1,6 +1,15 @@ #include <stdint.h> #include <stdlib.h> #include <stdio.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <unistd.h> +#include <sys/stat.h> +#include <sys/mman.h> + #include "board.h" const uint8_t sys_version[8] = { @@ -19,36 +28,144 @@ set_led (int on) puts (on ? "*": ""); } +static const char *flash_path; +static size_t flash_size; +static void * flash_addr; +static int flash_fd; + +void +flash_init (const char *f_name) +{ + int fd; + struct stat sb; + void *addr; + + fd = open (f_name, O_RDONLY); + if (fd < 0) + { + perror ("flash_init: open"); + exit (1); + } + + if (fstat (fd, &sb) < 0) + { + perror ("flash_init: fstat"); + exit (1); + } + + addr = mmap (NULL, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) + { + perror ("flash_init: mmap"); + exit (1); + } + + if (close (fd) < 0) + { + perror ("flash_init: close"); + exit (1); + } + + flash_path = f_name; + flash_addr = addr; + flash_size = sb.st_size; +} + void flash_unlock (void) { + int fd; + + fd = open (flash_path, O_WRONLY); + if (fd < 0) + { + perror ("flash_unlock: open"); + exit (1); + } + flash_fd = fd; } int flash_program_halfword (uint32_t addr, uint16_t data) { + off_t offset; + char buf[2]; + fprintf (stderr, "flash_program_halfword: addr=%08x, data=%04x\n", addr, data); + offset = (off_t)(addr - (uint32_t)flash_addr); + offset = lseek (flash_fd, offset, SEEK_SET); + if (offset == (off_t)-1) + { + perror ("flash_program_halfword"); + return 1; + } + buf[0] = (data & 0xff); + buf[1] = (data >> 8); + if (write (flash_fd, buf, 2) != 2) + { + perror ("flash_program_halfword"); + return 2; + } return 0; } +static const uint8_t erased[] = { [0 ... 1023 ] = 0xff }; + int flash_erase_page (uint32_t addr) { + off_t offset; + fprintf (stderr, "flash_erase_page: addr=%08x\n", addr); + + offset = (off_t)(addr - (uint32_t)flash_addr); + offset = lseek (flash_fd, offset, SEEK_SET); + if (offset == (off_t)-1) + { + perror ("flash_erase_page"); + return 1; + } + + if (write (flash_fd, erased, sizeof (erased)) != len) + { + perror ("flash_erase_page"); + return 2; + } return 0; } int flash_check_blank (const uint8_t *p_start, size_t size) { - fprintf (stderr, "flash_check_blank: addr=%p, size=%zd\n", p_start, size); - return 0; + const uint8_t *p; + + for (p = p_start; p < p_start + size; p++) + if (*p != 0xff) + return 0; + + return 1; } int flash_write (uint32_t dst_addr, const uint8_t *src, size_t len) { + off_t offset; + fprintf (stderr, "flash_write: addr=%08x, %p, %zd\n", dst_addr, src, len); + + offset = (off_t)(dst_addr - (uint32_t)flash_addr); + offset = lseek (flash_fd, offset, SEEK_SET); + if (offset == (off_t)-1) + { + perror ("flash_write"); + return 1; + } + + if (write (flash_fd, src, len) != len) + { + perror ("flash_write"); + return 2; + } return 0; } |