simtrace: introduce statistics

the statistics count various events like overruns, parity errors,
missing rctx and can dump those stats via USB as well as on the serial
console.
This commit is contained in:
Harald Welte 2012-03-23 00:03:45 +01:00
parent 4c0cf591b0
commit 868b6d0c68
4 changed files with 70 additions and 2 deletions

View File

@ -15,6 +15,7 @@ enum simtrace_usb_msgt {
SIMTRACE_MSGT_NULL,
SIMTRACE_MSGT_DATA,
SIMTRACE_MSGT_RESET, /* reset was asserted, no more data */
SIMTRACE_MSGT_STATS, /* statistics */
};
/* flags for MSGT_DATA */
@ -22,4 +23,15 @@ enum simtrace_usb_msgt {
#define SIMTRACE_FLAG_WTIME_EXP 0x04 /* work waiting time expired */
#define SIMTRACE_FLAG_PPS_FIDI 0x08 /* Fi/Di values in res[2] */
struct simtrace_stats {
u_int32_t no_rctx;
u_int32_t rctx_sent;
u_int32_t rst;
u_int32_t pps;
u_int32_t bytes;
u_int32_t parity_err;
u_int32_t frame_err;
u_int32_t overrun;
} stats;
#endif /* SIMTRACE_USB_H */

View File

@ -106,6 +106,8 @@ struct iso7816_3_handle {
int rctx_must_be_sent;
struct req_ctx *rctx;
struct simtrace_stats stats;
};
struct iso7816_3_handle isoh;
@ -123,6 +125,20 @@ static const u_int8_t di_table[] = {
12, 20, 2, 4, 8, 16, 32, 64,
};
void iso_uart_stats_dump(void)
{
DEBUGPCRF("no_rctx: %u, rctx_sent: %u, rst: %u, pps: %u, bytes: %u, "
"parity_err: %u, frame_err: %u, overrun:%u",
isoh.stats.no_rctx, isoh.stats.rctx_sent, isoh.stats.rst,
isoh.stats.pps, isoh.stats.bytes, isoh.stats.parity_err,
isoh.stats.frame_err, isoh.stats.overrun);
}
struct simtrace_stats *iso_uart_stats_get(void)
{
return &isoh.stats;
}
/* compute the F/D ratio based on Fi and Di values */
static int compute_fidi_ratio(u_int8_t fi, u_int8_t di)
{
@ -186,6 +202,8 @@ static void send_rctx(struct iso7816_3_handle *ih)
memset(&ih->sh, 0, sizeof(ih->sh));
ih->rctx = NULL;
ih->stats.rctx_sent++;
}
@ -476,6 +494,8 @@ static void process_byte(struct iso7816_3_handle *ih, u_int8_t byte)
int new_state = -1;
struct req_ctx *rctx;
ih->stats.bytes++;
if (!ih->rctx)
refill_rctx(ih);
@ -489,6 +509,7 @@ static void process_byte(struct iso7816_3_handle *ih, u_int8_t byte)
case ISO7816_S_WAIT_APDU:
if (byte == 0xff) {
new_state = process_byte_pts(ih, byte);
ih->stats.pps++;
goto out_silent;
}
case ISO7816_S_IN_APDU:
@ -506,7 +527,8 @@ static void process_byte(struct iso7816_3_handle *ih, u_int8_t byte)
rctx = ih->rctx;
if (!rctx) {
DEBUGPCR("==> Lost byte, missing rctx");
//DEBUGPCR("==> Lost byte, missing rctx");
ih->stats.no_rctx++;
return;
}
@ -562,6 +584,13 @@ static __ramfunc void usart_irq(void)
//DEBUGP("NER=%02x ", nb_err);
/* clear the status */
usart->US_CR |= AT91C_US_RSTSTA;
if (csr & AT91C_US_PARE)
isoh.stats.parity_err++;
if (csr & AT91C_US_FRAME)
isoh.stats.frame_err++;
if (csr & AT91C_US_OVRE)
isoh.stats.overrun++;
}
if (csr & AT91C_US_INACK) {
@ -579,6 +608,7 @@ static void reset_pin_irq(u_int32_t pio)
} else {
DEBUGPCR("RST");
set_state(&isoh, ISO7816_S_WAIT_ATR);
isoh.stats.rst++;
}
}
@ -647,6 +677,7 @@ void iso_uart_init(void)
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, SIMTRACE_PIO_IO, SIMTRACE_PIO_CLK);
AT91F_PIO_CfgInput(AT91C_BASE_PIOA, SIMTRACE_PIO_nRST);
/* Configure Interrupt */
AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_US0,
OPENPCD_IRQ_PRIO_USART,
AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL, &usart_irq);

View File

@ -1,4 +1,6 @@
struct simtrace_stats *iso_uart_stats_get(void);
void iso_uart_stats_dump(void);
void iso_uart_dump(void);
void iso_uart_rst(unsigned int state);
void iso_uart_rx_mode(void);

View File

@ -33,6 +33,7 @@
#include <simtrace/tc_etu.h>
#include <simtrace/iso7816_uart.h>
#include <simtrace/sim_switch.h>
#include <simtrace_usb.h>
enum simtrace_md {
SIMTRACE_MD_OFF,
@ -117,6 +118,24 @@ static void simtrace_set_mode(enum simtrace_md mode)
}
}
static int simtrace_usb_in(struct req_ctx *rctx)
{
struct openpcd_hdr *poh = (struct openpcd_hdr *) &rctx->data[0];
struct simtrace_stats *stats_in;
struct simtrace_stats *stats = (struct simtrace_stats *) poh->data;
switch (poh->cmd) {
case SIMTRACE_MSGT_STATS:
stats_in = iso_uart_stats_get();
memcpy(stats, stats_in, sizeof(*stats));
req_ctx_set_state(rctx, RCTX_STATE_UDP_EP2_PENDING);
break;
default:
req_ctx_set_state(rctx, RCTX_STATE_FREE);
break;
}
}
void _init_func(void)
{
/* low-level hardware initialization */
@ -126,6 +145,7 @@ void _init_func(void)
sim_switch_init();
usbtest_init();
usb_hdlr_register(&simtrace_usb_in, OPENPCD_CMD_CLS_ADC);
/* high-level protocol */
//opicc_usbapi_init();
@ -150,7 +170,7 @@ static void help(void)
"l: set nRST to low (active)\r\n"
"h: set nRST to high (inactive)\r\n"
"o: set nRST to input\r\n"
"r: set Rx mode for UART\r\n"
"t: ISO UART statistics\r\n"
"s: disconnect SIM bus switch\r\n"
"S: connect SIM bus switch\r\n");
}
@ -167,6 +187,9 @@ int _main_dbgu(char key)
case 'S':
simtrace_set_mode(SIMTRACE_MD_SNIFFER);
break;
case 't':
iso_uart_stats_dump();
break;
case 'r':
iso_uart_rx_mode();
break;