Move a number of urj_cmd_run calls from the library, and replace them with API calls

git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@1563 b68d4a1b-bc3d-0410-92ed-d4ac073336b7
master
Rutger Hofman 16 years ago
parent 726681b3f3
commit 8d1a8d91af

@ -40,4 +40,11 @@ struct urj_data_register
urj_data_register_t *urj_part_data_register_alloc (const char *name, int len);
void urj_part_data_register_free (urj_data_register_t *dr);
/**
* allocate a data register and initialize the relevant <code>part</code> parts
*
* @return URJ_STATUS_OK on success; URJ_STATUS_FAIL on error
*/
int urj_part_data_register_define (urj_part_t *part, const char *name, int len);
#endif /* URJ_DATA_REGISTER_H */

@ -25,6 +25,8 @@
#include <stdio.h>
#include "log.h"
/**
* Error types
*/
@ -36,6 +38,8 @@ typedef enum urj_error {
URJ_ERROR_INVALID,
URJ_ERROR_NOTFOUND,
URJ_ERROR_IO, /**< I/O error from OS */
URJ_ERROR_NO_BUS_DRIVER,
URJ_ERROR_BUFFER_EXHAUSTED,
} urj_error_t;
/** Max length of message string that can be recorded. */
@ -55,9 +59,12 @@ typedef struct urj_error_state {
extern urj_error_state_t urj_error_state;
/**
* Set error state. The macro interface allows for a stack of errors, where
* this macro would push an error. The implementation is free to maintain
* a stack of depth one.
* Descriptive string for error type
*/
extern const char *urj_error_string(urj_error_t error);
/**
* Set error state. If the logging level is not SILENT, also logs the error.
*
* @param e urj_error_t value
* @param ... consists of a printf argument set. It needs to start with a
@ -71,19 +78,21 @@ extern urj_error_state_t urj_error_state;
urj_error_state.line = __LINE__; \
snprintf (urj_error_state.msg, sizeof urj_error_state.msg, \
__VA_ARGS__); \
if (urj_log_state.level < URJ_LOG_LEVEL_SILENT) \
{ \
urj_log(URJ_LOG_LEVEL_ERRORS, "%s:%d %s() %s: ", __FILE__, \
__LINE__, __func__, urj_error_string(e)); \
urj_log(URJ_LOG_LEVEL_ERRORS, __VA_ARGS__); \
urj_log(URJ_LOG_LEVEL_ERRORS, "\n"); \
} \
} while (0)
/**
* The top of the error stack. The caller must not modify the returned struct.
*/
const urj_error_state_t *urj_error_get (void);
/**
* Pop the top off the error stack.
* @return #URJ_ERROR_OK if the bottom of the error stack is reached
* Reset the error state.
*/
urj_error_t urj_error_get_reset (void);
void urj_error_reset (void);
/**
* The top of the error state in human-readable form.
* The error state in human-readable form.
*
* This function is not reentrant.
*

@ -0,0 +1,61 @@
/*
* $Id: log.h 1519 2009-04-22 23:12:44Z rfhh $
*
* Copyright (C) 2009, Rutger Hofman, VU Amsterdam
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
*/
#ifndef URJ_LOG_H
#define URJ_LOG_H
#include "sysdep.h"
#include <stdarg.h>
/**
* Log levels
*/
typedef enum urj_log_level {
URJ_LOG_LEVEL_ALL, /**< every single bit as it is transmitted */
URJ_LOG_LEVEL_COMM, /**< low level communication details */
URJ_LOG_LEVEL_DEBUG, /**< more details of interest for developers */
URJ_LOG_LEVEL_DETAIL, /**< verbose output */
URJ_LOG_LEVEL_NORMAL, /**< just noteworthy info */
URJ_LOG_LEVEL_WARNINGS, /**< unmissable warnings */
URJ_LOG_LEVEL_ERRORS, /**< only fatal errors */
URJ_LOG_LEVEL_SILENT, /**< suppress logging output */
} urj_log_level_t;
/**
* Log state.
*/
typedef struct urj_log_state {
urj_log_level_t level; /**< logging level */
int (*out_vprintf) (const char *fmt, va_list ap);
int (*err_vprintf) (const char *fmt, va_list ap);
} urj_log_state_t;
extern urj_log_state_t urj_log_state;
int urj_log (urj_log_level_t level, const char *fmt, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;
#endif /* URJ_LOG_H */

@ -31,6 +31,9 @@
#include <urjtag/cmd.h>
#include <urjtag/part.h>
#include <urjtag/bsbit.h>
#include <urjtag/data_register.h>
#include <urjtag/bssignal.h>
#include "bsdl_sysdep.h"
@ -44,31 +47,6 @@
#include "dmalloc.h"
#endif
/*****************************************************************************
* void print_cmd(char **cmd)
*
* Prints the strings in array cmd until NULL is encountered.
*
* Parameters
* cmd : array of strings to print, terminated by NULL
*
* Returns
* void
****************************************************************************/
static void
print_cmd (char **cmd)
{
int idx = 0;
char *elem;
while ((elem = cmd[idx]))
{
printf ("%s%s", idx > 0 ? " " : "", elem);
idx++;
}
printf ("\n");
}
/*****************************************************************************
* int urj_bsdl_set_instruction_length( urj_bsdl_jtag_ctrl_t *jc )
@ -86,20 +64,11 @@ print_cmd (char **cmd)
static int
urj_bsdl_set_instruction_length (urj_bsdl_jtag_ctrl_t *jc)
{
char lenstring[6];
char *cmd[] = { "instruction",
"length",
lenstring,
NULL
};
snprintf (lenstring, 6, "%i", jc->instr_len);
lenstring[5] = '\0';
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_EXEC)
urj_cmd_run (jc->chain, cmd);
// @@@@ RFHH check result
(void) urj_part_instruction_length_set (jc->part, jc->instr_len);
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_PRINT)
print_cmd (cmd);
printf ("instruction %i\n", jc->instr_len);
return 1;
}
@ -132,10 +101,6 @@ urj_bsdl_emit_ports (urj_bsdl_jtag_ctrl_t *jc)
char *port_string;
int idx;
int result = 0;
char *cmd[] = { "signal",
NULL,
NULL
};
while (pd)
{
@ -152,8 +117,6 @@ urj_bsdl_emit_ports (urj_bsdl_jtag_ctrl_t *jc)
str_len = name_len + 1 + 10 + 1 + 1;
if ((port_string = malloc (str_len)) != NULL)
{
cmd[1] = port_string;
for (idx = pd->low_idx; idx <= pd->high_idx; idx++)
{
if (pd->is_vector)
@ -164,9 +127,10 @@ urj_bsdl_emit_ports (urj_bsdl_jtag_ctrl_t *jc)
port_string[str_len - 1] = '\0';
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_EXEC)
urj_cmd_run (jc->chain, cmd);
// @@@@ RFHH check result
(void) urj_part_signal_define (jc->chain, port_string);
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_PRINT)
print_cmd (cmd);
printf ("signal %s\n", port_string);
}
free (port_string);
@ -206,24 +170,14 @@ urj_bsdl_emit_ports (urj_bsdl_jtag_ctrl_t *jc)
static int
create_register (urj_bsdl_jtag_ctrl_t *jc, char *reg_name, size_t len)
{
const size_t str_len = 10;
char len_str[str_len + 1];
char *cmd[] = { "register",
reg_name,
len_str,
NULL
};
if (urj_part_find_data_register (jc->part, reg_name))
return 1;
/* convert length information to string */
snprintf (len_str, str_len, "%zu", len);
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_EXEC)
urj_cmd_run (jc->chain, cmd);
urj_part_data_register_define (jc->part, reg_name, len);
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_PRINT)
print_cmd (cmd);
printf ("register %s %zd\n", reg_name, len);
return 1;
}
@ -300,6 +254,27 @@ urj_bsdl_set_bsr_length (urj_bsdl_jtag_ctrl_t *jc)
}
static char
bsbit_type_char (int type)
{
switch (type)
{
case URJ_BSBIT_INPUT:
return 'I';
case URJ_BSBIT_OUTPUT:
return 'O';
case URJ_BSBIT_CONTROL:
return 'C';
case URJ_BSBIT_INTERNAL:
return 'X';
case URJ_BSBIT_BIDIR:
return 'B';
default:
return '?';
}
}
/*****************************************************************************
* int urj_bsdl_process_cell_info( urj_bsdl_jtag_ctrl_t *jc )
* Cell Info management function
@ -318,26 +293,11 @@ static int
urj_bsdl_process_cell_info (urj_bsdl_jtag_ctrl_t *jc)
{
urj_bsdl_cell_info_t *ci = jc->cell_info_first;
const size_t str_len = 10;
char bit_num_str[str_len + 1];
char ctrl_bit_num_str[str_len + 1];
char disable_safe_value_str[str_len + 1];
char *cmd[] = { "bit",
bit_num_str,
NULL,
NULL,
NULL,
NULL,
disable_safe_value_str,
"Z",
NULL
};
int type;
int safe;
while (ci)
{
/* convert bit number to string */
snprintf (bit_num_str, str_len, "%i", ci->bit_num);
bit_num_str[str_len] = '\0';
/* convert cell function from BSDL token to jtag syntax */
switch (ci->cell_function)
{
@ -346,55 +306,57 @@ urj_bsdl_process_cell_info (urj_bsdl_jtag_ctrl_t *jc)
case OUTPUT2:
/* fall through */
case OUTPUT3:
cmd[2] = "O";
type = URJ_BSBIT_OUTPUT;
break;
case OBSERVE_ONLY:
/* fall through */
case INPUT:
/* fall through */
case CLOCK:
cmd[2] = "I";
type = URJ_BSBIT_INPUT;
break;
case CONTROL:
/* fall through */
case CONTROLR:
cmd[2] = "C";
type = URJ_BSBIT_CONTROL;
break;
case BIDIR:
cmd[2] = "B";
type = URJ_BSBIT_BIDIR;
break;
default:
/* spoil command */
cmd[2] = "?";
type = -1;
break;
}
/* convert basic safe value */
cmd[3] =
strcasecmp (ci->basic_safe_value,
"x") == 0 ? "?" : ci->basic_safe_value;
/* apply port name */
cmd[4] = ci->port_name;
safe = strcasecmp (ci->basic_safe_value, "x") == 0 ? URJ_BSBIT_DONTCARE
: (ci->basic_safe_value[0] - '0');
/* add disable spec if present */
if (ci->ctrl_bit_num >= 0)
{
/* convert bit number to string */
snprintf (ctrl_bit_num_str, str_len, "%i", ci->ctrl_bit_num);
ctrl_bit_num_str[str_len] = '\0';
/* convert disable safe value to string */
snprintf (disable_safe_value_str, str_len, "%i",
ci->disable_safe_value);
disable_safe_value_str[str_len] = '\0';
cmd[5] = ctrl_bit_num_str;
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_EXEC)
// @@@@ RFHH check result
(void)urj_part_bsbit_alloc_control (jc->chain, ci->bit_num,
ci->port_name, type, safe,
ci->ctrl_bit_num,
ci->disable_safe_value,
URJ_BSBIT_STATE_Z);
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_PRINT)
printf ("bit %d %s %c %d %d %d %c\n", ci->bit_num,
ci->port_name, bsbit_type_char (type), safe,
ci->ctrl_bit_num, ci->disable_safe_value,
'Z');
}
else
/* stop command procssing here */
cmd[5] = NULL;
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_EXEC)
urj_cmd_run (jc->chain, cmd);
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_PRINT)
print_cmd (cmd);
{
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_EXEC)
// @@@@ RFHH check result
(void)urj_part_bsbit_alloc (jc->chain, ci->bit_num,
ci->port_name, type, safe);
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_PRINT)
printf ("bit %d %s %c %d\n", ci->bit_num, ci->port_name,
bsbit_type_char (type), safe);
}
ci = ci->next;
}
@ -531,17 +493,14 @@ urj_bsdl_process_register_access (urj_bsdl_jtag_ctrl_t *jc)
if (reg_name)
{
char *cmd[] = { "instruction",
instr_name,
cinst->opcode,
reg_name,
NULL
};
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_EXEC)
urj_cmd_run (jc->chain, cmd);
// @@@@ RFHH check result
// @@@@ RFHH check if jc->part equals chain_active_part
(void) urj_part_instruction_define (jc->part, instr_name,
cinst->opcode, reg_name);
if (jc->proc_mode & URJ_BSDL_MODE_INSTR_PRINT)
print_cmd (cmd);
printf ("instruction %s %s %s\n", instr_name, cinst->opcode,
reg_name);
}
cinst = cinst->next;

