⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.cc

📁 avrrice软件用于AVR单片机的JTAG调试.
💻 CC
字号:
/* *	avarice - The "avarice" program. *	Copyright (C) 2001 Scott Finneran *	Copyright (C) 2002, 2003, 2004 Intel Corporation * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License Version 2 *	as published by the Free Software Foundation. * * *	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., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * * This file contains the main() & support for avrjtagd. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <termios.h>#include <arpa/inet.h>#include <netdb.h>#include <netinet/in.h>#include <unistd.h>#include <netinet/tcp.h>#include <fcntl.h>#include "avarice.h"#include "remote.h"#include "jtag.h"#include "gnu_getopt.h"bool ignoreInterrupts;static int makeSocket(struct sockaddr_in *name, unsigned short int port){    int sock;    int tmp;    struct protoent *protoent;    sock = socket(PF_INET, SOCK_STREAM, 0);    gdbCheck(sock);    // Allow rapid reuse of this port.    tmp = 1;    gdbCheck(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&tmp, sizeof(tmp)));    // Enable TCP keep alive process.    tmp = 1;    gdbCheck(setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char *)&tmp, sizeof(tmp)));    gdbCheck(bind(sock, (struct sockaddr *)name, sizeof(*name)));    protoent = getprotobyname("tcp");    check(protoent != NULL, "tcp protocol unknown (oops?)");    tmp = 1;    gdbCheck(setsockopt(sock, protoent->p_proto, TCP_NODELAY,			(char *)&tmp, sizeof(tmp)));    return sock;}static void initSocketAddress(struct sockaddr_in *name,			      const char *hostname, unsigned short int port){    struct hostent *hostInfo;    memset(name, 0, sizeof(*name));    name->sin_family = AF_INET;    name->sin_port = htons(port);    // Try numeric interpretation (1.2.3.4) first, then    // hostname resolution if that failed.    if (inet_aton(hostname, &name->sin_addr) == 0)    {	hostInfo = gethostbyname(hostname);	check(hostInfo != NULL, "Unknown host %s", hostname);	name->sin_addr = *(struct in_addr *)hostInfo->h_addr;    }}static void usage(const char *progname){    fprintf(stderr,	    "Usage: %s [OPTION]... [[HOST_NAME]:PORT]\n\n", progname);    fprintf(stderr, "Options:\n");    fprintf(stderr,	    "  -h, --help                  Print this message.\n");    fprintf(stderr,	    "  -d, --debug                 Enable printing of debug"	    " information.\n");    fprintf(stderr,	    "  -D, --detach                Detach once synced with JTAG ICE\n");    fprintf(stderr,	    "  -C, --capture               Capture running program.\n"	    "                                Note: debugging must have been enabled prior\n"            "                                to starting the program. (e.g., by running\n"            "                                avarice earlier)\n");    fprintf(stderr,	    "  -I, --ignore-intr           Automatically step over interrupts.\n"	    "                                Note: EXPERIMENTAL. Can not currently handle\n"            "                                devices fused for compatibility.\n");    fprintf(stderr,	    "  -f, --file <filename>       Specify a file for use with the --program and\n"            "                                --verify options. If --file is passed and\n"            "                                neither --program or --verify are given then\n"            "                                --program is implied.\n");    fprintf(stderr,	    "  -j, --jtag <devname>        Port attached to JTAG box (default: /dev/avrjtag).\n");    fprintf(stderr,            "  -B, --jtag-bitrate <rate>   Set the bitrate that the JTAG box communicates\n"            "                                with the avr target device. This must be less\n"            "                                than 1/4 of the frequency of the target. Valid\n"            "                                values are 1MHz, 500KHz, 250KHz or 125KHz.\n"            "                                (default: 1MHz)\n");    fprintf(stderr,	    "  -p, --program               Program the target.\n"	    "                                Binary filename must be specified with --file\n"	    "                                option.\n");    fprintf(stderr,            "  -v, --verify                Verify program in device against file specified\n"            "                                with --file option.\n");    fprintf(stderr,            "  -e, --erase                 Erase target.\n");    fprintf(stderr,            "  -r, --read-fuses            Read fuses bytes.\n");    fprintf(stderr,            "  -W, --write-fuses <eehhll>  Write fuses bytes.\n");    fprintf(stderr,            "  -l, --read-lockbits         Read lock bits.\n");    fprintf(stderr,            "  -L, --write-lockbits <ll>   Write lock bits.\n");    fprintf(stderr,            "  -P, --part <name>           Target device name (e.g."            " atmega16)\n\n");    fprintf(stderr,	    "HOST_NAME defaults to 0.0.0.0 (listen on any interface).\n"	    "\":PORT\" is required to put avarice into gdb server mode.\n\n");    fprintf(stderr,	    "e.g. %s --program --file test.bin --jtag /dev/ttyS0 :4242\n\n",	    progname);    exit(1);}static struct option long_opts[] = {    /* name,                 has_arg, flag,   val */    { "help",                0,       0,     'h' },    { "debug",               0,       0,     'd' },    { "version",             0,       0,     'V' },    { "program",             0,       0,     'p' },    { "verify",              0,       0,     'v' },    { "erase",               0,       0,     'e' },    { "read-fuses",          0,       0,     'r' },    { "write-fuses",         1,       0,     'W' },    { "read-lockbits",       0,       0,     'l' },    { "write-lockbits",      1,       0,     'L' },    { "part",                1,       0,     'P' },    { "jtag",                1,       0,     'j' },    { "jtag-bitrate",        1,       0,     'B' },    { "ignore-intr",         0,       0,     'I' },    { "detach",              0,       0,     'D' },    { "capture",             0,       0,     'C' },    { "file",                1,       0,     'f' },    { 0,                     0,       0,      0 }};int main(int argc, char **argv){    int sock;    struct sockaddr_in clientname;    struct sockaddr_in name;    char *inFileName = 0;    char *jtagDeviceName = "/dev/avrjtag";    uchar jtagBitrate = 0;    const char *hostName = "0.0.0.0";	/* INADDR_ANY */    int  hostPortNumber;    bool erase = false;    bool program = false;    bool readFuses = false;    bool writeFuses = false;    char *fuses;    bool readLockBits = false;    bool writeLockBits = false;    bool gdbServerMode = false;    char *lockBits;    bool detach = false;    bool capture = false;    bool verify = false;    char *progname = argv[0];    int  option_index;    statusOut("AVaRICE version %s, %s %s\n\n",	      PACKAGE_VERSION, __DATE__, __TIME__);    device_name = 0;    opterr = 0;                 /* disable default error message */        while (1)    {        int c = getopt_long (argc, argv, "VhdDCIf:j:B:pverW:lL:P:",                             long_opts, &option_index);        if (c == -1)            break;              /* no more options */        switch (c) {            case 'h':            case '?':                usage(progname);            case 'd':                debugMode = true;                break;            case 'D':                detach = true;                break;            case 'C':                capture = true;                break;            case 'I':                ignoreInterrupts = true;                break;            case 'f':                inFileName = optarg;                break;            case 'j':                jtagDeviceName = optarg;                break;            case 'B':                if (strncmp ("1MHz", optarg, 4) == 0)                    jtagBitrate = JTAG_BITRATE_1_MHz;                else if (strncmp ("500KHz", optarg, 6) == 0)                    jtagBitrate = JTAG_BITRATE_500_KHz;                else if (strncmp ("250KHz", optarg, 6) == 0)                    jtagBitrate = JTAG_BITRATE_250_KHz;                else if (strncmp ("125KHz", optarg, 6) == 0)                    jtagBitrate = JTAG_BITRATE_125_KHz;                else                {                    fprintf (stderr, "Invalid bitrate: %s\n", optarg);                    exit (1);                }                break;            case 'p':                program = true;                break;            case 'v':                verify = true;                break;            case 'e':                erase = true;                break;            case 'r':                readFuses = true;                break;            case 'W':                fuses = optarg;                writeFuses = true;                break;            case 'l':                readLockBits = true;                break;            case 'L':                lockBits = optarg;                writeLockBits = true;                break;            case 'P':                device_name = optarg;                break;	    case 'V':		exit(0);            default:                fprintf (stderr, "getop() did something screwey");                exit (1);        }    }    if ((optind+1) == argc) {        /* Looks like user has given [[host]:port], so parse out the host and           port number then enable gdb server mode. */        int i;        char *arg = argv[optind];        int len = strlen (arg);        char *host = new char[len+1];        memset (host, '\0', len+1);        for (i=0; i<len; i++) {            if ((arg[i] == '\0') || (arg[i] == ':'))                break;            host[i] = arg[i];        }        if (strlen (host)) {            hostName = host;        }        if (arg[i] == ':') {            i++;        }        if (i >= len) {            /* No port was given. */            fprintf (stderr, "avarice: %s is not a valid host:port value.\n",                     arg);            exit (1);        }        char *endptr;        hostPortNumber = (int)strtol(arg+i, &endptr, 0);        if (endptr == arg+i) {            /* Invalid convertion. */            fprintf (stderr, "avarice: failed to convert port number: %s\n",                     arg+i);            exit (1);        }        /* Make sure the the port value is not a priviledged port and is not           greater than max port value. */        if ((hostPortNumber < 1024) || (hostPortNumber > 0xffff)) {            fprintf (stderr, "avarice: invalid port number: %d (must be >= %d"                     " and <= %d)\n", hostPortNumber, 1024, 0xffff);            exit (1);        }        gdbServerMode = true;    }    else if (optind != argc) {        usage (progname);    }    if (jtagBitrate == 0)    {        fprintf (stdout,                 "Defaulting JTAG bitrate to 1 MHz. Make sure that the target\n"                 "frequency is at least 4 MHz or you will likely encounter failures\n"                 "controlling the target.\n\n");        jtagBitrate = JTAG_BITRATE_1_MHz;    }    // And say hello to the JTAG box    initJtagPort(jtagDeviceName);    // Init JTAG box.    initJtagBox();    if (erase)    {        enableProgramming();	statusOut("Erasing program memory.\n");	eraseProgramMemory();	statusOut("Erase complete.\n");        disableProgramming();    }    if (readFuses)    {        jtagReadFuses();    }    if (readLockBits)    {        jtagReadLockBits();    }    if (writeFuses)        jtagWriteFuses(fuses);    // Init JTAG debugger for initial use.    //   - If we're attaching to a running target, we cannot do this.    //   - If we're running as a standalone programmer, we don't want    //     this.    if( gdbServerMode && ( ! capture ) )        initJtagOnChipDebugging(jtagBitrate);    if (inFileName != (char *)0)    {        if ((program == false) && (verify == false)) {            /* If --file is given and neither --program or --verify, then we               program, but not verify so as to be backward compatible with               the old meaning of --file from before the addition of --program               and --verify. */            program = true;        }        if ((erase == false) && (program == true)) {            statusOut("WARNING: The default behaviour has changed.\n"                      "Programming no longer erases by default. If you want to"                      " erase and program\nin a single step, use the --erase "                      "in addition to --program. The reason for\nthis change "                      "is to allow programming multiple sections (e.g. "                      "application and\nbootloader) in multiple passes.\n\n");        }        downloadToTarget(inFileName, program, verify);        resetProgram();    }    else    {	check( (!program) && (!verify),	      "\nERROR: Filename not specified."	      " Use the --file option.\n");    }    // Write fuses after all programming parts have completed.    if (writeLockBits)        jtagWriteLockBits(lockBits);    // Quit for operations that don't interact with gdb.    if (gdbServerMode)    {        initSocketAddress(&name, hostName, hostPortNumber);        sock = makeSocket(&name, hostPortNumber);        statusOut("Waiting for connection on port %hu.\n", hostPortNumber);        gdbCheck(listen(sock, 1));        if (detach)        {            int child = fork();            unixCheck(child, "Failed to fork");            if (child != 0)                _exit(0);            else                unixCheck(setsid(), "setsid failed - weird bug");        }        // Connection request on original socket.        socklen_t size = (socklen_t)sizeof(clientname);        int gfd = accept(sock, (struct sockaddr *)&clientname, &size);        gdbCheck(gfd);        statusOut("Connection opened by host %s, port %hu.\n",                  inet_ntoa(clientname.sin_addr), ntohs(clientname.sin_port));        setGdbFile(gfd);        // Now do the actual processing of GDB messages        // We stay here until exiting because of error of EOF on the        // gdb connection        for (;;)            talkToGdb();    }    return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -