added utils

This commit is contained in:
adrcs 2025-01-29 11:17:14 -07:00 committed by GitHub
parent a9a3f739b4
commit a9b13d2c39
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
85 changed files with 9213 additions and 0 deletions

View file

@ -0,0 +1,6 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libparsers
LOCAL_SRC_FILES := binary.c hex.c
include $(BUILD_STATIC_LIBRARY)

View file

@ -0,0 +1,12 @@
CFLAGS += -Wall -g
all: parsers.a
parsers.a: binary.o hex.o
$(AR) rc $@ binary.o hex.o
clean:
rm -f *.o parsers.a
.PHONY: all clean

View file

@ -0,0 +1,11 @@
noinst_LTLIBRARIES = parsers.la
parsers_la_SOURCES = binary.h binary.c hex.h hex.c parser.h
parsers_la_CXXFLAGS = -Wall -g
parsers_la_LDFLAGS = -module -avoid-version

View file

@ -0,0 +1,148 @@
/*
stm32flash - Open Source ST STM32 flash program for *nix
Copyright (C) 2010 Geoffrey McRae <geoff@spacevs.com>
This program 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 2
of the License, or (at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include "binary.h"
typedef struct {
int fd;
char write;
struct stat stat;
} binary_t;
void* binary_init() {
return calloc(sizeof(binary_t), 1);
}
parser_err_t binary_open(void *storage, const char *filename, const char write) {
binary_t *st = storage;
if (write) {
if (filename[0] == '-' && filename[1] == '\0')
st->fd = 1;
else
st->fd = open(
filename,
#ifndef __WIN32__
O_WRONLY | O_CREAT | O_TRUNC,
#else
O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
#endif
#ifndef __WIN32__
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
#else
0
#endif
);
st->stat.st_size = 0;
} else {
if (filename[0] == '-' && filename[1] == '\0') {
st->fd = 0;
} else {
if (stat(filename, &st->stat) != 0)
return PARSER_ERR_INVALID_FILE;
st->fd = open(filename,
#ifndef __WIN32__
O_RDONLY
#else
O_RDONLY | O_BINARY
#endif
);
}
}
st->write = write;
return st->fd == -1 ? PARSER_ERR_SYSTEM : PARSER_ERR_OK;
}
parser_err_t binary_close(void *storage) {
binary_t *st = storage;
if (st->fd) close(st->fd);
free(st);
return PARSER_ERR_OK;
}
unsigned int binary_base(void *storage) {
return 0;
}
unsigned int binary_size(void *storage) {
binary_t *st = storage;
return st->stat.st_size;
}
parser_err_t binary_read(void *storage, void *data, unsigned int *len) {
binary_t *st = storage;
unsigned int left = *len;
unsigned char *d = data;
if (st->write) return PARSER_ERR_WRONLY;
ssize_t r;
while(left > 0) {
r = read(st->fd, d, left);
if (r == 0)
break ;
else if ( r < 0)
return PARSER_ERR_SYSTEM;
left -= r;
d += r;
}
*len = *len - left;
return PARSER_ERR_OK;
}
parser_err_t binary_write(void *storage, void *data, unsigned int len) {
binary_t *st = storage;
unsigned char *d = data;
if (!st->write) return PARSER_ERR_RDONLY;
ssize_t r;
while(len > 0) {
r = write(st->fd, d, len);
if (r < 1) return PARSER_ERR_SYSTEM;
st->stat.st_size += r;
len -= r;
d += r;
}
return PARSER_ERR_OK;
}
parser_t PARSER_BINARY = {
"Raw BINARY",
binary_init,
binary_open,
binary_close,
binary_base,
binary_size,
binary_read,
binary_write
};

View file

@ -0,0 +1,27 @@
/*
stm32flash - Open Source ST STM32 flash program for *nix
Copyright (C) 2010 Geoffrey McRae <geoff@spacevs.com>
This program 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 2
of the License, or (at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _PARSER_BINARY_H
#define _PARSER_BINARY_H
#include "parser.h"
extern parser_t PARSER_BINARY;
#endif

Binary file not shown.

View file

@ -0,0 +1,251 @@
/*
stm32flash - Open Source ST STM32 flash program for *nix
Copyright (C) 2010 Geoffrey McRae <geoff@spacevs.com>
This program 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 2
of the License, or (at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "hex.h"
#include "../compiler.h"
#include "../utils.h"
extern FILE *diag;
typedef struct {
size_t data_len, offset;
uint8_t *data;
uint32_t base;
} hex_t;
void* hex_init() {
return calloc(sizeof(hex_t), 1);
}
parser_err_t hex_open(void *storage, const char *filename, const char write) {
hex_t *st = storage;
if (write) {
return PARSER_ERR_RDONLY;
} else {
char mark;
int fd;
uint8_t checksum;
unsigned int c, i;
uint32_t base = 0;
unsigned int last_address = 0x0;
fd = open(filename, O_RDONLY);
if (fd < 0)
return PARSER_ERR_SYSTEM;
/* read in the file */
while(read(fd, &mark, 1) != 0) {
if (mark == '\n' || mark == '\r') continue;
if (mark != ':')
return PARSER_ERR_INVALID_FILE;
char buffer[9];
unsigned int reclen, address, type;
uint8_t *record = NULL;
/* get the reclen, address, and type */
buffer[8] = 0;
if (read(fd, &buffer, 8) != 8) return PARSER_ERR_INVALID_FILE;
if (sscanf(buffer, "%2x%4x%2x", &reclen, &address, &type) != 3) {
close(fd);
return PARSER_ERR_INVALID_FILE;
}
/* setup the checksum */
checksum =
reclen +
((address & 0xFF00) >> 8) +
((address & 0x00FF) >> 0) +
type;
switch(type) {
/* data record */
case 0:
if (st->data_len == 0) {
st->base |= address;
last_address = address;
}
c = address - last_address;
st->data = realloc(st->data, st->data_len + c + reclen);
/* if there is a gap, set it to 0xff and increment the length */
if (c > 0) {
memset(&st->data[st->data_len], 0xff, c);
st->data_len += c;
}
last_address = address + reclen;
record = &st->data[st->data_len];
st->data_len += reclen;
break;
/* extended segment address record */
case 2:
base = 0;
break;
/* extended linear address record */
case 4:
base = 0;
break;
}
buffer[2] = 0;
for(i = 0; i < reclen; ++i) {
if (read(fd, &buffer, 2) != 2 || sscanf(buffer, "%2x", &c) != 1) {
close(fd);
return PARSER_ERR_INVALID_FILE;
}
/* add the byte to the checksum */
checksum += c;
switch(type) {
case 0:
if (record != NULL) {
record[i] = c;
} else {
return PARSER_ERR_INVALID_FILE;
}
break;
case 2:
case 4:
base = (base << 8) | c;
break;
}
}
/* read, scan, and verify the checksum */
if (
read(fd, &buffer, 2 ) != 2 ||
sscanf(buffer, "%2x", &c) != 1 ||
(uint8_t)(checksum + c) != 0x00
) {
close(fd);
return PARSER_ERR_INVALID_FILE;
}
switch(type) {
/* EOF */
case 1:
close(fd);
return PARSER_ERR_OK;
/* address record */
case 4: base = base << 12;
/* fall-through */
case 2: base = base << 4;
/* Reset last_address since our base changed */
last_address = 0;
/* Only assign the program's base address once, and only
* do so if we haven't seen any data records yet.
* If there are any data records before address records,
* the program's base address must be zero.
*/
if (st->base == 0 && st->data_len == 0) {
st->base = base;
break;
}
/* we cant cope with files out of order */
if (base < st->base) {
close(fd);
return PARSER_ERR_INVALID_FILE;
}
/* if there is a gap, enlarge and fill with 0xff */
size_t len = base - st->base;
if (len > st->data_len) {
size_t gap = len - st->data_len;
if (gap > 16384) /* arbitrary limit for warning */
fprintf(diag, "Warning: Filling gap of %zu bytes at 0x%08zx\n", gap, st->base + st->data_len);
st->data = realloc(st->data, len);
if (st->data == NULL) {
fprintf(diag, "Error: Cannot reallocate memory\n");
return PARSER_ERR_SYSTEM;
}
memset(&st->data[st->data_len], 0xff, gap);
st->data_len = len;
}
break;
}
}
close(fd);
return PARSER_ERR_OK;
}
}
parser_err_t hex_close(void *storage) {
hex_t *st = storage;
if (st) free(st->data);
free(st);
return PARSER_ERR_OK;
}
unsigned int hex_base(void *storage) {
hex_t *st = storage;
return st->base;
}
unsigned int hex_size(void *storage) {
hex_t *st = storage;
return st->data_len;
}
parser_err_t hex_read(void *storage, void *data, unsigned int *len) {
hex_t *st = storage;
unsigned int left = st->data_len - st->offset;
unsigned int get = left > *len ? *len : left;
memcpy(data, &st->data[st->offset], get);
st->offset += get;
*len = get;
return PARSER_ERR_OK;
}
parser_err_t hex_write(void __unused *storage, void __unused *data, unsigned int __unused len) {
return PARSER_ERR_RDONLY;
}
parser_t PARSER_HEX = {
"Intel HEX",
hex_init,
hex_open,
hex_close,
hex_base,
hex_size,
hex_read,
hex_write
};

