FreeCalypso > hg > freecalypso-tools
view loadtools/ltdump.c @ 407:19e5a3e2f9c0
fcup-settime: moved time() retrieval a little closer to the output
A fundamental problem with all simple time transfer tools is that there is
always some delay between the time retrieval on the source system and that
transmitted time being set on the destination, and the resulting time
on the destination system is off by that delay amount. This delay cannot
be fully eliminated when working in a simple environment like ours,
but we should make our best effort to minimize it. In the present case,
moving the atinterf_init() call before the time() retrieval should make
a teensy-tiny improvement.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 11 Aug 2018 21:52:17 +0000 |
parents | e7502631a0f9 |
children | 98474043ecdd |
line wrap: on
line source
/* * This module implements the dump2bin and dump2srec functionality * of fc-loadtool. */ #include <sys/types.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include <time.h> extern uint32_t crc32_table[]; extern char target_response_line[]; crc32_on_target(area_base, area_len, retptr) u_long area_base, area_len, *retptr; { char arg1[10], arg2[10], *argv[4]; int stat; char *strtoul_endp; sprintf(arg1, "%lx", area_base); sprintf(arg2, "%lx", area_len); argv[0] = "crc32"; argv[1] = arg1; argv[2] = arg2; argv[3] = 0; tpinterf_make_cmd(argv); if (tpinterf_send_cmd() < 0) return(-1); stat = tpinterf_capture_output_oneline(10); /* 10 s timeout */ if (stat != 1) { errout: fprintf(stderr, "error: malformed response to crc32 command\n"); return(-1); } if (strlen(target_response_line) != 8) goto errout; *retptr = strtoul(target_response_line, &strtoul_endp, 16); if (strtoul_endp != target_response_line + 8) goto errout; return(0); } cmd_crc32(argc, argv) char **argv; { u_long area_base, area_len; char *strtoul_endp; u_long crc_result; int stat; area_base = strtoul(argv[1], &strtoul_endp, 16); if (*strtoul_endp) { inv: fprintf(stderr, "usage: crc32 hex-start hex-len\n"); return(-1); } area_len = strtoul(argv[2], &strtoul_endp, 16); if (*strtoul_endp) goto inv; stat = crc32_on_target(area_base, area_len, &crc_result); if (stat == 0) printf("%08lX\n", crc_result); return(stat); } /* the actual dump facility */ static FILE *dump_outfile; static int dump_save_srec; static uint32_t dump_nextaddr, dump_crcaccum; static uint32_t dump_total_len, dump_progress_len; static u_char dump_binrec[0x86]; static time_t dump_last_time; static char dumpsrec_s0_line[] = "S007000044554D50C2\n"; static char dumpsrec_s7_line[] = "S70500000000FA\n"; static dump_receiver(line) char *line; { int i, b; u_char sr_cksum; uint32_t addr_from_srec; time_t curtime; if (strncmp(line, "S385", 4)) { fprintf(stderr, "error: target response is not the expected S385...\n"); return(-1); } for (i = 0; i < 0x86; i++) { b = decode_hex_byte(line + i*2 + 2); if (b < 0) { fprintf(stderr, "data from target: S-record hex decode error\n"); return(-1); } dump_binrec[i] = b; } sr_cksum = 0; for (i = 0; i < 0x86; i++) sr_cksum += dump_binrec[i]; if (sr_cksum != 0xFF) { fprintf(stderr, "data from target: bad S-record checksum\n"); return(-1); } /* basic S-record format OK; now verify the address */ addr_from_srec = ((uint32_t) dump_binrec[1] << 24) | ((uint32_t) dump_binrec[2] << 16) | ((uint32_t) dump_binrec[3] << 8) | (uint32_t) dump_binrec[4]; if (addr_from_srec != dump_nextaddr) { fprintf(stderr, "error: S3 record from target has the wrong address\n"); return(-1); } /* all checks passed - save it */ if (dump_save_srec) { if (!dump_progress_len) fputs(dumpsrec_s0_line, dump_outfile); fprintf(dump_outfile, "%s\n", line); } else fwrite(dump_binrec + 5, 1, 0x80, dump_outfile); /* update running CRC */ for (i = 0; i < 0x80; i++) dump_crcaccum = crc32_table[dump_crcaccum & 0xFF ^ dump_binrec[i+5]] ^ (dump_crcaccum >> 8); /* progress indication */ dump_progress_len += 0x80; i = dump_progress_len * 100 / dump_total_len; time(&curtime); if (curtime != dump_last_time || i == 100) { printf("\rRx %lu out of %lu bytes (%i%%)", (u_long) dump_progress_len, (u_long) dump_total_len, i); fflush(stdout); } dump_nextaddr += 0x80; dump_last_time = curtime; return(1); } loadtool_memdump(start_addr, area_len, filename, fmt_srec) u_long start_addr, area_len; char *filename; { u_long target_crc_init, target_crc_fin; char *target_argv[4], target_arg1[10], target_arg2[10]; int stat; if (start_addr & 0x7F || area_len & 0x7F) { fprintf(stderr, "error: implementation limit: 128-byte alignment required\n"); return(-1); } printf("Requesting initial CRC-32 of the area from target...\n"); stat = crc32_on_target(start_addr, area_len, &target_crc_init); if (stat) return(stat); printf("got %08lX\n", target_crc_init); dump_outfile = fopen(filename, "w"); if (!dump_outfile) { perror(filename); return(-1); } dump_save_srec = fmt_srec; dump_nextaddr = start_addr; dump_crcaccum = 0xFFFFFFFF; dump_total_len = area_len; dump_progress_len = 0; printf("Requesting memory dump...\n"); sprintf(target_arg1, "%lx", start_addr); sprintf(target_arg2, "%lx", area_len); target_argv[0] = "DUMP"; target_argv[1] = target_arg1; target_argv[2] = target_arg2; target_argv[3] = 0; tpinterf_make_cmd(target_argv); stat = tpinterf_send_cmd(); if (stat < 0) { fclose(dump_outfile); return(stat); } stat = tpinterf_capture_output(2, dump_receiver); if (stat < 0) { fclose(dump_outfile); return(stat); } putchar('\n'); /* after last progress line */ /* sanity checks */ if (dump_nextaddr != start_addr + area_len) { fclose(dump_outfile); fprintf(stderr, "error: received dump length does not match expected\n"); return(-1); } if (dump_crcaccum != (uint32_t) target_crc_init) { fclose(dump_outfile); fprintf(stderr, "error: CRC mismatch (computed %lX)\n", (u_long) dump_crcaccum); return(-1); } if (fmt_srec) fputs(dumpsrec_s7_line, dump_outfile); fclose(dump_outfile); printf("Requesting another CRC-32 of the area from target...\n"); stat = crc32_on_target(start_addr, area_len, &target_crc_fin); if (stat) return(stat); if (target_crc_fin == target_crc_init) { printf("match, dump successful\n"); return(0); } else { fprintf(stderr, "mismatch: got %lX this time\n", target_crc_fin); return(-1); } } cmd_dump2bin(argc, argv) char **argv; { u_long area_base, area_len; char *strtoul_endp; area_base = strtoul(argv[1], &strtoul_endp, 16); if (*strtoul_endp) { inv: fprintf(stderr, "usage: dump2bin hex-start hex-len outfile\n"); return(-1); } area_len = strtoul(argv[2], &strtoul_endp, 16); if (*strtoul_endp) goto inv; return loadtool_memdump(area_base, area_len, argv[3], 0); } cmd_dump2srec(argc, argv) char **argv; { u_long area_base, area_len; char *strtoul_endp; area_base = strtoul(argv[1], &strtoul_endp, 16); if (*strtoul_endp) { inv: fprintf(stderr, "usage: dump2srec hex-start hex-len outfile\n"); return(-1); } area_len = strtoul(argv[2], &strtoul_endp, 16); if (*strtoul_endp) goto inv; return loadtool_memdump(area_base, area_len, argv[3], 1); }