@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <urjtag/error.h>
#include <urjtag/part.h>
@ -68,8 +69,7 @@ cmd_instruction_run (urj_chain_t *chain, char *params[])
if (urj_part_instruction_length_set (part, len) != URJ_STATUS_OK)
{
printf ("%s\n", urj_error_describe());
urj_error_get_reset();
urj_error_reset();
}
return 1;
}
@ -81,8 +81,7 @@ cmd_instruction_run (urj_chain_t *chain, char *params[])
i = urj_part_instruction_define (part, params[1], params[2], params[3]);
if (!i)
{
printf ("%s\n", urj_error_describe());
urj_error_get_reset();
urj_error_reset();
return 1;
}

@ -57,42 +57,7 @@ cmd_register_run (urj_chain_t *chain, char *params[])
if (urj_cmd_get_number (params[2], &len))
return -1;
if (urj_part_find_data_register (part, params[1]) != NULL)
{
printf (_("Data register '%s' already defined\n"), params[1]);
return 1;
}
dr = urj_part_data_register_alloc (params[1], len);
if (!dr)
{
printf (_("out of memory\n"));
return 1;
}
dr->next = part->data_registers;
part->data_registers = dr;
/* Boundary Scan Register */
if (strcasecmp (dr->name, "BSR") == 0)
{
int i;
part->boundary_length = len;
part->bsbits = malloc (part->boundary_length * sizeof *part->bsbits);
if (!part->bsbits)
{
printf (_("out of memory\n"));
return 1;
}
for (i = 0; i < part->boundary_length; i++)
part->bsbits[i] = NULL;
}
/* Device Identification Register */
if (strcasecmp (dr->name, "DIR") == 0)
urj_tap_register_init (dr->out,
urj_tap_register_get_string (part->id));
(void) urj_part_data_register_define (part, params[1], len);
return 1;
}

