Added ELF support, made all buffers u_int8_t.
This commit is contained in:
parent
34e1d2d7a1
commit
1d3b4f3f81
2
Makefile
2
Makefile
|
@ -25,7 +25,7 @@ clean:
|
|||
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
mspdebug: main.o fet.o rf2500.o dis.o uif.o
|
||||
mspdebug: main.o fet.o rf2500.o dis.o uif.o ihex.o elf32.o
|
||||
$(CC) $(CFLAGS) -o $@ $^ -lusb
|
||||
|
||||
.c.o:
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/* MSPDebug - debugging tool for the eZ430
|
||||
* Copyright (C) 2009 Daniel Beer
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef BINFILE_H_
|
||||
#define BINFILE_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Callback for binary image data */
|
||||
typedef int (*imgfunc_t)(u_int16_t addr, const u_int8_t *data, int len);
|
||||
|
||||
/* Intel HEX file support */
|
||||
int ihex_check(FILE *in);
|
||||
int ihex_extract(FILE *in, imgfunc_t cb);
|
||||
|
||||
/* ELF32 file support */
|
||||
int elf32_check(FILE *in);
|
||||
int elf32_extract(FILE *in, imgfunc_t cb);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,192 @@
|
|||
/* MSPDebug - debugging tool for the eZ430
|
||||
* Copyright (C) 2009 Daniel Beer
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <elf.h>
|
||||
#include "binfile.h"
|
||||
|
||||
#define EM_MSP430 0x69
|
||||
|
||||
static const u_int8_t elf32_id[] = {
|
||||
ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS32
|
||||
};
|
||||
|
||||
#define MAX_PHDRS 32
|
||||
#define MAX_SHDRS 32
|
||||
|
||||
static Elf32_Ehdr file_ehdr;
|
||||
static Elf32_Phdr file_phdrs[MAX_PHDRS];
|
||||
static Elf32_Shdr file_shdrs[MAX_SHDRS];
|
||||
|
||||
static int read_ehdr(FILE *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Read and check the ELF header */
|
||||
rewind(in);
|
||||
if (fread(&file_ehdr, sizeof(file_ehdr), 1, in) < 0) {
|
||||
perror("elf32: couldn't read ELF header");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < sizeof(elf32_id); i++)
|
||||
if (file_ehdr.e_ident[i] != elf32_id[i]) {
|
||||
fprintf(stderr, "elf32: not an ELF32 file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_phdr(FILE *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (file_ehdr.e_phnum > MAX_PHDRS) {
|
||||
fprintf(stderr, "elf32: too many program headers: %d\n",
|
||||
file_ehdr.e_phnum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < file_ehdr.e_phnum; i++) {
|
||||
if (fseek(in, i * file_ehdr.e_phentsize + file_ehdr.e_phoff,
|
||||
SEEK_SET) < 0) {
|
||||
fprintf(stderr, "elf32: can't seek to phdr %d\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(&file_phdrs[i], sizeof(file_phdrs[0]), 1, in) < 0) {
|
||||
fprintf(stderr, "elf32: can't read phdr %d: %s\n",
|
||||
i, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_shdr(FILE *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (file_ehdr.e_shnum > MAX_SHDRS) {
|
||||
fprintf(stderr, "elf32: too many section headers: %d\n",
|
||||
file_ehdr.e_shnum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < file_ehdr.e_shnum; i++) {
|
||||
if (fseek(in, i * file_ehdr.e_shentsize + file_ehdr.e_shoff,
|
||||
SEEK_SET) < 0) {
|
||||
fprintf(stderr, "elf32: can't seek to phdr %d\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fread(&file_shdrs[i], sizeof(file_shdrs[0]), 1, in) < 0) {
|
||||
fprintf(stderr, "elf32: can't read phdr %d: %s\n",
|
||||
i, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u_int32_t file_to_phys(u_int32_t v)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < file_ehdr.e_phnum; i++) {
|
||||
Elf32_Phdr *p = &file_phdrs[i];
|
||||
|
||||
if (v >= p->p_offset && v - p->p_offset < p->p_filesz)
|
||||
return v - p->p_offset + p->p_paddr;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static int feed_section(FILE *in, int offset, int size, imgfunc_t cb)
|
||||
{
|
||||
u_int8_t buf[1024];
|
||||
u_int16_t addr = file_to_phys(offset);
|
||||
|
||||
if (fseek(in, offset, SEEK_SET) < 0) {
|
||||
perror("elf32: can't seek to section");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (size) {
|
||||
int ask = size > sizeof(buf) ? sizeof(buf) : size;
|
||||
int len = fread(buf, 1, ask, in);
|
||||
|
||||
if (len < 0) {
|
||||
perror("elf32: can't read section");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cb(addr, buf, len) < 0)
|
||||
return -1;
|
||||
|
||||
size -= len;
|
||||
offset += len;
|
||||
addr += len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elf32_extract(FILE *in, imgfunc_t cb)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (read_ehdr(in) < 0)
|
||||
return -1;
|
||||
if (file_ehdr.e_machine != EM_MSP430) {
|
||||
fprintf(stderr, "elf32: this is not an MSP430 ELF32\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (read_phdr(in) < 0)
|
||||
return -1;
|
||||
if (read_shdr(in) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < file_ehdr.e_shnum; i++) {
|
||||
Elf32_Shdr *s = &file_shdrs[i];
|
||||
|
||||
if (s->sh_type == SHT_PROGBITS && s->sh_flags & SHF_ALLOC &&
|
||||
feed_section(in, s->sh_offset, s->sh_size, cb) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int elf32_check(FILE *in)
|
||||
{
|
||||
int i;
|
||||
|
||||
rewind(in);
|
||||
for (i = 0; i < sizeof(elf32_id); i++)
|
||||
if (fgetc(in) != elf32_id[i])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
28
fet.c
28
fet.c
|
@ -105,7 +105,7 @@ static void init_codes(void)
|
|||
* needs to be stored in little-endian format at the end of the payload.
|
||||
*/
|
||||
|
||||
static u_int16_t calc_checksum(const char *data, int len)
|
||||
static u_int16_t calc_checksum(const u_int8_t *data, int len)
|
||||
{
|
||||
int i;
|
||||
u_int16_t cksum = 0xffff;
|
||||
|
@ -140,13 +140,13 @@ static u_int16_t calc_checksum(const char *data, int len)
|
|||
*
|
||||
* No checksums are included.
|
||||
*/
|
||||
static int send_rf2500_data(const char *data, int len)
|
||||
static int send_rf2500_data(const u_int8_t *data, int len)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
assert (fet_transport != NULL);
|
||||
while (len) {
|
||||
char pbuf[63];
|
||||
u_int8_t pbuf[63];
|
||||
int plen = len > 59 ? 59 : len;
|
||||
|
||||
pbuf[0] = 0x83;
|
||||
|
@ -165,7 +165,7 @@ static int send_rf2500_data(const char *data, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char fet_buf[65538];
|
||||
static u_int8_t fet_buf[65538];
|
||||
static int fet_len;
|
||||
|
||||
#define MAX_PARAMS 16
|
||||
|
@ -178,7 +178,7 @@ static struct {
|
|||
int argc;
|
||||
u_int32_t argv[MAX_PARAMS];
|
||||
|
||||
char *data;
|
||||
u_int8_t *data;
|
||||
int datalen;
|
||||
} fet_reply;
|
||||
|
||||
|
@ -372,12 +372,12 @@ static int recv_packet(void)
|
|||
|
||||
static int send_command(int command_code,
|
||||
const u_int32_t *params, int nparams,
|
||||
const char *extra, int exlen)
|
||||
const u_int8_t *extra, int exlen)
|
||||
{
|
||||
char datapkt[256];
|
||||
u_int8_t datapkt[256];
|
||||
int len = 0;
|
||||
|
||||
char buf[512];
|
||||
u_int8_t buf[512];
|
||||
u_int16_t cksum;
|
||||
int i = 0;
|
||||
int j;
|
||||
|
@ -449,7 +449,7 @@ static int send_command(int command_code,
|
|||
return fet_transport->send(buf, i);
|
||||
}
|
||||
|
||||
static int xfer(int command_code, const char *data, int datalen,
|
||||
static int xfer(int command_code, const u_int8_t *data, int datalen,
|
||||
int nparams, ...)
|
||||
{
|
||||
u_int32_t params[MAX_PARAMS];
|
||||
|
@ -534,7 +534,7 @@ static const struct {
|
|||
}
|
||||
};
|
||||
|
||||
extern void hexdump(int addr, const char *data, int len);
|
||||
extern void hexdump(int addr, const u_int8_t *data, int len);
|
||||
|
||||
static int do_identify(void)
|
||||
{
|
||||
|
@ -633,7 +633,7 @@ int fet_open(const struct fet_transport *tr, int proto_flags, int vcc_mv)
|
|||
* This is RF2500-specific.
|
||||
*/
|
||||
if (fet_is_rf2500) {
|
||||
static const char data[] = {
|
||||
static const u_int8_t data[] = {
|
||||
0x00, 0x80, 0xff, 0xff, 0x00, 0x00, 0x00, 0x10,
|
||||
0xff, 0x10, 0x40, 0x00, 0x00, 0x02, 0xff, 0x05,
|
||||
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00,
|
||||
|
@ -703,7 +703,7 @@ int fet_get_context(u_int16_t *regs)
|
|||
|
||||
int fet_set_context(u_int16_t *regs)
|
||||
{
|
||||
char buf[FET_NUM_REGS * 4];
|
||||
u_int8_t buf[FET_NUM_REGS * 4];;
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
|
@ -729,7 +729,7 @@ int fet_set_context(u_int16_t *regs)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fet_read_mem(u_int16_t addr, char *buffer, int count)
|
||||
int fet_read_mem(u_int16_t addr, u_int8_t *buffer, int count)
|
||||
{
|
||||
while (count) {
|
||||
int plen = count > 128 ? 128 : count;
|
||||
|
@ -755,7 +755,7 @@ int fet_read_mem(u_int16_t addr, char *buffer, int count)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int fet_write_mem(u_int16_t addr, char *buffer, int count)
|
||||
int fet_write_mem(u_int16_t addr, const u_int8_t *buffer, int count)
|
||||
{
|
||||
while (count) {
|
||||
int plen = count > 128 ? 128 : count;
|
||||
|
|
8
fet.h
8
fet.h
|
@ -39,8 +39,8 @@ int rf2500_open(void);
|
|||
* high-level functions.
|
||||
*/
|
||||
struct fet_transport {
|
||||
int (*send)(const char *data, int len);
|
||||
int (*recv)(char *data, int max_len);
|
||||
int (*send)(const u_int8_t *data, int len);
|
||||
int (*recv)(u_int8_t *data, int max_len);
|
||||
void (*close)(void);
|
||||
};
|
||||
|
||||
|
@ -90,8 +90,8 @@ int fet_erase(int type, u_int16_t addr, int len);
|
|||
/* Read and write memory. fet_write_mem can be used to reflash the
|
||||
* device, but only after an erase.
|
||||
*/
|
||||
int fet_read_mem(u_int16_t addr, char *buffer, int count);
|
||||
int fet_write_mem(u_int16_t addr, char *buffer, int count);
|
||||
int fet_read_mem(u_int16_t addr, u_int8_t *buffer, int count);
|
||||
int fet_write_mem(u_int16_t addr, const u_int8_t *buffer, int count);
|
||||
|
||||
/* Fetch the device status. If the device is currently running, then
|
||||
* the FET_POLL_RUNNING flag will be set. FET_POLL_BREAKPOINT is set
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/* MSPDebug - debugging tool for the eZ430
|
||||
* Copyright (C) 2009 Daniel Beer
|
||||
*
|
||||
* 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 St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "binfile.h"
|
||||
|
||||
int ihex_check(FILE *in)
|
||||
{
|
||||
rewind(in);
|
||||
return fgetc(in) == ':';
|
||||
}
|
||||
|
||||
static int feed_line(FILE *in, u_int8_t *data, int nbytes, imgfunc_t cb)
|
||||
{
|
||||
u_int8_t cksum = 0;
|
||||
int i;
|
||||
|
||||
if (nbytes < 5 || data[3])
|
||||
return 0;
|
||||
|
||||
/* Verify checksum */
|
||||
for (i = 0; i + 1 < nbytes; i++)
|
||||
cksum += data[i];
|
||||
cksum = ~(cksum - 1) & 0xff;
|
||||
|
||||
if (data[nbytes - 1] != cksum) {
|
||||
fprintf(stderr, "ihex: invalid checksum: %02x "
|
||||
"(calculated %02x)\n", data[nbytes - 1], cksum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return cb(((u_int16_t)data[1]) << 8 | ((u_int16_t)data[2]),
|
||||
data + 4, nbytes - 5);
|
||||
}
|
||||
|
||||
int ihex_extract(FILE *in, imgfunc_t cb)
|
||||
{
|
||||
char buf[128];
|
||||
int lno = 0;
|
||||
|
||||
rewind(in);
|
||||
while (fgets(buf, sizeof(buf), in)) {
|
||||
int len = strlen(buf);
|
||||
int i;
|
||||
u_int8_t data[64];
|
||||
int nbytes;
|
||||
|
||||
lno++;
|
||||
if (buf[0] != ':') {
|
||||
fprintf(stderr, "ihex: line %d: invalid start "
|
||||
"marker\n", lno);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Trim trailing whitespace */
|
||||
while (len && isspace(buf[len - 1]))
|
||||
len--;
|
||||
buf[len] = 0;
|
||||
|
||||
/* Decode hex digits */
|
||||
nbytes = (len - 1) / 2;
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
char d[] = {buf[i * 2 + 1], buf[i * 2 + 2], 0};
|
||||
|
||||
data[i] = strtoul(d, NULL, 16);
|
||||
}
|
||||
|
||||
/* Handle the line */
|
||||
if (feed_line(in, data, nbytes, cb) < 0) {
|
||||
fprintf(stderr, "ihex: error on line %d\n", lno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
154
main.c
154
main.c
|
@ -26,8 +26,9 @@
|
|||
|
||||
#include "dis.h"
|
||||
#include "fet.h"
|
||||
#include "binfile.h"
|
||||
|
||||
void hexdump(int addr, const char *data, int len)
|
||||
void hexdump(int addr, const u_int8_t *data, int len)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
|
@ -145,7 +146,7 @@ static int cmd_md(char **arg)
|
|||
}
|
||||
|
||||
while (length) {
|
||||
char buf[128];
|
||||
u_int8_t buf[128];
|
||||
int blen = length > sizeof(buf) ? sizeof(buf) : length;
|
||||
|
||||
if (fet_read_mem(offset, buf, blen) < 0)
|
||||
|
@ -202,7 +203,7 @@ static int cmd_dis(char **arg)
|
|||
char *len_text = get_arg(arg);
|
||||
unsigned int offset = 0;
|
||||
unsigned int length = 0;
|
||||
char buf[128];
|
||||
u_int8_t buf[128];
|
||||
|
||||
if (!off_text) {
|
||||
fprintf(stderr, "md: offset must be specified\n");
|
||||
|
@ -235,7 +236,7 @@ static int cmd_reset(char **arg)
|
|||
static int cmd_regs(char **arg)
|
||||
{
|
||||
u_int16_t regs[FET_NUM_REGS];
|
||||
char code[16];
|
||||
u_int8_t code[16];
|
||||
|
||||
if (fet_get_context(regs) < 0)
|
||||
return -1;
|
||||
|
@ -325,107 +326,76 @@ static int cmd_step(char **arg)
|
|||
return cmd_regs(NULL);
|
||||
}
|
||||
|
||||
static int hexval(const char *text, int len)
|
||||
{
|
||||
int value = 0;
|
||||
/************************************************************************
|
||||
* Flash image programming state machine.
|
||||
*/
|
||||
|
||||
while (len && *text) {
|
||||
value <<= 4;
|
||||
|
||||
if (*text >= 'A' && *text <= 'F')
|
||||
value += *text - 'A' + 10;
|
||||
else if (*text >= 'a' && *text <= 'f')
|
||||
value += *text - 'a' + 10;
|
||||
else if (isdigit(*text))
|
||||
value += *text - '0';
|
||||
|
||||
text++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static char prog_buf[128];
|
||||
static u_int8_t prog_buf[128];
|
||||
static u_int16_t prog_addr;
|
||||
static int prog_len;
|
||||
static int prog_have_erased;
|
||||
|
||||
static void prog_init(void)
|
||||
{
|
||||
prog_len = 0;
|
||||
prog_have_erased = 0;
|
||||
}
|
||||
|
||||
static int prog_flush(void)
|
||||
{
|
||||
while (prog_len) {
|
||||
int wlen = prog_len;
|
||||
|
||||
if (!prog_len)
|
||||
return 0;
|
||||
|
||||
/* Writing across this address seems to cause a hang */
|
||||
if (prog_addr < 0x999a && wlen + prog_addr > 0x999a)
|
||||
wlen = 0x999a - prog_addr;
|
||||
|
||||
printf("Writing %3d bytes to %04x...\n", wlen, prog_addr);
|
||||
if (!prog_have_erased) {
|
||||
printf("Erasing...\n");
|
||||
if (fet_erase(FET_ERASE_ALL, 0x1000, 0x100) < 0)
|
||||
return -1;
|
||||
prog_have_erased = 1;
|
||||
}
|
||||
|
||||
printf("Writing %3d bytes to %04x...\n", wlen, prog_addr);
|
||||
if (fet_write_mem(prog_addr, prog_buf, wlen) < 0)
|
||||
return -1;
|
||||
|
||||
memmove(prog_buf, prog_buf + wlen, prog_len - wlen);
|
||||
prog_len -= wlen;
|
||||
prog_addr += wlen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int prog_hex(int lno, const char *hex)
|
||||
static int prog_feed(u_int16_t addr, const u_int8_t *data, int len)
|
||||
{
|
||||
int len = strlen(hex);
|
||||
int count, address, type, cksum = 0;
|
||||
int i;
|
||||
|
||||
if (*hex != ':')
|
||||
return 0;
|
||||
|
||||
hex++;
|
||||
len--;
|
||||
|
||||
while (len && isspace(hex[len - 1]))
|
||||
len--;
|
||||
|
||||
if (len < 10)
|
||||
return 0;
|
||||
|
||||
count = hexval(hex, 2);
|
||||
address = hexval(hex + 2, 4);
|
||||
type = hexval(hex + 6, 2);
|
||||
|
||||
if (type)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i + 2 < len; i += 2)
|
||||
cksum = (cksum + hexval(hex + i, 2))
|
||||
& 0xff;
|
||||
cksum = ~(cksum - 1) & 0xff;
|
||||
|
||||
if (count * 2 + 10 != len) {
|
||||
fprintf(stderr, "warning: length mismatch at line %d\n", lno);
|
||||
count = (len - 10) / 2;
|
||||
}
|
||||
|
||||
if (cksum != hexval(hex + len - 2, 2))
|
||||
fprintf(stderr, "warning: invalid checksum at line %d\n", lno);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
int offset;
|
||||
|
||||
offset = address + i - prog_addr;
|
||||
if (offset < 0 || offset >= sizeof(prog_buf))
|
||||
if (prog_flush() < 0)
|
||||
/* Flush if this section is discontiguous */
|
||||
if (prog_len && prog_addr + prog_len != addr && prog_flush() < 0)
|
||||
return -1;
|
||||
|
||||
if (!prog_len)
|
||||
prog_addr = address + i;
|
||||
prog_addr = addr;
|
||||
|
||||
offset = address + i - prog_addr;
|
||||
prog_buf[offset] = hexval(hex + 8 + i * 2, 2);
|
||||
if (offset + 1 > prog_len)
|
||||
prog_len = offset + 1;
|
||||
/* Add the buffer in piece by piece, flushing when it gets
|
||||
* full.
|
||||
*/
|
||||
while (len) {
|
||||
int count = sizeof(prog_buf) - prog_len;
|
||||
|
||||
if (count > len)
|
||||
count = len;
|
||||
|
||||
if (!count) {
|
||||
if (prog_flush() < 0)
|
||||
return -1;
|
||||
} else {
|
||||
memcpy(prog_buf + prog_len, data, count);
|
||||
prog_len += count;
|
||||
data += count;
|
||||
len -= count;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -434,35 +404,31 @@ static int prog_hex(int lno, const char *hex)
|
|||
static int cmd_prog(char **arg)
|
||||
{
|
||||
FILE *in = fopen(*arg, "r");
|
||||
char text[256];
|
||||
int lno = 1;
|
||||
int result = 0;
|
||||
|
||||
if (!in) {
|
||||
fprintf(stderr, "prog: %s: %s\n", *arg, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("Erasing...\n");
|
||||
if (fet_erase(FET_ERASE_ALL, 0x1000, 0x100) < 0) {
|
||||
if (fet_reset(FET_RESET_ALL | FET_RESET_HALT) < 0) {
|
||||
fclose(in);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fet_reset(FET_RESET_ALL | FET_RESET_HALT) < 0)
|
||||
return -1;
|
||||
prog_init();
|
||||
if (elf32_check(in))
|
||||
result = elf32_extract(in, prog_feed);
|
||||
else if (ihex_check(in))
|
||||
result = ihex_extract(in, prog_feed);
|
||||
else
|
||||
fprintf(stderr, "%s: unknown file type\n", *arg);
|
||||
|
||||
if (!result)
|
||||
result = prog_flush();
|
||||
|
||||
prog_len = 0;
|
||||
while (fgets(text, sizeof(text), in))
|
||||
if (prog_hex(lno++, text) < 0) {
|
||||
fclose(in);
|
||||
return -1;
|
||||
}
|
||||
fclose(in);
|
||||
|
||||
if (prog_flush() < 0)
|
||||
return -1;
|
||||
|
||||
return fet_reset(FET_RESET_ALL | FET_RESET_HALT);
|
||||
return result;
|
||||
}
|
||||
|
||||
static const struct command all_commands[] = {
|
||||
|
|
15
rf2500.c
15
rf2500.c
|
@ -22,7 +22,7 @@
|
|||
|
||||
#include "fet.h"
|
||||
|
||||
void hexdump(int addr, const char *data, int len);
|
||||
extern void hexdump(int addr, const u_int8_t *data, int len);
|
||||
|
||||
/*********************************************************************
|
||||
* USB transport
|
||||
|
@ -87,10 +87,10 @@ static int usbtr_open_device(struct usb_device *dev)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int usbtr_send(const char *data, int len)
|
||||
static int usbtr_send(const u_int8_t *data, int len)
|
||||
{
|
||||
while (len) {
|
||||
char pbuf[256];
|
||||
u_int8_t pbuf[256];
|
||||
int plen = len > 255 ? 255 : len;
|
||||
int txlen = plen + 1;
|
||||
|
||||
|
@ -112,7 +112,7 @@ static int usbtr_send(const char *data, int len)
|
|||
hexdump(0, pbuf, txlen);
|
||||
#endif
|
||||
if (usb_bulk_write(usbtr_handle, USB_FET_OUT_EP,
|
||||
pbuf, txlen, 10000) < 0) {
|
||||
(const char *)pbuf, txlen, 10000) < 0) {
|
||||
perror("usbtr_send");
|
||||
return -1;
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ static int usbtr_send(const char *data, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static char usbtr_buf[64];
|
||||
static u_int8_t usbtr_buf[64];
|
||||
static int usbtr_len;
|
||||
static int usbtr_offset;
|
||||
|
||||
|
@ -136,13 +136,14 @@ static void usbtr_flush(void)
|
|||
buf, sizeof(buf), 100) >= 0);
|
||||
}
|
||||
|
||||
static int usbtr_recv(char *databuf, int max_len)
|
||||
static int usbtr_recv(u_int8_t *databuf, int max_len)
|
||||
{
|
||||
int rlen;
|
||||
|
||||
if (usbtr_offset >= usbtr_len) {
|
||||
if (usb_bulk_read(usbtr_handle, USB_FET_IN_EP,
|
||||
usbtr_buf, sizeof(usbtr_buf), 10000) < 0) {
|
||||
(char *)usbtr_buf, sizeof(usbtr_buf),
|
||||
10000) < 0) {
|
||||
perror("usbtr_recv");
|
||||
return -1;
|
||||
}
|
||||
|
|
6
uif.c
6
uif.c
|
@ -28,11 +28,11 @@
|
|||
|
||||
#include "fet.h"
|
||||
|
||||
void hexdump(int addr, const char *data, int len);
|
||||
extern void hexdump(int addr, const u_int8_t *data, int len);
|
||||
|
||||
static int serial_fd = -1;
|
||||
|
||||
static int serial_send(const char *data, int len)
|
||||
static int serial_send(const u_int8_t *data, int len)
|
||||
{
|
||||
int result;
|
||||
|
||||
|
@ -60,7 +60,7 @@ static int serial_send(const char *data, int len)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int serial_recv(char *data, int max_len)
|
||||
static int serial_recv(u_int8_t *data, int max_len)
|
||||
{
|
||||
int len;
|
||||
|
||||
|
|
Loading…
Reference in New Issue