/* Attach to PID `pid', take a snapshot, modify its state to have it call * `dlopen()', restore the previously saved snapshot and detach. */ static int inject(pid_t pid, char *filename, char all_thrs) { regs_t regs; char buf[PAGE_SIZE]; ssize_t size; int r = -1; if(attach(pid, all_thrs) != 0) goto ret; if(read_registers(pid, ®s) != 0) goto ret; if((size = read_memory(pid, (void *)SP(regs), buf, sizeof(buf))) < 0) goto ret; r = 0; if(force_dlopen(pid, filename) != 0) r = -1; if(write_memory(pid, (void *)SP(regs), buf, size) != size) r = -1; if(write_registers(pid, ®s) != 0) r = -1; if(detach(pid, all_thrs) != 0) r = -1; ret: return r; }
int main( int argc, char *argv[]) { int fd; fd=open_chip(); read_registers(fd); close_chip(fd); reg[0x02] |= (1<<10); // allow wrap reg[0x02] |= (1<<9); // set seek direction reg[0x02] |= (1<<8); // start seek reg[0x06] |= (1<<4); // set min seek threshold reg[0x06] |= (1<<1); //set min FM Imp. threshold write_registers(); // watch for STC == 1 while (1) { fd=open_chip(); read_registers(fd); close_chip(fd); if((reg[10] & (1<<14)) !=0) break; //tuning finished } fd=open_chip(); read_registers(fd); close_chip(fd); int SFBL = reg[0x0A] & (1<<13); reg[0x02] &= ~(1<<8); //clear the seek bit write_registers(); // usleep(80000); while (1) { fd=open_chip(); read_registers(fd); close_chip(fd); if((reg[0x0A] & (1<<14)) == 0) break; } if(SFBL) { exit(1); } return; }
int write_args(t_arg *arg, int fd, t_label *label, int decal) { if ((arg->type == 1 && write_registers(arg, fd) == 1) || (arg->type == 2 && write_direct(arg, fd, label, decal) == 1) || (arg->type == 3 && write_indirects(arg, fd) == 1) || (arg->type == 4 && write_odds(arg, fd, label, decal) == 1)) return (1); return (0); }
void VGA_deinit() { memcpyTF((char*)VGA_address, vidmem, 256*1024); write_registers(mode_80_25_text); restorePalette(savedPalette); _isVGA = false; DebugReset(); //restorefont((char*)g_8x8_font); //write_font(g_8x8_font, 8); //memset((char*)0xB8000, 0, 64*1024); DebugClrScr(0x17); }
static int process_gdb_command(struct gdb_data *data, char *buf, int len) { #ifdef DEBUG_GDB printc("process_gdb_command: %s\n", buf); #endif switch (buf[0]) { case '?': /* Return target halt reason */ return run_final_status(data); case 'z': case 'Z': return set_breakpoint(data, buf[0] == 'Z', buf + 1); case 'r': /* Restart */ case 'R': return restart_program(data); case 'g': /* Read registers */ return read_registers(data); case 'G': /* Write registers */ return write_registers(data, buf + 1); case 'q': /* Query */ if (!strncmp(buf, "qRcmd,", 6)) return monitor_command(data, buf + 6); if (!strncmp(buf, "qSupported", 10)) return gdb_send_supported(data); break; case 'm': /* Read memory */ return read_memory(data, buf + 1); case 'M': /* Write memory */ return write_memory(data, buf + 1); case 'c': /* Continue */ return run(data, buf + 1); case 's': /* Single step */ return single_step(data, buf + 1); case 'k': /* kill */ return -1; } #ifdef DEBUG_GDB printc("process_gdb_command: unknown command %s\n", buf); #endif /* For unknown/unsupported packets, return an empty reply */ return gdb_send(data, ""); }
void VGA_init(int width, int height, int bpp){ //savefont(); savePalette(savedPalette); //read_registers(mode_80_25_text); /*outport(0x3C4, 0x02); char in = inport(0x3C5); DebugPrintf("\n0x3c4.0x02=0x%x", in); for(;;);*/ //setup the vga struct VGA_width=(unsigned int)width; VGA_height=(unsigned int)height; VGA_bpp=bpp; VGA_address = (unsigned char*)0xA0000; //enables the mode 13 state //write_registers(mode_320_200_256); write_registers(mode_640_480_16); VGA_width = 640; VGA_height = 480; mode.address = (char*)VGA_address; mode.bpp = bpp; mode.height = VGA_height; mode.width = VGA_width; mode.id = 0x12; mode.putpixel = (PIXEL_WRITER)write_pixel4p; //save videomemory vidmem = (char*)malloc(256*1024); memcpy((char*)VGA_address, vidmem, 256*1024); _isVGA = true; DebugReset(); //clears the screen VGA_clear_screen(); //write_pixel4p(16, 16, 0x3d); // for(;;); // VGA_put_pixel(16, 16, 11); VGA_map_color(0x3D, 0xFF, 0x00, 0x00); VGA_map_color(0x00, 0xFF, 0xFF, 0xFF); /*_put_char(16, 16, 'l'); _put_char(24, 16, 'e'); _put_char(32, 16, 'v'); _put_char(40, 16, 'e'); _put_char(48, 16, 'x');*/ //VGA_put_string(16,16, "levex"); //mehgfor(;;); // VGA_put_image(10, 10, "test.bmp"); }
int writegeneralRTU(int IDNumber){ uint16_t rtcbuffer[7]; time_t t = time(NULL); struct tm tm = *localtime(&t); setmodbusslave(IDNumber); rtcbuffer[0] = tm.tm_sec; rtcbuffer[1] = tm.tm_min; rtcbuffer[2] = tm.tm_hour; rtcbuffer[3] = tm.tm_mday; rtcbuffer[4] = tm.tm_mon + 1; rtcbuffer[5] = tm.tm_year + 1900; rtcbuffer[6] = 1; write_registers(REG_RTC_GEN_SECS -1,7, rtcbuffer); }
/**************************************************************************** * write_registers_info ****************************************************************************/ static int write_registers_info(int fdout, info_s *pi , char *buffer, int sz) { int ret = ENOENT; if (pi->flags & eRegsPresent) { ret = -EIO; int n = snprintf(buffer, sz, " Processor registers: from 0x%08x\n", pi->current_regs); if (n == write(fdout, buffer, n)) { ret = write_registers(pi->regs, buffer, sz, fdout); } } return ret; }
//-------------------------------------------------------------------------- // Cleanup after appcall() // The debugger module must keep the stack blob in the memory until this function // is called. It will be called by the kernel for each successful call_app_func() int idaapi debmod_t::dbg_cleanup_appcall(thid_t tid) { call_contexts_t &calls = appcalls[tid]; if ( calls.empty() ) return 0; // remove the return breakpoint call_context_t &ctx = calls.back(); if ( !preprocess_appcall_cleanup(tid, ctx) ) return 0; dbg_del_bpt(BPT_SOFT, ctx.ctrl_ea, bpt_code.begin(), bpt_code.size()); if ( ctx.regs_spoiled ) { if ( !write_registers(tid, 0, ctx.saved_regs.size(), ctx.saved_regs.begin()) ) { dmsg("Failed to restore registers!\n"); return 0; } } calls.pop(); return events.empty() ? 1 : 2; }
/* Reads contents of the filename file as an info file and updates it with the * state of current instance. */ static void update_info_file(const char filename[]) { /* TODO: refactor this function update_info_file() */ FILE *fp; char **cmds_list; int ncmds_list = -1; char **ft = NULL, **fx = NULL, **fv = NULL, **cmds = NULL, **marks = NULL; char **lh = NULL, **rh = NULL, **cmdh = NULL, **srch = NULL, **regs = NULL; int *lhp = NULL, *rhp = NULL, *bt = NULL, *bmt = NULL; char **prompt = NULL, **filter = NULL, **trash = NULL; char **bmarks = NULL; int nft = 0, nfx = 0, nfv = 0, ncmds = 0, nmarks = 0, nlh = 0, nrh = 0; int ncmdh = 0, nsrch = 0, nregs = 0, nprompt = 0, nfilter = 0, ntrash = 0; int nbmarks = 0; char **dir_stack = NULL; int ndir_stack = 0; char *non_conflicting_marks; if(cfg.vifm_info == 0) return; cmds_list = list_udf(); while(cmds_list[++ncmds_list] != NULL); non_conflicting_marks = strdup(valid_marks); if((fp = os_fopen(filename, "r")) != NULL) { size_t nlhp = 0UL, nrhp = 0UL, nbt = 0UL, nbmt = 0UL; char *line = NULL, *line2 = NULL, *line3 = NULL, *line4 = NULL; while((line = read_vifminfo_line(fp, line)) != NULL) { const char type = line[0]; const char *const line_val = line + 1; if(type == LINE_TYPE_COMMENT || type == '\0') continue; if(type == LINE_TYPE_FILETYPE) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if(!ft_assoc_exists(&filetypes, line_val, line2)) { nft = add_to_string_array(&ft, nft, 2, line_val, line2); } } } else if(type == LINE_TYPE_XFILETYPE) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if(!ft_assoc_exists(&xfiletypes, line_val, line2)) { nfx = add_to_string_array(&fx, nfx, 2, line_val, line2); } } } else if(type == LINE_TYPE_FILEVIEWER) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if(!ft_assoc_exists(&fileviewers, line_val, line2)) { nfv = add_to_string_array(&fv, nfv, 2, line_val, line2); } } } else if(type == LINE_TYPE_COMMAND) { if(line_val[0] == '\0') continue; if((line2 = read_vifminfo_line(fp, line2)) != NULL) { int i; const char *p = line_val; for(i = 0; i < ncmds_list; i += 2) { int cmp = strcmp(cmds_list[i], p); if(cmp < 0) continue; if(cmp == 0) p = NULL; break; } if(p == NULL) continue; ncmds = add_to_string_array(&cmds, ncmds, 2, line_val, line2); } } else if(type == LINE_TYPE_LWIN_HIST || type == LINE_TYPE_RWIN_HIST) { if(line_val[0] == '\0') continue; if((line2 = read_vifminfo_line(fp, line2)) != NULL) { const int pos = read_optional_number(fp); if(type == LINE_TYPE_LWIN_HIST) { process_hist_entry(&lwin, line_val, line2, pos, &lh, &nlh, &lhp, &nlhp); } else { process_hist_entry(&rwin, line_val, line2, pos, &rh, &nrh, &rhp, &nrhp); } } } else if(type == LINE_TYPE_MARK) { const char mark = line_val[0]; if(line_val[1] != '\0') { LOG_ERROR_MSG("Expected end of line, but got: %s", line_val + 1); } if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if((line3 = read_vifminfo_line(fp, line3)) != NULL) { const int timestamp = read_optional_number(fp); const char mark_str[] = { mark, '\0' }; if(!char_is_one_of(valid_marks, mark)) { continue; } if(is_mark_older(mark, timestamp)) { char *const pos = strchr(non_conflicting_marks, mark); if(pos != NULL) { nmarks = add_to_string_array(&marks, nmarks, 3, mark_str, line2, line3); nbt = add_to_int_array(&bt, nbt, timestamp); *pos = '\xff'; } } } } } else if(type == LINE_TYPE_BOOKMARK) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if((line3 = read_vifminfo_line(fp, line3)) != NULL) { long timestamp; if(read_number(line3, ×tamp) && bmark_is_older(line_val, timestamp)) { nbmarks = add_to_string_array(&bmarks, nbmarks, 2, line_val, line2); nbmt = add_to_int_array(&bmt, nbmt, timestamp); } } } } else if(type == LINE_TYPE_TRASH) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { char *const trash_name = convert_old_trash_path(line_val); if(exists_in_trash(trash_name) && !is_in_trash(trash_name)) { ntrash = add_to_string_array(&trash, ntrash, 2, trash_name, line2); } free(trash_name); } } else if(type == LINE_TYPE_CMDLINE_HIST) { if(!hist_contains(&cfg.cmd_hist, line_val)) { ncmdh = add_to_string_array(&cmdh, ncmdh, 1, line_val); } } else if(type == LINE_TYPE_SEARCH_HIST) { if(!hist_contains(&cfg.search_hist, line_val)) { nsrch = add_to_string_array(&srch, nsrch, 1, line_val); } } else if(type == LINE_TYPE_PROMPT_HIST) { if(!hist_contains(&cfg.prompt_hist, line_val)) { nprompt = add_to_string_array(&prompt, nprompt, 1, line_val); } } else if(type == LINE_TYPE_FILTER_HIST) { if(!hist_contains(&cfg.filter_hist, line_val)) { nfilter = add_to_string_array(&filter, nfilter, 1, line_val); } } else if(type == LINE_TYPE_DIR_STACK) { if((line2 = read_vifminfo_line(fp, line2)) != NULL) { if((line3 = read_vifminfo_line(fp, line3)) != NULL) { if((line4 = read_vifminfo_line(fp, line4)) != NULL) { ndir_stack = add_to_string_array(&dir_stack, ndir_stack, 4, line_val, line2, line3 + 1, line4); } } } } else if(type == LINE_TYPE_REG) { if(regs_exists(line_val[0])) { continue; } nregs = add_to_string_array(®s, nregs, 1, line); } } free(line); free(line2); free(line3); free(line4); fclose(fp); } if((fp = os_fopen(filename, "w")) != NULL) { fprintf(fp, "# You can edit this file by hand, but it's recommended not to " "do that.\n"); if(cfg.vifm_info & VIFMINFO_OPTIONS) { write_options(fp); } if(cfg.vifm_info & VIFMINFO_FILETYPES) { write_assocs(fp, "Filetypes", LINE_TYPE_FILETYPE, &filetypes, nft, ft); write_assocs(fp, "X Filetypes", LINE_TYPE_XFILETYPE, &xfiletypes, nfx, fx); write_assocs(fp, "Fileviewers", LINE_TYPE_FILEVIEWER, &fileviewers, nfv, fv); } if(cfg.vifm_info & VIFMINFO_COMMANDS) { write_commands(fp, cmds_list, cmds, ncmds); } if(cfg.vifm_info & VIFMINFO_MARKS) { write_marks(fp, non_conflicting_marks, marks, bt, nmarks); } if(cfg.vifm_info & VIFMINFO_BOOKMARKS) { write_bmarks(fp, bmarks, bmt, nbmarks); } if(cfg.vifm_info & VIFMINFO_TUI) { write_tui_state(fp); } if((cfg.vifm_info & VIFMINFO_DHISTORY) && cfg.history_len > 0) { write_view_history(fp, &lwin, "Left", LINE_TYPE_LWIN_HIST, nlh, lh, lhp); write_view_history(fp, &rwin, "Right", LINE_TYPE_RWIN_HIST, nrh, rh, rhp); } if(cfg.vifm_info & VIFMINFO_CHISTORY) { write_history(fp, "Command line", LINE_TYPE_CMDLINE_HIST, MIN(ncmdh, cfg.history_len - cfg.cmd_hist.pos), cmdh, &cfg.cmd_hist); } if(cfg.vifm_info & VIFMINFO_SHISTORY) { write_history(fp, "Search", LINE_TYPE_SEARCH_HIST, nsrch, srch, &cfg.search_hist); } if(cfg.vifm_info & VIFMINFO_PHISTORY) { write_history(fp, "Prompt", LINE_TYPE_PROMPT_HIST, nprompt, prompt, &cfg.prompt_hist); } if(cfg.vifm_info & VIFMINFO_FHISTORY) { write_history(fp, "Local filter", LINE_TYPE_FILTER_HIST, nfilter, filter, &cfg.filter_hist); } if(cfg.vifm_info & VIFMINFO_REGISTERS) { write_registers(fp, regs, nregs); } if(cfg.vifm_info & VIFMINFO_DIRSTACK) { write_dir_stack(fp, dir_stack, ndir_stack); } write_trash(fp, trash, ntrash); if(cfg.vifm_info & VIFMINFO_STATE) { write_general_state(fp); } if(cfg.vifm_info & VIFMINFO_CS) { fputs("\n# Color scheme:\n", fp); fprintf(fp, "c%s\n", cfg.cs.name); } fclose(fp); } free_string_array(ft, nft); free_string_array(fv, nfv); free_string_array(fx, nfx); free_string_array(cmds, ncmds); free_string_array(marks, nmarks); free_string_array(cmds_list, ncmds_list); free_string_array(lh, nlh); free_string_array(rh, nrh); free(lhp); free(rhp); free(bt); free(bmt); free_string_array(cmdh, ncmdh); free_string_array(srch, nsrch); free_string_array(regs, nregs); free_string_array(prompt, nprompt); free_string_array(filter, nfilter); free_string_array(trash, ntrash); free_string_array(bmarks, nbmarks); free_string_array(dir_stack, ndir_stack); free(non_conflicting_marks); }
/* Force the target to call `dlopen()'. Modify its registers and stack contents * and continue execution until a segmentation fault is caught. Return 0 on * success and -1 on failure. */ static int force_dlopen(pid_t pid, char *filename) { void *linker_addr, *dlopen_off, *dlopen_addr; regs_t regs; size_t size; int r = -1; if(resolve_symbol(LINKER_PATH, DLOPEN_NAME1, &dlopen_off) != 0 && resolve_symbol(LINKER_PATH, DLOPEN_NAME2, &dlopen_off) != 0 && resolve_symbol(LINKER_PATH, DLOPEN_NAME3, &dlopen_off) != 0) { printf("[*] Could not resolve dlopen()\n"); goto ret; } if((linker_addr = get_linker_addr(pid)) == NULL) { printf("[*] Linker not found in PID %d\n", pid); goto ret; } dlopen_addr = linker_addr + (ptrdiff_t)dlopen_off; printf("[*] Resolved dlopen() at %p\n", dlopen_addr); if(read_registers(pid, ®s) != 0) goto ret; /* Prepare `do_dlopen()' input arguments. On Android >= 7, we set the 4th * argument to a value that emulates `__builtin_return_address()', so that * our DSO is loaded in the correct namespace. */ ARG0(regs) = SP(regs) + SP_OFF; ARG1(regs) = RTLD_NOW | RTLD_GLOBAL; ARG2(regs) = 0; ARG3(regs) = PC(regs); /* We set the new PC and also set LR to force the debuggee to crash. */ #if defined(__aarch64__) LR(regs) = 0xffffffffffffffff; PC(regs) = (reg_t)dlopen_addr; #elif defined(__arm__) LR(regs) = 0xffffffff; PC(regs) = (reg_t)dlopen_addr | 1; CPSR(regs) |= 1 << 5; #endif printf("[*] Modifying target's state\n"); if(write_registers(pid, ®s) != 0) goto ret; size = strlen(filename) + 1; if(write_memory(pid, (void *)SP(regs) + SP_OFF, filename, size) != size) goto ret; printf("[*] Waiting for target to throw SIGSEGV or SIGBUS\n"); if(resume_and_wait(pid) != 0) goto ret; r = 0; ret: return r; }
/* return value: 0 if the simulator is to be killed, * 1 if the simulator is to be continued. */ static int process_gdb_loop(void) { int addr; int length; int cpu_id; int step_cpu, other_cpu = 0; char *ptr; char type; int regnum; uint32_t val; regnum = regnum; step_cpu = other_cpu = 0; /* if the hardware is running, we dropped here because the user has * hit break in gdb, so we send a signal to GDB indicating that */ if (hardware->running == 1) { remcomOutBuffer[0] = 'S'; remcomOutBuffer[1] = '0'; remcomOutBuffer[2] = '5'; remcomOutBuffer[3] = 0; putpacket((unsigned char *)remcomOutBuffer); } while (1) { remcomOutBuffer[0] = 0; ptr = (char*)getpacket(); if (ptr == NULL) { /* we didn't receive a valid packet, assume that the connection has been terminated */ gdb_interface_close(); return 1; } if (debug_packets) printf("from gdb:%s\n", ptr); switch (*ptr++) { case '?': /* `?' -- last signal */ remcomOutBuffer[0] = 'S'; remcomOutBuffer[1] = '0'; remcomOutBuffer[2] = '1'; remcomOutBuffer[3] = 0; break; case 'c': /* cAA..AA Continue at address AA..AA(optional) */ if (hexToInt(&ptr, &addr)) set_pc(step_cpu, addr); hardware->running = 1; return 1; break; case 'd': /* `d' -- toggle debug *(deprecated)* */ debug_packets = (debug_packets + 1) % 2; break; case 'g': /* return the value of the CPU registers */ read_registers(other_cpu, remcomOutBuffer); break; case 'G': /* set the value of the CPU registers - return OK */ write_registers(other_cpu, ptr); strcpy(remcomOutBuffer,"OK"); break; case 'H': /* `H'CT... -- set thread */ type = *ptr++; if (hexToInt(&ptr, &cpu_id)) { if (cpu_id == -1 || cpu_id == 0) /* XXX all threads */ cpu_id = 1; if (type == 'c') { step_cpu = cpu_id - 1; /* minus one because gdb threats start from 1 and yams cpu's from 0. */ strcpy(remcomOutBuffer, "OK"); } else if (type == 'g') { other_cpu = cpu_id - 1; /* same here */ strcpy(remcomOutBuffer, "OK"); } else strcpy(remcomOutBuffer, "E01"); } else strcpy(remcomOutBuffer, "E01"); break; case 'k' : /* kill the program */ return 0; break; case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ if (hexToInt(&ptr,&addr) &&*ptr++==','&& hexToInt(&ptr,&length)) { if (read_mem(addr, length, remcomOutBuffer)) strcpy(remcomOutBuffer, "E03"); } else strcpy(remcomOutBuffer, "E01"); break; case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA */ if (hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length) && *ptr++ == ':') { if (!write_mem(addr, length, ptr)) strcpy(remcomOutBuffer, "OK"); else strcpy(remcomOutBuffer, "E03"); } else strcpy(remcomOutBuffer, "E02"); break; case 'p': /* `p'HEX NUMBER OF REGISTER -- read register packet */ if (hexToInt(&ptr, ®num) && regnum <= 73) sprintf(remcomOutBuffer, "%08x", read_register(other_cpu, regnum)); else sprintf(remcomOutBuffer, "E01"); break; case 'P': /* `P'N...`='R... -- write register */ if (hexToInt(&ptr, (int*)®num) && *ptr++=='=' && hexToInt(&ptr, (int*)&val)) { write_register(other_cpu, regnum, val); sprintf(remcomOutBuffer, "OK"); } else sprintf(remcomOutBuffer, "E01"); case 'q': /* `q'QUERY -- general query */ if (!strcmp(ptr, "fThreadInfo")) { int i; char *ptr = remcomOutBuffer; ptr += sprintf(ptr, "m01"); if (hardware->num_cpus > 1) for (i = 1; i < hardware->num_cpus; i++) ptr += sprintf(ptr, ",%02x", i + 1); sprintf(ptr, "l"); } break; case 's': /* `s'ADDR -- step */ command_step(1); sprintf(remcomOutBuffer, "S01"); break; case 'T': /* `T'XX -- thread alive */ if (hexToInt(&ptr, &cpu_id) && --cpu_id < hardware->num_cpus) strcpy(remcomOutBuffer, "OK"); else strcpy(remcomOutBuffer, "E01"); break; case 'z': /* remove breakpoint: `Z'TYPE`,'ADDR`,'LENGTH */ type = *ptr++; if (*ptr++== ',' && hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length)) { if (type == '1') { /* hardware breakpoint */ command_breakpoint(0xFFFFFFFF); strcpy(remcomOutBuffer, "OK"); } else /* all others are unsupported */ strcpy(remcomOutBuffer, "E01"); } else strcpy(remcomOutBuffer, "E02"); break; case 'Z': /* insert breakpoint: `Z'TYPE`,'ADDR`,'LENGTH */ type = *ptr++; if (*ptr++== ',' && hexToInt(&ptr, &addr) && *ptr++ == ',' && hexToInt(&ptr, &length)) { if (type == '1') { /* hardware breakpoint */ command_breakpoint(addr); strcpy(remcomOutBuffer, "OK"); } else /* all others are unsupported */ strcpy(remcomOutBuffer, "E01"); } else strcpy(remcomOutBuffer, "E02"); break; default: break; } /* switch */ /* reply to the request */ putpacket((unsigned char *)remcomOutBuffer); if (debug_packets) printf("to gdb: %s\n", remcomOutBuffer); } }
bool write_register(uint8_t addr, uint8_t reg, uint8_t val) { return write_registers(addr, reg, &val, 1); }