@ -32,6 +32,7 @@
#include <stdint.h>
#include <string.h>
#include <stddef.h>
#include <urjtag/flash.h>
#include <urjtag/bus.h>

@ -23,6 +23,9 @@
#include <urjtag/sysdep.h>
#include <stdarg.h>
#include <urjtag/log.h>
#include <urjtag/error.h>
#include <urjtag/jtag.h>
@ -30,20 +33,44 @@ urj_error_state_t urj_error_state;
int urj_debug_mode = 0;
int urj_big_endian = 0;
const urj_error_state_t *
urj_error_get (void)
static int stderr_vprintf (const char *fmt, va_list ap);
urj_log_state_t urj_log_state =
{
.level = URJ_LOG_LEVEL_NORMAL,
.out_vprintf = vprintf,
.err_vprintf = stderr_vprintf,
};
static int
stderr_vprintf(const char *fmt, va_list ap)
{
return &urj_error_state;
return vfprintf (stderr, fmt, ap);
}
urj_error_t
urj_error_get_reset (void)
int
urj_log (urj_log_level_t level, const char *fmt, ...)
{
urj_error_t e = urj_error_state.errnum;
va_list ap;
int r;
urj_error_state.errnum = URJ_ERROR_OK;
if (level < urj_log_state.level)
return 0;
return e;
va_start (ap, fmt);
if (level < URJ_LOG_LEVEL_WARNINGS)
r = urj_log_state.out_vprintf (fmt, ap);
else
r = urj_log_state.err_vprintf (fmt, ap);
va_end (ap);
return r;
}
void
urj_error_reset (void)
{
urj_error_state.errnum = URJ_ERROR_OK;
}
const char *
@ -58,4 +85,19 @@ urj_error_describe (void)
return msg;
}
const char *
urj_error_string (urj_error_t err)
{
switch (err)
{
case URJ_ERROR_OK: return "no error";
case URJ_ERROR_ALREADY: return "already defined";
case URJ_ERROR_OUT_OF_MEMORY: return "out of memory";
case URJ_ERROR_NO_ACTIVE_PART: return "no active part";
case URJ_ERROR_INVALID: return "invalid parameter";
case URJ_ERROR_NOTFOUND: return "not found";
case URJ_ERROR_IO: return "I/O error from OS";
case URJ_ERROR_NO_BUS_DRIVER: return "no bus driver";
case URJ_ERROR_BUFFER_EXHAUSTED: return "buffer exhausted";
}
}