View file

@ -0,0 +1,27 @@
/*
stm32flash - Open Source ST STM32 flash program for *nix
Copyright (C) 2010 Geoffrey McRae <geoff@spacevs.com>
This program 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 2
of the License, or (at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _PARSER_HEX_H
#define _PARSER_HEX_H
#include "parser.h"
extern parser_t PARSER_HEX;
#endif

Binary file not shown.

View file

@ -0,0 +1,57 @@
/*
stm32flash - Open Source ST STM32 flash program for *nix
Copyright (C) 2010 Geoffrey McRae <geoff@spacevs.com>
This program 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 2
of the License, or (at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _H_PARSER
#define _H_PARSER
enum parser_err {
PARSER_ERR_OK,
PARSER_ERR_SYSTEM,
PARSER_ERR_INVALID_FILE,
PARSER_ERR_WRONLY,
PARSER_ERR_RDONLY
};
typedef enum parser_err parser_err_t;
struct parser {
const char *name;
void* (*init )(); /* initialise the parser */
parser_err_t (*open )(void *storage, const char *filename, const char write); /* open the file for read|write */
parser_err_t (*close)(void *storage); /* close and free the parser */
unsigned int (*base )(void *storage); /* get the base address */
unsigned int (*size )(void *storage); /* get the total data size */
parser_err_t (*read )(void *storage, void *data, unsigned int *len); /* read a block of data */
parser_err_t (*write)(void *storage, void *data, unsigned int len); /* write a block of data */
};
typedef struct parser parser_t;
static inline const char* parser_errstr(parser_err_t err) {
switch(err) {
case PARSER_ERR_OK : return "OK";
case PARSER_ERR_SYSTEM : return "System Error";
case PARSER_ERR_INVALID_FILE: return "Invalid File";
case PARSER_ERR_WRONLY : return "Parser can only write";
case PARSER_ERR_RDONLY : return "Parser can only read";
default:
return "Unknown Error";
}
}
#endif

Binary file not shown.