📄 logterm.c
字号:
log_showitems(&savebuf, lines);
log_output(TRUE);
}
else
log_emitstr("trace: Bad number.\n");
}
else if (strcmp(argv[1], "on") == 0)
{
log_emitstr("trace: on (was: ");
log_emitstr(log_tracing ? "on)\n" : "off)\n");
log_tracing = TRUE;
}
else if (strcmp(argv[1], "off") == 0)
{
log_emitstr("trace: off (was: ");
log_emitstr(log_tracing ? "on)\n" : "off)\n");
log_tracing = FALSE;
}
else
{
for(i = 1; i < argc; i++)
{
log_id id;
if (argv[i][0] == '-')
rem = TRUE, p = argv[i]+1;
else if (argv[i][0] == '+')
rem = FALSE, p = argv[i]+1;
else
rem = FALSE, p = argv[i];
id = log_tracebit(p);
if (id != 0)
{
log_set_log_id(id, !rem);
}
else
{
log_emitstr("trace: unknown module ");
log_emitstr(p);
log_emitch('\n');
}
}
}
}
return 0;
}
/*
* Function: log_execute
* Purpose: Accept a command string which will be split up by into
* overwriting spaces into individual strings indexed by
* an array of string pointers, to create a C library like
* argc/argv pair. Look up the command (the first such string,
* if any) in the list of known commands, and if found call
* the execution function. If the command is not found, print
* an error message ("Eh?"!!) and return.
*
* Unless the command set log_deferredprompt, print a prompt
* for the user once command processing complete.
*
* Pre-conditions: log_Initialise called
*
* Params:
* Input: cmd - pointer to command string.
*
* Returns: nothing.
*/
static void log_execute(char *cmd)
{
char *s = cmd;
char *argv[MAXARGS];
int argc, i;
for(argc = 0; argc < MAXARGS && *s != '\0';)
{
while(*s == ' ' || *s == '\t')
s++;
/*
* if quoted arg, search for end of quote;
* else search for next whitespace.
*/
if (*s == '\"')
{
argv[argc++] = ++s;
while(*s != '\"' && *s != '\0')
s++;
}
else
{
argv[argc++] = s;
while(*s != ' ' && *s != '\t' && *s != '\0')
s++;
}
/*
* replace character which ended search (if not EOS)
* with EOS (to terminate this arg) and increment s
* so we can search for more...
*/
if (*s == ' ' || *s == '\t' || *s == '\"')
{
*s = '\0';
s++;
}
}
argv[argc] = NULL;
if (argv[0] == NULL)
goto finish;
for (i = 0; i < log_ncmds; i++)
{
switch(strcmp(argv[0], log_cmds[i].str))
{
case 0: /* match ! */
log_cmds[i].pfn(argc, argv);
break;
case -1: /* no match found */
log_emitstr("Eh?\n");
goto finish;
case 1: /* still looking; */
break;
}
}
finish:
if (log_deferredprompt == FALSE)
log_emitstr(PROMPT);
return;
}
/*
main_table
"", do_nothing, 0,
"help", do_execute, helptable,
NULL,
helptable
"", do_general_help, helptable,
"stat", do_specific_help, "Print Statistics\0syntax: ..."
*/
/*
* Function: log_serialexecute
* Purpose: Wrapper for log_execute, when that function is being called
* from the serializer. It basically maintains various locks,
* and resets the command buffer...
*
* Pre-conditions: none.
*
* Params:
* Input: cmd - the command to execute
*
* Output: none
*
* Returns: none.
*/
static void log_serialexecute(char *cmd)
{
static char buf[CMDBUFSIZE];
strcpy(buf, cmd);
log_commandbuf[0] = '\0';
log_cursor = 0;
log_buflock = FALSE;
log_emitstr("Executing: ");
log_emitstr(buf);
log_output(TRUE);
log_commandbuf[0] = '\0';
log_cursor = 0;
log_execute(buf);
log_cmdlock = FALSE;
}
/*
* Function: log_processchar
* Purpose: CALLED AS AN INTERRUPT ROUTINE!
*
* Process a character received from the controlling
* terminal. Form a command string for execution by
* log_execute, using the serialiser to enable the
* commands to overcome the 'fast' limitation of int
* handlers.
*
* Handle some simplistic echo/deletion codes too.
*
* If log_deferredprompt is set, we must print a prompt
* before eching the character. We must also bracket
* the operation with a request to kill run time trace
* ouptut temporarily while a command is typed.
*
* Pre-conditions: log_Initialise, interrupt handler set up
*
* Params:
* Input: ch - the character read from the terminal
* empty-stack - passed in by the int handler for the
* serialiser.
*
* Returns: nothing.
*/
static void log_processchar(char ch, unsigned int empty_stack)
{
/* can't process -- previous command hasn't copied buffer yet */
if (log_buflock)
return;
if (log_deferredprompt)
{
log_emitstr(PROMPT);
log_output(FALSE);
log_deferredprompt = FALSE;
}
switch(ch)
{
case '\b': /* backspace */
case '\177': /* delete */
if (log_cursor > 0)
{
log_emitstr("\b \b"); /* delete */
log_commandbuf[log_cursor--] = '\0';
log_commandbuf[log_cursor] = '\0';
}
if (log_cursor == 0)
{
log_deferredprompt = TRUE;
log_emitstr("\b\b \b\b"); /* length of prompt */
log_output(TRUE);
}
break;
case '\n':
case '\r':
log_emitch('\n');
if (empty_stack == 0) /* if called from 'pause' */
{
log_output(TRUE);
log_execute(log_commandbuf);
log_commandbuf[0] = '\0';
log_cursor = 0;
}
else
{
/* can't execute; previous command hasn't finished yet */
if (log_cmdlock)
break;
/* lock buffer while we're copying it from log_commandbuf;
lock command interp. until command completed */
log_cmdlock = TRUE;
log_buflock = TRUE;
Angel_SerialiseTask(0,
(angel_SerialisedFn)log_serialexecute,
(void *)log_commandbuf,
empty_stack);
}
break;
default:
if (ch >= 32) /* note: ch signed, so only 32-126 get through (127 above)! */
{
log_commandbuf[log_cursor++] = ch;
log_commandbuf[log_cursor] = '\0';
log_emitch(ch);
log_output(FALSE);
}
break;
}
}
/*
* Function: log_output
* Purpose: To enable/disable real-time trace output while commands are
* being typed. If log_tracing is TRUE, then overall we want tracing,
* while if false, we don't. log_ouptut is intended to bracket
* regions of code when trace would be a bad idea.
*
* Pre-conditions: none.
*
* Params:
* Input: enable true if we're leaving a sensitive area,
* false if entering one.
*
* Returns: Nothing
*/
static void log_output(int enable)
{
if (enable && log_tracing)
{
log_set_logging_options(log_get_logging_options() | WL_PRINTMSG);
}
else
{
log_set_logging_options(log_get_logging_options() & ~WL_PRINTMSG);
}
}
/*
* Function: int_*
* Purpose: Set of handlers for the various prioritised interrupts.
* These routines do all the urgent processing required
* for the interrupt condition
*
* Pre-conditions: Processor is in IRQ / FIQ mode, with a minimal stack,
* AND NO STACK LIMIT SET UP.
*
* Params:
* Input: devid device ID of the driver
*
* port serial port identifier
*
* serchip address of the controller for the given port
*
* empty_stack top of the stack
*
* Returns: Nothing
*/
static void int_msr(unsigned int devid,
unsigned int port,
ST16C552Reg *const serchip,
unsigned int empty_stack)
{
unsigned int msr;
UNUSED(empty_stack);
UNUSED(port);
UNUSED(devid);
/*
* we really couldn't care less about these signals (in
* fact, we shouldn't really ever get this interrupt
* because it is never enabled); read the status to clear
* the interrupt and go away again
*/
msr = serchip->msr;
}
static void int_txrdy(unsigned int devid,
unsigned int port,
ST16C552Reg *const serchip,
unsigned int empty_stack)
{
unsigned int lsr;
UNUSED(empty_stack);
UNUSED(port);
UNUSED(devid);
/*
* we really couldn't care less about these signals (in
* fact, we shouldn't really ever get this interrupt
* because it is never enabled); read the status to clear
* the interrupt and go away again
*/
lsr = serchip->msr;
}
static void int_rxrdy(unsigned int devid,
unsigned int port,
ST16C552Reg *const serchip,
unsigned int empty_stack)
{
UNUSED(devid);
UNUSED(port);
UNUSED(empty_stack);
/*
* keep looping for as long as there are characters
* in the Rx FIFO
*/
while (!st16c552_RxBuffEmpty(serchip))
{
unsigned char ch = st16c552_GetChar(serchip);
log_processchar(ch, empty_stack);
}
}
static void int_lsr(unsigned int devid,
unsigned int port,
ST16C552Reg *const serchip,
unsigned int empty_stack)
{
unsigned int lsr;
IGNORE(devid);
IGNORE(empty_stack);
UNUSED(port);
lsr = serchip->lsr;
}
/*
* Function: angel_LogtermIntHandler
* Purpose: Entry point for interrupts from the ST16C552 UART
* See documentation for angel_IntHandlerFn in devdriv.h
*/
void angel_LogtermIntHandler(unsigned int ident, unsigned int devid,
unsigned int empty_stack)
{
/*
* jump table for prioritised interrupts
*/
static void (*const intjump[4])(const unsigned int devid,
const unsigned int port,
ST16C552Reg *const serchip,
const unsigned int empty_stack) =
{
int_msr, int_txrdy, int_rxrdy, int_lsr
};
unsigned int intsrc;
const unsigned int port = SerCtrl(devid)->port;
ST16C552Reg *const serchip = (port == ST16C552_IDENT_A) ?
(ST16C552Reg *)NISA_SER_A : (ST16C552Reg *)NISA_SER_B;
IGNORE(ident);
/*
* we are only interested in the first three bits of the
* ISR: bit 0 signals whether another Int. is pending,
* bits 1-2 indicate the prioritised interrupt; bit 3 is
* only used to differentiate between a FIFO triggered
* RxRDY Int and a character timeout RxRDY Int, and we
* are not interested in this difference
*/
while (((intsrc = (serchip->isr & 0x07)) & 0x01) == 0)
intjump[intsrc >> 1](devid, port, serchip, empty_stack);
}
#endif /* DEBUG && !MINIMAL ANGEL */
/* EOF logterm.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -