0
kdb>kgdb // 可进入kgdb 模式
if (dbg_kdb_mode) {
error = kdb_stub(ks);
} else {
error = gdb_serial_stub(ks);
}
1
gdbstub.c
—>
while (1) {
//接收一个完整的数据包或者一帧数据(不同领域说法不一致)
get_packet(remcom_in_buffer);
//开始处理数据包
switch (remcom_in_buffer[0]) {
case ‘?’: /* gdbserial status */
…
}
2
首先了解下数据包的格式:(GDB Remote Serial Protocol)
$packet-data#checksum
两位数校验和的计算方法是,对’$'和’#'间的所有字符求和,然后再对256求模(8位无符号校验和)。
static void get_packet(char *buffer)
{
do {
//数据包以 ‘$’ 符号开始
while ((ch = (gdbstub_read_wait())) != ‘$’)
/* nothing */;
//数据包以 ‘#’ 符号结束 ,中间数据部分是对调试真正有意义的
while (count < (BUFMAX – 1)) {
ch = gdbstub_read_wait();
if (ch == ‘#’)
break;
checksum = checksum + ch;
buffer[count] = ch;
count = count + 1;
}
buffer[count] = 0;
//再接收两个数据,判断其校验是否与我们计算的相一致
if (ch == ‘#’) {
xmitcsum = hex(gdbstub_read_wait()) << 4;
xmitcsum += hex(gdbstub_read_wait());
if (checksum != xmitcsum)
/* failed checksum */
dbg_io_ops->write_char(‘-’);
else
/* successful transfer */
dbg_io_ops->write_char(‘+’);
if (dbg_io_ops->flush)
dbg_io_ops->flush();
}
} while (checksum != xmitcsum); //直到接收完正确校验的数据报才开始,去调用处理函数
}
3
由于Remote Serial Protocol协议相对来说比较简单,
建议协议复杂点的话,需要用的状态机,会比较简单明了。