Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disabling code or data flash. Intel HEX support. #12

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 41 additions & 8 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ const char *usage =
"\t-e\tErase memory\n"
"\t-w\tWrite memory\n"
"\t-c\tVerify memory\n"
"\t-x\tDisable Data Flash\n"
"\t-y\tDisable Code Flash\n"
"\t-r\tReset MCU (switch to RUN mode)\n"
"\t-d\tDelay bootloader initialization till keypress\n"
"\t-b baud\tSet baudrate (supported baudrates: 115200, 250000, 500000, 1000000)\n"
Expand All @@ -48,6 +50,10 @@ const char *usage =
"\t\t\tn=4 Two-wire UART, Reset by RTS\n"
"\t\t\tdefault: n=1\n"
"\t-n\tInvert reset\n"
"\t-f n\tSet file format\n"
"\t\t\tn=0 S-record\n"
"\t\t\tn=1 Intel Hex\n"
"\t\t\tdefault: n=0\n"
"\t-p v\tSpecify power supply voltage\n"
"\t\t\tdefault: 3.3\n"
"\t-t baud\tStart terminal with specified baudrate\n"
Expand All @@ -67,13 +73,22 @@ int main(int argc, char *argv[])
float voltage = 3.3f;
char terminal = 0;
int terminal_baud = 0;
char nodata = 0;
char nocode = 0;
char file_format = 0;

