With synchronous and asynchronous execution error handling becomes a bit trickier...
I'm thinking that jtag_add_pathmove() and jtag_add_stavemove() should be split into two: checking args and queing fns. Performance sensitive code that *KNOWS* that the arguments are correct can invoke the queue fn directly. The queue fn can have assert()'s that are compiled out. The argument checking fn can be invoked explicitly without queing a operation. a wrapper fn for the two should be written that does precisely the same as today, except that jtag_add_statemove() should, like, jtag_add_pathmove() return void. The programming model is that everything is queued and then the error is checked at jtag_add_execute_queue(). Code that needs to know the error sooner should invoke jtag_execute_queue() "more often" or use the arg checking fn's directly. Patch attached to illustrate what I have in mind. -- Øyvind Harboe Embedded software and hardware consulting services http://consulting.zylin.com
### Eclipse Workspace Patch 1.0 #P openocd Index: src/jtag/core.c =================================================================== --- src/jtag/core.c (revision 2179) +++ src/jtag/core.c (working copy) @@ -438,7 +438,7 @@ jtag_call_event_callbacks(JTAG_TRST_ASSERTED); } -void jtag_add_pathmove(int num_states, const tap_state_t *path) +int jtag_check_pathmove(int num_states, const tap_state_t *path) { tap_state_t cur_state = cmd_queue_cur_state; @@ -446,8 +446,7 @@ if (!tap_is_state_stable(path[num_states - 1])) { LOG_ERROR("BUG: TAP path doesn't finish in a stable state"); - jtag_set_error(ERROR_JTAG_NOT_STABLE_STATE); - return; + return ERROR_JTAG_NOT_STABLE_STATE; } for (int i = 0; i < num_states; i++) @@ -455,8 +454,7 @@ if (path[i] == TAP_RESET) { LOG_ERROR("BUG: TAP_RESET is not a valid state for pathmove sequences"); - jtag_set_error(ERROR_JTAG_STATE_INVALID); - return; + return ERROR_JTAG_STATE_INVALID; } if ( tap_state_transition(cur_state, true) != path[i] @@ -464,18 +462,36 @@ { LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_name(cur_state), tap_state_name(path[i])); - jtag_set_error(ERROR_JTAG_TRANSITION_INVALID); - return; + return ERROR_JTAG_TRANSITION_INVALID; } cur_state = path[i]; } + return ERROR_OK; +} + +void jtag_add_pathmove_nocheck(int num_states, const tap_state_t *path) +{ + /* this check can be compiled out */ + assert(jtag_check_pathmove(num_states, path)==ERROR_OK); + jtag_checks(); jtag_set_error(interface_jtag_add_pathmove(num_states, path)); cmd_queue_cur_state = path[num_states - 1]; } +void jtag_add_pathmove(int num_states, const tap_state_t *path) +{ + int retval; + if ((retval=jtag_check_pathmove(num_states, path))!=ERROR_OK) + { + jtag_set_error(retval); + return; + } + jtag_add_pathmove_nocheck(num_states, path); +} + void jtag_add_runtest(int num_cycles, tap_state_t state) { jtag_prelude(state);
_______________________________________________ Openocd-development mailing list Openocd-development@lists.berlios.de https://lists.berlios.de/mailman/listinfo/openocd-development