@ -28,8 +28,10 @@
#include <string.h>
#include <stdio.h>
#include <urjtag/part.h>
#include <urjtag/tap_register.h>
#include <urjtag/data_register.h>
#include <urjtag/error.h>
urj_data_register_t *
urj_part_data_register_alloc (const char *name, int len)
@ -41,10 +43,15 @@ urj_part_data_register_alloc (const char *name, int len)
dr = malloc (sizeof *dr);
if (!dr)
{
urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "malloc(%zd) fails",
sizeof *dr);
return NULL;
}
if (strlen (name) > URJ_DATA_REGISTER_MAXLEN)
printf (_("Warning: Data register name too long\n"));
urj_log (URJ_LOG_LEVEL_WARNINGS,
_("Warning: Data register name too long\n"));
strncpy (dr->name, name, URJ_DATA_REGISTER_MAXLEN);
dr->name[URJ_DATA_REGISTER_MAXLEN] = '\0';
@ -60,6 +67,7 @@ urj_part_data_register_alloc (const char *name, int len)
}
if (!dr->in || !dr->out)
{
// retain error state
free (dr->in);
free (dr->out);
free (dr->name);
@ -82,3 +90,47 @@ urj_part_data_register_free (urj_data_register_t *dr)
urj_tap_register_free (dr->out);
free (dr);
}
int
urj_part_data_register_define (urj_part_t *part, const char *name, int len)
{
urj_data_register_t *dr;
if (urj_part_find_data_register (part, name) != NULL)
{
urj_error_set (URJ_ERROR_ALREADY,
_("Data register '%s' already defined"), name);
return URJ_STATUS_FAIL;
}
dr = urj_part_data_register_alloc (name, len);
if (!dr)
// retain error state
return URJ_STATUS_FAIL;
dr->next = part->data_registers;
part->data_registers = dr;
/* Boundary Scan Register */
if (strcasecmp (dr->name, "BSR") == 0)
{
int i;
part->boundary_length = len;
part->bsbits = malloc (part->boundary_length * sizeof *part->bsbits);
if (!part->bsbits)
{
urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "malloc(%zd) fails",
part->boundary_length * sizeof *part->bsbits);
return URJ_STATUS_FAIL;
}
for (i = 0; i < part->boundary_length; i++)
part->bsbits[i] = NULL;
}
/* Device Identification Register */
else if (strcasecmp (dr->name, "DIR") == 0)
urj_tap_register_init (dr->out, urj_tap_register_get_string (part->id));
return URJ_STATUS_OK;
}

