pgdb->status.isAppStarted = 0;
}
- } else if (pgdb->ctrl.notify && pgdb->buffer.state == idle) {
+ } else if (pgdb->ctrl.notify && pgdb->buffer.state.substate == idle) {
pgdb->ctrl.notify = 0;
pgdb->timer = 20;
xputsmem(gdb_StatusStop);
struct gdb::Gdb *pgdb = GDB_PTR;
struct Buffer *p = &pgdb->buffer;
- if (p->state == execerr) {
+ if (p->state.substate == execerr) {
xputc('-');
- p->state = idle;
+ p->state.substate = idle;
- } else if (p->state == exec) {
+ } else if (p->state.substate == exec) {
xputc('+');
#ifdef GDB_DEBUG_UART_REQUEST
#endif
pgdb->status.isConnected = 1;
p->buffer[(p->rpos < sizeof(p->buffer) - 1) ? p->rpos : sizeof(p->buffer) - 1] = 0;
- p->state = send;
+ p->state.substate = send;
uint8_t i;
switch(*p->buffer) {
xputsmem(gdb_OK);
return;
- } else if (i == 11 && sum == 0xa9) { // vFlashWrite:
+ } else if (i == 10 && sum == 0x6f) { // vFlashWrite
pgdb->ctrl.kill = 1;
executeControl();
- uint8_t i = 12;
+ char *pData = (char *)(RAMSTART + 0x400);
+ if (!pgdb->buffer.state.binpack || *pData++ != ':') {
+ xputsmem(gdb_E00);
+ return;
+ }
uint32_t address;
- uint8_t size = parseHex(p->buffer, i, &address);
- i += size;
- if (size <= 0 || p->buffer[i++] != ':') {
+ uint8_t aSize = parseHex(pData, 0, &address);
+ pData += aSize;
+ uint16_t size = (uint16_t)p->binpackPtr - (uint16_t)pData - 1;
+
+ if (aSize <= 0 || *pData++ != ':' || size <= 0 || size > 0x3ff) {
xputsmem(gdb_E00);
} else {
- flashFill((uint8_t *)&p->buffer[i], p->rpos - i, (uint16_t)address);
+ flashFill((uint8_t *)pData, size, (uint16_t)address);
xputsmem(gdb_OK);
}
return;
gputc(dec2hex((pbuf->chkSumToGdb >> 4) & 0x0f));
gputc(dec2hex(pbuf->chkSumToGdb & 0x0f));
if (!pgdb->status.isSendingNotification ) {
- pbuf->state = waitack;
+ pbuf->state.substate = waitack;
}
break;
}
struct gdb::Gdb *pgdb = GDB_PTR;
struct Buffer *p = &pgdb->buffer;
if (c == '$') {
- if (p->state != idle) {
+ if (p->state.substate != idle) {
// incUint8Cnt(&gdb.status.errCnt);
pgdb->status.errorFlags |= 0x02;
}
p->chkSumFromGdb = 0;
p->rpos = 0;
- p->state = data;
+ p->state.substate = data;
+ p->state.binpack = 0;
+ p->binpackPtr = (uint8_t *)(RAMEND + 1);
} else {
- switch (p->state) {
+ switch (p->state.substate) {
case data: {
if (c == '#') {
- p->state = chk1;
+ p->state.substate = chk1;
} else {
p->chkSumFromGdb += c;
+ if (p->rpos == 0x0b && p->chkSumFromGdb == 0xa9) { //$vFlashWrite:
+ pushReceivedByte(c); // increase p->rpos
+ p->state.binpack = 1;
+ p->binpackPtr = (uint8_t *)(RAMSTART + 0x400); // first 0x400 bytes for flashFill()
+ }
if (c == '}') {
- p->state = esc;
-
+ p->state.substate = esc;
+ } else if (p->state.binpack) {
+ *p->binpackPtr++ = c;
} else {
pushReceivedByte(c);
}
case esc: {
p->chkSumFromGdb += c;
- pushReceivedByte(c ^ 0x20);
- p->state = data;
+ c ^= 0x20;
+ if (p->state.binpack) {
+ *p->binpackPtr++ = c;
+ } else {
+ pushReceivedByte(c);
+ }
+ p->state.substate = data;
break;
}
case chk1: {
int8_t v = hexValueFromChar(c);
if (v < 0) {
- p->state = chk2err;
+ p->state.substate = chk2err;
} else {
p->chkSumFromGdb -= (v << 4);
- p->state = chk2;
+ p->state.substate = chk2;
}
break;
}
case chk2err: {
// incUint8Cnt(&gdb.status.errCnt);
pgdb->status.errorFlags |= 0x04;
- p->state = execerr;
+ p->state.substate = execerr;
break;
}
if (v < 0 || p->chkSumFromGdb != 0) {
// incUint8Cnt(&gdb.status.errCnt);
pgdb->status.errorFlags |= 0x08;
- p->state = execerr;
+ p->state.substate = execerr;
} else {
- p->state = p->rpos <= BUFFER_SIZE ? exec : execerr;
+ p->state.substate = p->rpos <= BUFFER_SIZE ? exec : execerr;
}
break;
}
case waitack: {
if (c == '-') {
- p->state = send;
+ p->state.substate = send;
} else {
if (c != '+') {
// incUint8Cnt(&gdb.status.errCnt);
pgdb->status.errorFlags |= 0x10;
}
- p->state = idle;
+ p->state.substate = idle;
}
break;
}
//const uint8_t BUFFER_SIZE = 13 + 5 + 128 + 3; // "$vFlashWrite:" + "ffff:" + 128 Bytes + "#00"
const uint16_t BUFFER_SIZE = 13 + 5 + 300 + 3; // "$vFlashWrite:" + "ffff:" + 128 Bytes + "#00"
- enum BufferState { idle = 0, data, esc, chk1, chk2, chk2err, exec, execerr, send, waitack };
+ enum BufferSubState { idle = 0, data, esc, chk1, chk2, chk2err, exec, execerr, send, waitack };
struct Status { // (gdb) print ((gdb::Gdb *)0x801039)->status
uint8_t notify:1; // Bit 7
};
+ struct BufferState {
+ uint8_t binpack:1; // Bit 0
+ uint8_t dbg1:1; // Bit 1 (for debugging)
+ uint8_t dbg2:1; // Bit 2 (for debugging)
+ enum BufferSubState substate;
+ };
+
struct Buffer { // (gdb) print ((gdb::Gdb *)0x801039)->buffer
- enum BufferState state;
+ // enum BufferState state;
+ struct BufferState state;
uint16_t rpos;
uint8_t chkSumFromGdb;
uint8_t chkSumToGdb;
+ uint8_t *binpackPtr;
char buffer[BUFFER_SIZE];
};