#!/usr/bin/env python # ui_remote.py - naive script to poke and prod the altimeter firmware over # GDB/MI. Useful for rapid UI development/testing, all while probably not being # strictly threadsafe. We're not triggering an ISR on the remote, so PC could # already be in the middle of an ISR when we fire a UI event, which should # never be allowed to happen in normal use. # Useful nonetheless. # # FIXME allow smarter queueing of UI events in this script so they can be # batched into the same (slow) interrupt-and-continue window. # import atexit import curses import pygdbmi.gdbcontroller import sys def interrupt_run_continue(mi, command): mi.write('interrupt') mi.write(command) mi.write('continue &') def main(): def curses_init(): stdscr = curses.initscr() curses.cbreak() curses.noecho() return stdscr def curses_end(): curses.nocbreak() stdscr.keypad(False) curses.echo() curses.endwin() # Give pygdbmi hardcoded GDB, ELF paths, remote. Good enough for now mi = pygdbmi.gdbcontroller.GdbController( command=["/usr/bin/avr-gdb", '--interpreter=mi3']) mi.write('file build/altimeter_sim.elf', timeout_sec=5) mi.write('target remote :1234') mi.write('continue &') # atexit covers crash cases which is nice atexit.register(curses_end) stdscr = curses_init() stdscr.addstr(0, 0, "UI remote control via GDB. Press q to quit") stdscr.addstr(1, 0, "w: up s: down a: hold d: short press") running = True while running: stdscr.addstr(2, 0, "ready") stdscr.clrtoeol() key = stdscr.getch() stdscr.addstr(2, 0, "busy") stdscr.clrtoeol() stdscr.refresh() if key == ord('q'): running = False elif key == ord('w'): interrupt_run_continue(mi, 'call up()') elif key == ord('s'): interrupt_run_continue(mi, 'call down()') elif key == ord('a'): interrupt_run_continue(mi, 'call hold()') elif key == ord('d'): interrupt_run_continue(mi, 'call press()') else: stdscr.addstr(1, 0, str(key)) if __name__ == "__main__": sys.exit(main())