char *endp;
int opt;
while ((opt = getopt(argc, argv, "ab:cvwrdeim:np:t:h?")) != -1)
while ((opt = getopt(argc, argv, "f:xyab:cvwrdeim:np:t:h?")) != -1)
{
switch (opt)
{
case 'x':
nodata = 1;
break;
case 'y':
nocode = 1;
break;
case 'a':
erase = 1;
write = 1;
Expand All @@ -100,6 +115,17 @@ int main(int argc, char *argv[])
return EINVAL;
}
break;
case 'f':
file_format = strtol(optarg, &endp, 10);
if (optarg == endp
|| FILE_FORMAT_MAX_VALUE < mode
|| FILE_FORMAT_MIN_VALUE > mode)
{
fprintf(stderr, "Invalid file format\n");
printf("%s", usage);
return EINVAL;
}
break;
case 't':
terminal = 1;
terminal_baud = strtol(optarg, &endp, 10);
Expand Down Expand Up @@ -243,7 +269,7 @@ int main(int argc, char *argv[])
device_name, code_size / 1024, data_size / 1024
);
}
if (1 == erase)
if (!nocode && (1 == erase))
{
if (1 <= verbose_level)
{
Expand All @@ -257,7 +283,7 @@ int main(int argc, char *argv[])
break;
}
}
if (1 == erase && data_size)
if (!nodata && (1 == erase && data_size))
{
if (1 <= verbose_level)
{
Expand All @@ -282,15 +308,22 @@ int main(int argc, char *argv[])
{
printf("Read file \"%s\"\n", filename);
}
rc = srec_read(filename, code, code_size, data, data_size);
if (FILE_FORMAT_IHEX == file_format)
{
rc = ihex_read(filename, code, code_size, data, data_size);
}
else
{
rc = srec_read(filename, code, code_size, data, data_size);
}
if (0 != rc)
{
fprintf(stderr, "Read failed\n");
retcode = EIO;
break;
}
}
if (1 == write)
if (!nocode && (1 == write))
{
if (1 <= verbose_level)
{
Expand All @@ -304,7 +337,7 @@ int main(int argc, char *argv[])
break;
}
}
if (1 == write && data_size)
if (!nodata && (1 == write && data_size))
{
if (1 <= verbose_level)
{
Expand All @@ -318,7 +351,7 @@ int main(int argc, char *argv[])
break;
}
}
if (1 == verify)
if (!nocode && (1 == verify))
{
if (1 <= verbose_level)
{
Expand All @@ -332,7 +365,7 @@ int main(int argc, char *argv[])
break;
}
}
if (1 == verify && data_size)
if (!nodata && (1 == verify && data_size))
{
if (1 <= verbose_level)
{
Expand Down
25 changes: 24 additions & 1 deletion src/main_g10.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ const char *usage =
"\t\t\tn=2 Single-wire UART, Reset by RTS\n"
"\t\t\tdefault: n=1\n"
"\t-n\tInvert reset\n"
"\t-f n\tSet file format\n"
"\t\t\tn=0 S-record\n"
"\t\t\tn=1 Intel Hex\n"
"\t\t\tdefault: n=0\n"
"\t-t baud\tStart terminal with specified baudrate\n"
"\t-v\tVerbose mode\n"
"\t-h\tDisplay help\n";
Expand All @@ -55,6 +59,7 @@ int main(int argc, char *argv[])
char invert_reset = 0;
char terminal = 0;
int terminal_baud = 0;
char file_format = 0;

char *endp;
int opt;
Expand All @@ -77,6 +82,17 @@ int main(int argc, char *argv[])
return EINVAL;
}
break;
case 'f':
file_format = strtol(optarg, &endp, 10);
if (optarg == endp
|| FILE_FORMAT_MAX_VALUE < mode
|| FILE_FORMAT_MIN_VALUE > mode)
{
fprintf(stderr, "Invalid file format\n");
printf("%s", usage);
return EINVAL;
}
break;
case 't':
terminal = 1;
terminal_baud = strtol(optarg, &endp, 10);
Expand Down Expand Up @@ -209,7 +225,14 @@ int main(int argc, char *argv[])
{
printf("Read file \"%s\"\n", filename);
}
rc = srec_read(filename, code, codesize, NULL, 0);
if (FILE_FORMAT_IHEX == file_format)
{
rc = ihex_read(filename, code, codesize, NULL, 0);
}
else
{
rc = srec_read(filename, code, codesize, NULL, 0);
}
if (0 != rc)
{
fprintf(stderr, "Read failed\n");
Expand Down
121 changes: 121 additions & 0 deletions src/srec.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,3 +164,124 @@ int srec_read(const char *filename,
fclose(pfile);
return rc;
}

int ihex_read(const char *filename,
void *code, unsigned int code_len,
void *data, unsigned int data_len)
{
FILE *pfile;
char line[512];
int rc = SREC_NO_ERROR;
unsigned int extended_address = 0;
pfile = fopen(filename, "r");
if (NULL == pfile)
{
fprintf(stderr, "Unable to open file \"%s\"\n", filename);
return SREC_IO_ERROR;
}
rewind(pfile);
while (!feof(pfile))
{
if (NULL == fgets(line, sizeof line, pfile))
{
if (ferror(pfile))
{
fprintf(stderr, "Unable to read file \"%s\"\n", filename);
rc = SREC_IO_ERROR;
}
break;
}
const size_t len = strlen(line);
if (0 == len || '\n' != line[len - 1])
{
fprintf(stderr, "Unable to parse file: line is too long\n");
rc = SREC_IO_ERROR;
}
if (4 <= verbose_level)
{
printf("ihex: %s\n", line);
}
if (':' != line[0])
{
fprintf(stderr, "File format error (\"%s\")\n", line);
rc = SREC_FORMAT_ERROR;
break;
}
// Ignore non-data frames
const unsigned int record_type = ascii2hex(&line[7], 2);
if (0 != record_type
&& 2 != record_type
&& 4 != record_type)
{
if (4 <= verbose_level)
{
printf("Record with no data (%u)\n", record_type);
}
continue;
}
unsigned int address = ascii2hex(&line[3], 4) + extended_address;
const int data_length = ascii2hex(&line[1], 2); // in bytes
const char *data_p = line + 9;
unsigned char *memory;

if (2 == record_type
|| 4 == record_type)
{
extended_address = ascii2hex(&line[9], 4) << ((4 == record_type) ? 16 : 4);
if (4 <= verbose_level)
{
printf("Extended address (%06X)\n", extended_address);
}
continue;
}
else if ((CODE_OFFSET + code_len) >= (address + data_length))
{
if (NULL == code)
{
continue;
}
memory = (unsigned char*)code;
address -= CODE_OFFSET;
if (4 <= verbose_level)
{
printf("ihex_code (%06X) : ", address);
}
}
else if (DATA_OFFSET <= address
&& (DATA_OFFSET + data_len) >= (address + data_length))
{
if (NULL == data)
{
continue;
}
memory = (unsigned char*)data;
address -= DATA_OFFSET;
if (4 <= verbose_level)
{
printf("ihex_data (%06X) : ", address);
}
}
else
{
rc = SREC_MEMORY_ERROR;
break;
}
unsigned int i = data_length;
for(; 0 < i; --i)
{
memory[address] = ascii2hex(data_p, 2);
if (4 <= verbose_level)
{
printf("%02X ", memory[address]);
}
++address;
data_p += 2;
}
if (4 <= verbose_level)
{
printf("\n");
}
}
fclose(pfile);
return rc;
}
9 changes: 9 additions & 0 deletions src/srec.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,19 @@
#define SREC_H__

int srec_read(const char *filename, void *code, unsigned int code_len, void *data, unsigned int data_len);
int ihex_read(const char *filename, void *code, unsigned int code_len, void *data, unsigned int data_len);


#define SREC_NO_ERROR (0)
#define SREC_IO_ERROR (-1)
#define SREC_FORMAT_ERROR (-2)
#define SREC_MEMORY_ERROR (-3)

#define FILE_FORMAT_SREC 0
#define FILE_FORMAT_IHEX 1

#define FILE_FORMAT_MIN_VALUE 0
#define FILE_FORMAT_MAX_VALUE 1


#endif // SREC_H__