@ -1165,13 +1165,7 @@ urj_svf_run (urj_chain_t *chain, FILE *SVF_FILE, int stop_on_mismatch,
/* setup register SDR if not already existing */
if (!(priv.dr = urj_part_find_data_register (priv.part, "SDR")))
{
char *register_cmd[] = { "register",
"SDR",
"32",
NULL
};
if (urj_cmd_run (chain, register_cmd) < 1)
if (urj_part_data_register_define(priv.part, "SDR", 32) != URJ_STATUS_OK)
return;
if (!(priv.dr = urj_part_find_data_register (priv.part, "SDR")))

@ -32,6 +32,7 @@
%{
#include <strings.h>
#include <stdlib.h>
#include <ctype.h>
#include <urjtag/sysdep.h>

@ -41,6 +41,7 @@
#include <urjtag/chain.h>
#include <urjtag/part.h>
#include <urjtag/bus.h>
#include <urjtag/data_register.h>
#include <urjtag/jtag.h>
struct id_record
@ -463,11 +464,7 @@ urj_tap_manual_add (urj_chain_t *chain, int instr_len)
chain->active_part = chain->parts->len - 1;
/* make the BR register available */
cmd[0] = "register";
cmd[1] = "BR";
cmd[2] = "1";
cmd[3] = NULL;
if (urj_cmd_run (chain, cmd) < 1)
if (urj_part_data_register_define (part, "BR", 1) != URJ_STATUS_OK)
{
printf (_("Error: could not set BR register"));
return 0;

Loading…
Cancel
Save