diff --git a/utils/rum-ba/Makefile b/utils/rum-ba/Makefile new file mode 100644 index 0000000..a7da2ae --- /dev/null +++ b/utils/rum-ba/Makefile @@ -0,0 +1,87 @@ +# binary file name +TARGET=sdr-samba + +# CROSS_COMPILE= +QUIET=@ + +# N = build release version +# y = optimize but include debugger info +# Y = build debug version +DEBUG=N + +C_SOURCES=\ + src/main.c \ + src/osmosdr.c \ + src/sam3u.c \ + src/serial.c \ + src/utils.c + +# general compiler flags +CFLAGS=-Wall +LDFLAGS=-Wl,-Map=$(FULLTARGET).map +LIBS=-lrt + +############################################################################## + +SUBDIRS=$(sort $(dir $(C_SOURCES))) + +DEPDIR=deps +OBJDIR=objs +BINDIR=bin +DEPDIRS=$(addprefix $(DEPDIR)/,$(SUBDIRS)) +OBJDIRS=$(addprefix $(OBJDIR)/,$(SUBDIRS)) + +CC=$(CROSS_COMPILE)gcc +LD=$(CROSS_COMPILE)gcc + +COBJS=$(C_SOURCES:%.c=%.o) +DEPS=$(C_SOURCES:%.c=%.dep) +FULLDEPS=$(addprefix $(DEPDIR)/,$(DEPS)) +FULLCOBJS=$(addprefix $(OBJDIR)/,$(COBJS)) +FULLTARGET=$(addprefix $(BINDIR)/,$(TARGET)) + +ifeq ($(DEBUG),Y) + # debug version + CFLAGS+=-O0 -g3 + LDFLAGS+=-g3 +else ifeq ($(DEBUG),y) + # optimized version with debugger info + CFLAGS+=-O2 -g3 -Werror -ffunction-sections -fdata-sections + LDFLAGS+=-g3 -Wl,--gc-sections +else + # release version + CFLAGS+=-O2 -s -Werror -ffunction-sections -fdata-sections + LDFLAGS+=-s -Wl,--gc-sections +endif + +.PHONY: all build clean distclean + +all: build + +build: $(FULLTARGET) + +-include $(FULLDEPS) + +$(FULLTARGET): $(DEPDIRS) $(OBJDIRS) $(BINDIR) $(FULLCOBJS) + @echo LD \ $(TARGET) + $(QUIET)$(LD) $(LDFLAGS) -o $(FULLTARGET) -Wl,--start-group $(FULLCOBJS) $(LIBS) -Wl,--end-group + $(QUIET)ln -sf $(FULLTARGET) $(TARGET) + +$(FULLCOBJS): + @echo C\ \ \ $(patsubst $(OBJDIR)/%,%,$(patsubst %.o,%.c, $@)) + $(QUIET)$(CC) $(CFLAGS) $(CFLAGS_$(subst /,_,$(patsubst %.o,%,$@))) -MD -MP -MF $(patsubst %.o,$(DEPDIR)/%.dep,$(patsubst $(OBJDIR)/%,%,$@)) -c $(patsubst $(OBJDIR)/%,%,$(patsubst %.o,%.c, $@)) -o $@ + +$(DEPDIRS): + $(QUIET)mkdir -p $@ + +$(OBJDIRS): + $(QUIET)mkdir -p $@ + +$(BINDIR): + $(QUIET)mkdir -p $@ + +clean: + $(QUIET)echo CLEAN + $(QUIET)rm -Rf $(DEPDIR) $(OBJDIR) $(BINDIR) $(TARGET) $(TARGET).map *~ *.s *.ss + +distclean: clean diff --git a/utils/rum-ba/src/main.c b/utils/rum-ba/src/main.c new file mode 100644 index 0000000..6e68443 --- /dev/null +++ b/utils/rum-ba/src/main.c @@ -0,0 +1,86 @@ +#include +#include +#include +#include "serial.h" +#include "osmosdr.h" +#include "utils.h" + +static int printSyntax() +{ + fprintf(stderr, "Error: Invalid command line!\n\n" + "syntax: sdr-samba /dev/ttyACM0 command\n" + "valid commands are:\n" + " - detect: detect OsmoSDR and print unique ID\n" + " - blink: blink LEDs on board\n" + " - ramload image.bin: load image.bin into SRAM and start it\n" + " - flash image.bin: write image.bin to FLASH\n"); + + return EXIT_FAILURE; +} + +int main(int argc, char* argv[]) +{ + int fd; + int res = -1; + void* bin; + size_t binSize; + + if(argc < 3) + return printSyntax(); + + if(strcmp(argv[2], "detect") == 0) { + if(argc != 3) + return printSyntax(); + if((fd = serialOpen(argv[1])) < 0) + return EXIT_FAILURE; + res = 0; + if(res >= 0) + res = osmoSDRDetect(fd); + if(res >= 0) + res = osmoSDRPrintUID(fd, 0); + if(res >= 0) + res = osmoSDRPrintUID(fd, 1); + serialClose(fd); + } else if(strcmp(argv[2], "blink") == 0) { + if(argc != 3) + return printSyntax(); + if((fd = serialOpen(argv[1])) < 0) + return EXIT_FAILURE; + res = 0; + if(res >= 0) + res = osmoSDRDetect(fd); + if(res >= 0) + res = osmoSDRBlink(fd); + serialClose(fd); + } else if(strcmp(argv[2], "ramload") == 0) { + if(argc != 4) + return printSyntax(); + if((bin = loadFile(argv[3], &binSize)) == NULL) + return EXIT_FAILURE; + if((fd = serialOpen(argv[1])) < 0) + return EXIT_FAILURE; + res = 0; + if(res >= 0) + res = osmoSDRDetect(fd); + if(res >= 0) + res = osmoSDRRamLoad(fd, bin, binSize); + serialClose(fd); + } else if(strcmp(argv[2], "flash") == 0) { + if(argc != 4) + return printSyntax(); + if((bin = loadFile(argv[3], &binSize)) == NULL) + return EXIT_FAILURE; + if((fd = serialOpen(argv[1])) < 0) + return EXIT_FAILURE; + res = 0; + if(res >= 0) + res = osmoSDRDetect(fd); + if(res >= 0) + res = osmoSDRFlash(fd, bin, binSize); + serialClose(fd); + } else { + return printSyntax(); + } + + return (res < 0) ? EXIT_FAILURE : EXIT_SUCCESS; +} diff --git a/utils/rum-ba/src/osmosdr.c b/utils/rum-ba/src/osmosdr.c new file mode 100644 index 0000000..b792138 --- /dev/null +++ b/utils/rum-ba/src/osmosdr.c @@ -0,0 +1,104 @@ +#include +#include +#include "osmosdr.h" +#include "sam3u.h" + +int osmoSDRDetect(int fd) +{ + uint32_t chipID; + + if(sam3uDetect(fd, &chipID) < 0) + return -1; + + if((chipID & 0xffffffe0) == 0x28000960) { + printf("Chip ID: 0x%08x -- ok\n", chipID); + } else { + printf("Chip ID: 0x%08x -- ERROR\n", chipID); + return -1; + } + + return 0; +} + +int osmoSDRPrintUID(int fd, int bank) +{ + uint8_t uniqueID[16]; + int i; + + if(sam3uReadUniqueID(fd, bank, uniqueID) < 0) { + fprintf(stderr, "could not read unique ID\n"); + return -1; + } + + printf("UID%d : ", bank); + for(i = 0; i < 16; i++) + printf("%02x", uniqueID[i]); + printf("\n"); + + return 0; +} + +int osmoSDRBlink(int fd) +{ + int i; + + if(sam3uWrite32(fd, 0x400e0e00 + 0x44, 1 << 19) < 0) + return -1; + if(sam3uWrite32(fd, 0x400e0e00 + 0x60, 1 << 19) < 0) + return -1; + if(sam3uWrite32(fd, 0x400e0e00 + 0x54, 1 << 19) < 0) + return -1; + if(sam3uWrite32(fd, 0x400e0e00 + 0x10, 1 << 19) < 0) + return -1; + if(sam3uWrite32(fd, 0x400e0e00 + 0x00, 1 << 19) < 0) + return -1; + + for(i = 0; i < 10; i++) { + printf("on."); fflush(stdout); + if(sam3uWrite32(fd, 0x400e0e00 + 0x34, 1 << 19) < 0) + return -1; + usleep(250 * 1000); + printf("off."); fflush(stdout); + if(sam3uWrite32(fd, 0x400e0e00 + 0x30, 1 << 19) < 0) + return -1; + usleep(250 * 1000); + } + + printf(" -- ok\n"); + return 0; +} + +int osmoSDRRamLoad(int fd, void* bin, size_t binSize) +{ + size_t ofs; + uint32_t tmp; + + printf("Uploading %zu bytes @ 0x20001000", binSize); + + for(ofs = 0; ofs < binSize; ofs += 4) { + if(sam3uWrite32(fd, 0x20001000 + ofs, ((uint32_t*)bin)[ofs / 4]) < 0) + return -1; + } + + for(ofs = 0; ofs < binSize; ofs += 4) { + if(sam3uRead32(fd, 0x20001000 + ofs, &tmp) < 0) + return -1; + if(tmp != ((uint32_t*)bin)[ofs / 4]) { + printf(" -- RAM verify failed\n"); + return -1; + } + } + printf(" -- ok\n"); + + printf("Starting @ 0x%08x\n", ((uint32_t*)bin)[1]); + + if(sam3uRun(fd, ((uint32_t*)bin)[1]) < 0) + return -1; + + return 0; +} + +int osmoSDRFlash(int fd, void* bin, size_t binSize) +{ + return sam3uFlash(fd, 0, bin, binSize); +} diff --git a/utils/rum-ba/src/osmosdr.h b/utils/rum-ba/src/osmosdr.h new file mode 100644 index 0000000..5ed3a51 --- /dev/null +++ b/utils/rum-ba/src/osmosdr.h @@ -0,0 +1,12 @@ +#ifndef INCLUDE_OSMOSDR_H +#define INCLUDE_OSMOSDR_H + +#include + +int osmoSDRDetect(int fd); +int osmoSDRPrintUID(int fd, int bank); +int osmoSDRBlink(int fd); +int osmoSDRRamLoad(int fd, void* bin, size_t binSize); +int osmoSDRFlash(int fd, void* bin, size_t binSize); + +#endif // INCLUDE_OSMOSDR_H diff --git a/utils/rum-ba/src/sam3u.c b/utils/rum-ba/src/sam3u.c new file mode 100644 index 0000000..ab6a2c3 --- /dev/null +++ b/utils/rum-ba/src/sam3u.c @@ -0,0 +1,308 @@ +#include +#include +#include +#include +#include "sam3u.h" +#include "serial.h" + +int sam3uRead32(int fd, uint32_t address, uint32_t* value) +{ + char str[32]; + sprintf(str, "w%08X,4#", address); + if(serialPutS(fd, str) < 0) + return -1; + if(serialExpect(fd, "\n\r0x", 100) < 0) + return -1; + if(serialGetS(fd, str, 8, 100) < 0) + return -1; + str[8] = '\0'; + errno = 0; + *value = strtoll(str, NULL, 16); + if(errno != 0) { + fprintf(stderr, "number conversion failed: %s", strerror(errno)); + return -1; + } + if(serialExpect(fd, "\n\r>", 100) < 0) + return -1; + return 0; +} + +int sam3uRead16(int fd, uint32_t address, uint16_t* value) +{ + char str[32]; + sprintf(str, "h%08X,2#", address); + if(serialPutS(fd, str) < 0) + return -1; + if(serialExpect(fd, "\n\r0x", 100) < 0) + return -1; + if(serialGetS(fd, str, 4, 100) < 0) + return -1; + str[4] = '\0'; + errno = 0; + *value = strtol(str, NULL, 16); + if(errno != 0) { + fprintf(stderr, "number conversion failed: %s", strerror(errno)); + return -1; + } + if(serialExpect(fd, "\n\r>", 100) < 0) + return -1; + return 0; +} + +int sam3uRead8(int fd, uint32_t address, uint8_t* value) +{ + char str[32]; + sprintf(str, "o%08X,1#", address); + if(serialPutS(fd, str) < 0) + return -1; + if(serialExpect(fd, "\n\r0x", 100) < 0) + return -1; + if(serialGetS(fd, str, 2, 100) < 0) + return -1; + str[2] = '\0'; + errno = 0; + *value = strtol(str, NULL, 16); + if(errno != 0) { + fprintf(stderr, "number conversion failed: %s", strerror(errno)); + return -1; + } + if(serialExpect(fd, "\n\r>", 100) < 0) + return -1; + return 0; +} + +int sam3uWrite32(int fd, uint32_t address, uint32_t value) +{ + char str[32]; + sprintf(str, "W%08X,%08X#", address, value); + if(serialPutS(fd, str) < 0) + return -1; + if(serialExpect(fd, "\n\r>", 100) < 0) + return -1; + return 0; +} + +int sam3uWrite16(int fd, uint32_t address, uint16_t value) +{ + char str[32]; + sprintf(str, "H%08X,%04X#", address, value); + if(serialPutS(fd, str) < 0) + return -1; + if(serialExpect(fd, "\n\r>", 100) < 0) + return -1; + return 0; +} + +int sam3uWrite8(int fd, uint32_t address, uint8_t value) +{ + char str[32]; + sprintf(str, "O%08X,%02X#", address, value); + if(serialPutS(fd, str) < 0) + return -1; + if(serialExpect(fd, "\n\r>", 100) < 0) + return -1; + return 0; +} + +int sam3uRun(int fd, uint32_t address) +{ + char str[32]; + sprintf(str, "G%08X#", address); + if(serialPutS(fd, str) < 0) + return -1; + return 0; +} + +int sam3uDetect(int fd, uint32_t* chipID) +{ + char c; + + while(serialGetC(fd, &c, 100) >= 0) ; + + if(serialPutS(fd, "T#") < 0) + return -1; + + if(serialExpect(fd, "\n\r\n\r>", 100) < 0) { + fprintf(stderr, "did not receive expected answer\n"); + return -1; + } + + return sam3uRead32(fd, 0x400e0740, chipID); +} + +int sam3uReadUniqueID(int fd, int bank, uint8_t* uniqueID) +{ + uint32_t regBase; + uint32_t flashBase; + uint32_t fsr; + int i; + + switch(bank) { + case 0: + regBase = 0x400e0800; + flashBase = 0x80000; + break; + case 1: + regBase = 0x400e0a00; + flashBase = 0x100000; + break; + default: + fprintf(stderr, "illegal flash bank"); + return -1; + } + + if(sam3uWrite32(fd, regBase + 0x04, 0x5a00000e) < 0) + return -1; + + do { + if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0) + return -1; + } while((fsr & 1) != 0); + + for(i = 0; i < 16; i++) { + if(sam3uRead8(fd, flashBase + i, uniqueID + i) < 0) + return -1; + } + + if(sam3uWrite32(fd, regBase + 0x04, 0x5a00000f) < 0) + return -1; + + do { + if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0) + return -1; + } while((fsr & 1) == 0); + + return 0; +} + +int sam3uFlash(int fd, int bank, void* bin, size_t binSize) +{ + uint32_t regBase; + uint32_t flashBase; + uint32_t fsr; + uint32_t flID; + uint32_t flSize; + uint32_t flPageSize; + uint32_t flNbPlane; + uint8_t buf[8192]; + uint32_t ofs; + uint32_t todo; + uint32_t len; + uint32_t idx; + + switch(bank) { + case 0: + regBase = 0x400e0800; + flashBase = 0x80000; + break; + case 1: + regBase = 0x400e0a00; + flashBase = 0x100000; + break; + default: + fprintf(stderr, "illegal flash bank"); + return -1; + } + + printf("reading flash descriptor"); + + if(sam3uWrite32(fd, regBase + 0x04, 0x5a000000) < 0) + goto error; + + do { + if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0) + goto error; + } while((fsr & 1) == 0); + + + if(sam3uRead32(fd, regBase + 0x0c, &flID) < 0) + goto error; + if(sam3uRead32(fd, regBase + 0x0c, &flSize) < 0) + goto error; + if(sam3uRead32(fd, regBase + 0x0c, &flPageSize) < 0) + goto error; + if(sam3uRead32(fd, regBase + 0x0c, &flNbPlane) < 0) + goto error; + + printf(" -- ok\n"); + printf("Flash ID: 0x%08x\n", flID); + printf("Flash size: %d Bytes\n", flSize); + printf("Page size: %d Bytes\n", flPageSize); + printf("Number of planes: %d\n", flNbPlane); + +#if 1 + printf("erasing flash"); fflush(stdout); + + if(sam3uWrite32(fd, regBase + 0x04, 0x5a000005) < 0) + goto error; + + do { + if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0) + goto error; + } while((fsr & 1) == 0); + + printf(" -- ok\n"); +#endif + + ofs = 0; + for(todo = binSize; todo > 0; todo -= len) { + printf("flashing @ 0x%08x", ofs); fflush(stdout); + len = todo; + if(len > flPageSize) + len = flPageSize; + memset(buf, 0xff, sizeof(buf)); + memcpy(buf, ((uint8_t*)bin) + ofs, len); + for(idx = 0; idx < flPageSize / 4; idx++) { + if(sam3uWrite32(fd, flashBase + ofs + (idx * 4), ((uint32_t*)buf)[idx]) < 0) + goto error; + } + + if(sam3uWrite32(fd, regBase + 0x04, 0x5a000000 | ((ofs / flPageSize) << 8) | 0x03) < 0) + goto error; + + do { + if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0) + goto error; + } while((fsr & 1) == 0); + + printf(" -- ok\n"); + + ofs += flPageSize; + } + + ofs = 0; + for(todo = binSize; todo > 0; todo -= len) { + printf("verifying @ 0x%08x", ofs); fflush(stdout); + len = todo; + if(len > flPageSize) + len = flPageSize; + + for(idx = 0; idx < flPageSize / 4; idx++) { + if(sam3uRead32(fd, flashBase + ofs + (idx * 4), ((uint32_t*)buf) + idx) < 0) + goto error; + } + + if(memcmp(buf, ((uint8_t*)bin) + ofs, len) == 0) + printf(" -- ok\n"); + else printf(" -- ERROR\n"); + + ofs += flPageSize; + } + + printf("disabling SAM-BA"); fflush(stdout); + if(sam3uWrite32(fd, regBase + 0x04, 0x5a000000 | (1 << 8) | 0x0b) < 0) + goto error; + + do { + if(sam3uRead32(fd, regBase + 0x08, &fsr) < 0) + goto error; + } while((fsr & 1) == 0); + + printf(" -- ok\n"); + + return 0; + +error: + printf(" -- ERROR\n"); + return -1; +} diff --git a/utils/rum-ba/src/sam3u.h b/utils/rum-ba/src/sam3u.h new file mode 100644 index 0000000..190cd40 --- /dev/null +++ b/utils/rum-ba/src/sam3u.h @@ -0,0 +1,19 @@ +#ifndef INCLUDE_SAM3U_H +#define INCLUDE_SAM3U_H + +#include + +int sam3uRead32(int fd, uint32_t address, uint32_t* value); +int sam3uRead16(int fd, uint32_t address, uint16_t* value); +int sam3uRead8(int fd, uint32_t address, uint8_t* value); + +int sam3uWrite32(int fd, uint32_t address, uint32_t value); +int sam3uWrite16(int fd, uint32_t address, uint16_t value); +int sam3uWrite8(int fd, uint32_t address, uint8_t value); + +int sam3uRun(int fd, uint32_t address); +int sam3uDetect(int fd, uint32_t* chipID); +int sam3uReadUniqueID(int fd, int bank, uint8_t* uniqueID); +int sam3uFlash(int fd, int bank, void* bin, size_t binSize); + +#endif // INCLUDE_SAM3U_H diff --git a/utils/rum-ba/src/serial.c b/utils/rum-ba/src/serial.c new file mode 100644 index 0000000..545a35a --- /dev/null +++ b/utils/rum-ba/src/serial.c @@ -0,0 +1,175 @@ +#include +#include +#include +#include +#include +#include +#include +#include "serial.h" +#include "utils.h" + +int serialOpen(const char* device) +{ + int fd = -1; + struct termios tios; + + if((fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY)) < 0) { + fprintf(stderr, "could not open %s: %s\n", device, strerror(errno)); + goto failed; + } + bzero(&tios, sizeof(tios)); + tios.c_cflag = B115200 | CS8 | CLOCAL | CREAD; + tios.c_iflag = IGNPAR; + tios.c_oflag = 0; + tios.c_lflag = ICANON; + tios.c_cc[VMIN] = 1; + cfmakeraw(&tios); + if(tcflush(fd, TCIOFLUSH) < 0) { + fprintf(stderr, "tcflush() failed: %s\n", strerror(errno)); + goto failed; + } + if(tcsetattr(fd, TCSAFLUSH, &tios) < 0) { + fprintf(stderr, "tcsetattr() failed: %s\n", strerror(errno)); + goto failed; + } + if(tcflush(fd, TCIOFLUSH) < 0) { + fprintf(stderr, "tcflush() failed: %s\n", strerror(errno)); + goto failed; + } + + return fd; + +failed: + if(fd >= 0) + close(fd); + return -1; +} + +void serialClose(int fd) +{ + if(fd >= 0) + close(fd); +} + +int serialPutC(int fd, char c) +{ + if(write(fd, &c, sizeof(char)) != sizeof(char)) { + if(errno == EAGAIN) { + struct pollfd pollfd; + int res; + pollfd.fd = fd; + pollfd.events = POLLOUT; + pollfd.revents = 0; + do { + res = poll(&pollfd, 1, 250); + } while((res < 0) && (errno == EINTR)); + if(res > 0) { + if(write(fd, &c, sizeof(char)) != sizeof(char)) { + fprintf(stderr, "write failed: %s\n", strerror(errno)); + return -1; + } else { + return 0; + } + } else if(res == 0) { + fprintf(stderr, "write failed: %s\n", strerror(errno)); + return -1; + } else { + fprintf(stderr, "poll failed: %s\n", strerror(errno)); + return -1; + } + } else { + fprintf(stderr, "write failed: %s\n", strerror(errno)); + return -1; + } + } else { + return 0; + } +} + +int serialPutS(int fd, const char* str) +{ + while(*str != '\0') { + if(serialPutC(fd, *str++) < 0) + return -1; + } + return 0; +} + +int serialGetC(int fd, char* c, int timeout) +{ + struct pollfd pollfd; + int res; + + pollfd.fd = fd; + pollfd.events = POLLIN; + pollfd.revents = 0; + + do { + res = poll(&pollfd, 1, timeout); + } while((res < 0) && (errno == EINTR)); + + if(res > 0) { + if(read(fd, c, sizeof(char)) != sizeof(char)) { + fprintf(stderr, "read failed: %s\n", strerror(errno)); + return -1; + } else { + return 0; + } + } else if(res == 0) { + // timeout + return -1; + } + + fprintf(stderr, "poll failed: %s\n", strerror(errno)); + return -1; +} + +int serialGetS(int fd, char* str, int len, int timeout) +{ + int todo = len; + uint64_t endTime = getTickCount() + timeout; + + while(todo > 0) { + uint64_t now = getTickCount(); + + if(now < endTime) { + char c; + if(serialGetC(fd, &c, endTime - now) < 0) + return -1; + //printf("[%02x]", c); + *str++ = c; + todo--; + } else { + break; + } + } + + return (todo > 0) ? -1 : 0; +} + +int serialExpect(int fd, const char* str, int timeout) +{ + int todo = strlen(str); + uint64_t endTime = getTickCount() + timeout; + + while(todo > 0) { + uint64_t now = getTickCount(); + + if(now < endTime) { + char c; + if(serialGetC(fd, &c, endTime - now) < 0) + return -1; + //printf("[%02x]", c); + if(c == *str++) { + todo--; + continue; + } else { + return -1; + } + } else { + break; + } + } + + return (todo > 0) ? -1 : 0; +} diff --git a/utils/rum-ba/src/serial.h b/utils/rum-ba/src/serial.h new file mode 100644 index 0000000..6f70c4e --- /dev/null +++ b/utils/rum-ba/src/serial.h @@ -0,0 +1,14 @@ +#ifndef INCLUDE_SERIAL_H +#define INCLUDE_SERIAL_H + +#include + +int serialOpen(const char* device); +void serialClose(int fd); +int serialPutC(int fd, char c); +int serialPutS(int fd, const char* str); +int serialGetC(int fd, char* c, int timeout); +int serialGetS(int fd, char* str, int len, int timeout); +int serialExpect(int fd, const char* str, int timeout); + +#endif // INCLUDE_SERIAL_H diff --git a/utils/rum-ba/src/utils.c b/utils/rum-ba/src/utils.c new file mode 100644 index 0000000..4d1e54c --- /dev/null +++ b/utils/rum-ba/src/utils.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include "utils.h" + +uint64_t getTickCount() +{ + struct timespec t; + + if(clock_gettime(CLOCK_MONOTONIC, &t) != 0) + return 0; + return (((uint64_t)t.tv_sec) * 1000) + (((uint64_t)t.tv_nsec) / 1000000); +} + +void* loadFile(const char* filename, size_t* size) +{ + void* result = NULL; + struct stat statbuf; + FILE* f = NULL; + + if(stat(filename, &statbuf) < 0) { + fprintf(stderr, "could not stat() file %s: %s\n", filename, strerror(errno)); + goto failed; + } + + if((result = calloc(1, statbuf.st_size)) == NULL) { + fprintf(stderr, "failed to allocate %zu bytes of memory\n", (size_t)statbuf.st_size); + goto failed; + } + if((f = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "failed to open %s: %s\n", filename, strerror(errno)); + goto failed; + } + if(fread(result, 1, statbuf.st_size, f) != statbuf.st_size) { + fprintf(stderr, "could not read all bytes: %s\n", strerror(errno)); + goto failed; + } + + fclose(f); + *size = (size_t)statbuf.st_size; + return result; + +failed: + if(f != NULL) + fclose(f); + return NULL; +} diff --git a/utils/rum-ba/src/utils.h b/utils/rum-ba/src/utils.h new file mode 100644 index 0000000..a990dd6 --- /dev/null +++ b/utils/rum-ba/src/utils.h @@ -0,0 +1,9 @@ +#ifndef INCLUDE_UTILS_H +#define INCLUDE_UTILS_H + +#include + +uint64_t getTickCount(); +void* loadFile(const char* filename, size_t* size); + +#endif // INCLUDE_UTILS_H