add initial version of flasher tool

This commit is contained in:
Christian Daniel 2011-12-27 00:09:21 +01:00
parent 79c3f63c78
commit a59a982503
10 changed files with 863 additions and 0 deletions

87
utils/rum-ba/Makefile Normal file
View File

@ -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

86
utils/rum-ba/src/main.c Normal file
View File

@ -0,0 +1,86 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

104
utils/rum-ba/src/osmosdr.c Normal file
View File

@ -0,0 +1,104 @@
#include <stdio.h>
#include <unistd.h>
#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);
}

View File

@ -0,0 +1,12 @@
#ifndef INCLUDE_OSMOSDR_H
#define INCLUDE_OSMOSDR_H
#include <stdint.h>
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

308
utils/rum-ba/src/sam3u.c Normal file
View File

@ -0,0 +1,308 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#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;
}

19
utils/rum-ba/src/sam3u.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef INCLUDE_SAM3U_H
#define INCLUDE_SAM3U_H
#include <stdint.h>
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

175
utils/rum-ba/src/serial.c Normal file
View File

@ -0,0 +1,175 @@
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <poll.h>
#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;
}

14
utils/rum-ba/src/serial.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef INCLUDE_SERIAL_H
#define INCLUDE_SERIAL_H
#include <stdint.h>
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

49
utils/rum-ba/src/utils.c Normal file
View File

@ -0,0 +1,49 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#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;
}

9
utils/rum-ba/src/utils.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef INCLUDE_UTILS_H
#define INCLUDE_UTILS_H
#include <stdint.h>
uint64_t getTickCount();
void* loadFile(const char* filename, size_t* size);
#endif // INCLUDE_UTILS_H