mirror of https://github.com/zrafa/xinu-avr.git
32 changed files with 6346 additions and 11 deletions
@ -0,0 +1,6 @@
|
||||
|
||||
This app needs the below modificationes into conf/Configuration file: |
||||
|
||||
#define NPROC 4 /* number of user processes */ |
||||
#define NSEM 6 /* number of semaphores */ |
||||
|
||||
@ -0,0 +1,137 @@
|
||||
/* xsh_test.c - xsh_test */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
|
||||
/*
|
||||
void sndA(void); |
||||
void sndB(void); |
||||
*/ |
||||
// void prod2(sid32 consumed, sid32 produced, int a);
|
||||
// void cons2(sid32 consumed, sid32 produced, int a);
|
||||
|
||||
int32 n = 0; |
||||
int32 j = 0; |
||||
|
||||
//void cons2(sid32 consumed, sid32 produced, int a);
|
||||
void cons2(int argc, char * argv[]); |
||||
void prod2(int argc, char * argv[]); |
||||
|
||||
void freem(void) |
||||
{ |
||||
int mask = disable(); |
||||
uint32 free_mem=0; |
||||
struct memblk *memptr; |
||||
/* Output Xinu memory layout */ |
||||
free_mem = 0; |
||||
for (memptr = memlist.mnext; memptr != NULL; |
||||
memptr = memptr->mnext) { |
||||
free_mem += memptr->mlength; |
||||
} |
||||
kprintf("\n\rFreeMEM:%d\n", free_mem); |
||||
restore(mask); |
||||
} |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xhs_test |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
process main(void) |
||||
{ |
||||
// int32 a = roundmb(81);
|
||||
|
||||
/* EEPROM TEST
|
||||
char buf[6]; |
||||
char buf2[6]; |
||||
memset(buf, 0, 6); |
||||
memset(buf2, 0, 6); |
||||
buf[0] = 49; |
||||
buf[1] = 50; |
||||
printf("b=%s\n", buf); |
||||
write(EEPROM0, buf, 4); |
||||
buf[0] = 0; |
||||
buf[1] = 0; |
||||
read(EEPROM0, buf2, 4); |
||||
buf2[1] = 0; |
||||
printf("b=%s\n", buf2); |
||||
blink_avr(); |
||||
blink_avr(); |
||||
blink_avr(); |
||||
blink_avr(); |
||||
blink_avr(); |
||||
blink_avr(); |
||||
EN EEPROM TEST */ |
||||
|
||||
sid32 produced, consumed; |
||||
consumed = semcreate(0); |
||||
produced = semcreate(1); |
||||
printf ("prod=%d \n", produced); |
||||
printf ("consu=%d \n", consumed); |
||||
blink_avr(); |
||||
blink_avr(); |
||||
resume(create(cons2, 200, 20, "cons", 3, consumed, produced, 4)); |
||||
resume(create(prod2, 200, 20, "prod", 3, consumed, produced, 4)); |
||||
return 0; |
||||
} |
||||
|
||||
void prod2(int argc, char * argv[]) |
||||
{ |
||||
sid32 consumed, produced; |
||||
consumed = argv[0]; |
||||
produced = argv[1]; |
||||
int a = argv[2]; |
||||
int32 i; |
||||
|
||||
printf("argc=%d\n", argc); |
||||
printf("n1=%d\n", consumed); |
||||
printf("n2=%d\n", produced); |
||||
printf("n3=%d\n", a); |
||||
//for (i=1; i<=2000; i++) {
|
||||
for (i=1; i<=100; i++) { |
||||
// printf("n3=%d\n", a);
|
||||
wait(consumed); |
||||
j = j + 1; |
||||
//n++;
|
||||
signal(produced); |
||||
} |
||||
} |
||||
|
||||
void cons2(int argc, char * argv[]) |
||||
//void cons2(sid32 consumed, sid32 produced, int a)
|
||||
{ |
||||
int32 i; |
||||
|
||||
sid32 consumed, produced; |
||||
consumed = argv[0]; |
||||
produced = argv[1]; |
||||
//for (i=1; i<=2000; i++) {
|
||||
for (i=1; i<=100; i++) { |
||||
wait(produced); |
||||
n = n + (j*2); |
||||
printf("n is %d \n", n); |
||||
signal(consumed); |
||||
} |
||||
|
||||
} |
||||
/* original test
|
||||
process test(int nargs, char *args[]) |
||||
{ |
||||
resume(create(sndA, 64, 20, "proc1", 0)); |
||||
resume(create(sndB, 64, 20, "proc1", 0)); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
void sndA(void) |
||||
{ |
||||
while(1) |
||||
putc(CONSOLE, 'A'); |
||||
} |
||||
|
||||
void sndB(void) |
||||
{ |
||||
while(1) |
||||
putc(CONSOLE, 'B'); |
||||
|
||||
} |
||||
end of original test */ |
||||
@ -0,0 +1,6 @@
|
||||
|
||||
This app needs the below modificationes into conf/Configuration file: |
||||
|
||||
#define NPROC 3 /* number of user processes */ |
||||
#define NSEM 2 /* number of semaphores */ |
||||
|
||||
@ -0,0 +1,119 @@
|
||||
/* addargs.c - addargs */ |
||||
|
||||
#include <xinu.h> |
||||
#include "shprototypes.h" |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* addargs - Add local copy of argv-style arguments to the stack of |
||||
* a command process that has been created by the shell |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
status addargs( |
||||
pid32 pid, /* ID of process to use */ |
||||
int32 ntok, /* Count of arguments */ |
||||
int32 tok[], /* Index of tokens in tokbuf */ |
||||
int32 tlen, /* Length of data in tokbuf */ |
||||
char *tokbuf, /* Array of null-term. tokens */ |
||||
void *dummy /* Dummy argument that was */ |
||||
/* used at creation and must */ |
||||
/* be replaced by a pointer */ |
||||
/* to an argument vector */ |
||||
) |
||||
{ |
||||
intmask mask; /* Saved interrupt mask */ |
||||
struct procent *prptr; /* Ptr to process' table entry */ |
||||
uint32 aloc; /* Argument location in process */ |
||||
/* stack as an integer */ |
||||
uint32 *argloc; /* Location in process's stack */ |
||||
/* to place args vector */ |
||||
char *argstr; /* Location in process's stack */ |
||||
/* to place arg strings */ |
||||
uint32 *search; /* pointer that searches for */ |
||||
/* dummy argument on stack */ |
||||
uint32 *aptr; /* Walks through args array */ |
||||
int32 i; /* Index into tok array */ |
||||
|
||||
mask = disable(); |
||||
|
||||
/* Check argument count and data length */ |
||||
|
||||
if ( (ntok <= 0) || (tlen < 0) ) { |
||||
// serial_put_char('M');
|
||||
restore(mask); |
||||
return SYSERR; |
||||
} |
||||
|
||||
prptr = &proctab[pid]; |
||||
|
||||
/* Compute lowest location in the process stack where the */ |
||||
/* args array will be stored followed by the argument */ |
||||
/* strings */ |
||||
|
||||
// aloc = (uint32) (prptr->prstkbase
|
||||
// - prptr->prstklen + sizeof(uint32));
|
||||
// argloc = (uint32*) ((aloc + 3) & ~0x3); /* round multiple of 4 */
|
||||
|
||||
/* Compute the first location beyond args array for the strings */ |
||||
//
|
||||
// argstr = (char *) (argloc + (ntok+1)); /* +1 for a null ptr */
|
||||
|
||||
/* Set each location in the args vector to be the address of */ |
||||
/* string area plus the offset of this argument */ |
||||
|
||||
// for (aptr=argloc, i=0; i < ntok; i++) {
|
||||
// *aptr++ = (uint32) (argstr + tok[i]);
|
||||
// }
|
||||
|
||||
/* Add a null pointer to the args array */ |
||||
|
||||
// *aptr++ = (uint32)NULL;
|
||||
|
||||
/* Copy the argument strings from tokbuf into process's stack */ |
||||
/* just beyond the args vector */ |
||||
|
||||
// memcpy(aptr, tokbuf, tlen);
|
||||
|
||||
/* Find the second argument in process's stack */ |
||||
|
||||
// for (search = (uint32 *)prptr->prstkptr;
|
||||
// search < (uint32 *)prptr->prstkbase; search++) {
|
||||
|
||||
/* If found, replace with the address of the args vector*/ |
||||
|
||||
// if (*search == (uint32)dummy) {
|
||||
// *search = (uint32)argloc;
|
||||
// restore(mask);
|
||||
// return OK;
|
||||
// }
|
||||
// }
|
||||
|
||||
/* Argument value not found on the stack - report an error */ |
||||
|
||||
// serial_put_char('\n');
|
||||
|
||||
// for (fromarg=Shl.shtok ; nargs > 0 ; nargs--) {
|
||||
for (i=0 ; i < ntok; i++) { |
||||
// prptr->parg[i+prptr->pargs] = (int)tok[i]; /******** change int parg[] TO void *parg[] in proc.h ******/
|
||||
// prptr->parg[i+prptr->pargs] = (void *)tok[i]; /******** change int parg[] TO void *parg[] in proc.h ******/
|
||||
// serial_put_char(48+i);
|
||||
// serial_put_char(' ');
|
||||
// serial_put_char(tokbuf[tok[i]]);
|
||||
// serial_put_char(' ');
|
||||
prptr->parg[i] = &tokbuf[tok[i]]; |
||||
|
||||
} |
||||
// *toarg = 0;
|
||||
prptr->pargs = ntok; |
||||
prptr->parg[ntok] = 0; |
||||
|
||||
// RAFA prptr->pargs += ntok;
|
||||
// RAFA prptr->parg[prptr->pargs] = 0;
|
||||
/* machine/compiler dependent pass arguments to created process */ |
||||
prptr->pregs[24] = lobyte((unsigned)prptr->pargs); /*r24*/ |
||||
prptr->pregs[25] = hibyte((unsigned)prptr->pargs); |
||||
|
||||
|
||||
restore(mask); |
||||
return OK; |
||||
// return SYSERR;
|
||||
} |
||||
@ -0,0 +1,148 @@
|
||||
/* lexan.c - lexan */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* lexan - Ad hoc lexical analyzer to divide command line into tokens |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
|
||||
int32 lexan ( |
||||
char *line, /* Input line terminated with */ |
||||
/* NEWLINE or NULLCH */ |
||||
int32 len, /* Length of the input line, */ |
||||
/* including NEWLINE */ |
||||
char *tokbuf, /* Buffer into which tokens are */ |
||||
/* stored with a null */ |
||||
/* following each token */ |
||||
int32 *tlen, /* Place to store number of */ |
||||
/* chars in tokbuf */ |
||||
int32 tok[], /* Array of pointers to the */ |
||||
/* start of each token */ |
||||
int32 toktyp[] /* Array that gives the type */ |
||||
/* of each token */ |
||||
) |
||||
{ |
||||
char quote; /* Character for quoted string */ |
||||
uint32 ntok; /* Number of tokens found */ |
||||
char *p; /* Pointer that walks along the */ |
||||
/* input line */ |
||||
int32 tbindex; /* Index into tokbuf */ |
||||
char ch; /* Next char from input line */ |
||||
|
||||
/* Start at the beginning of the line with no tokens */ |
||||
|
||||
ntok = 0; |
||||
p = line; |
||||
tbindex = 0; |
||||
|
||||
/* While not yet at end of line, get next token */ |
||||
|
||||
while ( (*p != NULLCH) && (*p != SH_NEWLINE) ) { |
||||
|
||||
/* If too many tokens, return error */ |
||||
|
||||
if (ntok >= SHELL_MAXTOK) { |
||||
return SYSERR; |
||||
} |
||||
|
||||
/* Skip whitespace before token */ |
||||
|
||||
while ( (*p == SH_BLANK) || (*p == SH_TAB) ) { |
||||
p++; |
||||
} |
||||
|
||||
/* Stop parsing at end of line (or end of string) */ |
||||
|
||||
ch = *p; |
||||
if ( (ch==SH_NEWLINE) || (ch==NULLCH) ) { |
||||
*tlen = tbindex; |
||||
return ntok; |
||||
} |
||||
|
||||
/* Set next entry in tok array to be an index to the */ |
||||
/* current location in the token buffer */ |
||||
|
||||
tok[ntok] = tbindex; /* the start of the token */ |
||||
|
||||
/* Set the token type */ |
||||
|
||||
switch (ch) { |
||||
|
||||
case SH_AMPER: toktyp[ntok] = SH_TOK_AMPER; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
case SH_LESS: toktyp[ntok] = SH_TOK_LESS; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
case SH_GREATER: toktyp[ntok] = SH_TOK_GREATER; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
default: toktyp[ntok] = SH_TOK_OTHER; |
||||
}; |
||||
|
||||
/* Handle quoted string (single or double quote) */ |
||||
|
||||
if ( (ch==SH_SQUOTE) || (ch==SH_DQUOTE) ) { |
||||
quote = ch; /* remember opening quote */ |
||||
|
||||
/* Copy quoted string to arg area */ |
||||
|
||||
p++; /* Move past starting quote */ |
||||
|
||||
while ( ((ch=*p++) != quote) && (ch != SH_NEWLINE) |
||||
&& (ch != NULLCH) ) { |
||||
tokbuf[tbindex++] = ch; |
||||
} |
||||
if (ch != quote) { /* string missing end quote */ |
||||
return SYSERR; |
||||
} |
||||
|
||||
/* Finished string - count token and go on */ |
||||
|
||||
tokbuf[tbindex++] = NULLCH; /* terminate token */ |
||||
ntok++; /* count string as one token */ |
||||
continue; /* go to next token */ |
||||
} |
||||
|
||||
/* Handle a token other than a quoted string */ |
||||
|
||||
tokbuf[tbindex++] = ch; /* put first character in buffer*/ |
||||
p++; |
||||
|
||||
while ( ((ch = *p) != SH_NEWLINE) && (ch != NULLCH) |
||||
&& (ch != SH_LESS) && (ch != SH_GREATER) |
||||
&& (ch != SH_BLANK) && (ch != SH_TAB) |
||||
&& (ch != SH_AMPER) && (ch != SH_SQUOTE) |
||||
&& (ch != SH_DQUOTE) ) { |
||||
tokbuf[tbindex++] = ch; |
||||
p++; |
||||
} |
||||
|
||||
/* Report error if other token is appended */ |
||||
|
||||
if ( (ch == SH_SQUOTE) || (ch == SH_DQUOTE) |
||||
|| (ch == SH_LESS) || (ch == SH_GREATER) ) { |
||||
return SYSERR; |
||||
} |
||||
|
||||
tokbuf[tbindex++] = NULLCH; /* terminate the token */ |
||||
|
||||
ntok++; /* count valid token */ |
||||
|
||||
} |
||||
*tlen = tbindex; |
||||
return ntok; |
||||
} |
||||
@ -0,0 +1,331 @@
|
||||
/* main.c - main */ |
||||
|
||||
/* shell.c - shell */ |
||||
|
||||
|
||||
#include <xinu.h> |
||||
//#include <stdio.h>
|
||||
#include "shprototypes.h" |
||||
|
||||
/************************************************************************/ |
||||
/* Table of Xinu shell commands and the function associated with each */ |
||||
/************************************************************************/ |
||||
const struct cmdent cmdtab[] = { |
||||
{"memstat", FALSE, xsh_memstat}, /* Make built-in */ |
||||
{"editor", FALSE, xsh_editor}, /* Make built-in */ |
||||
{"basic", FALSE, xsh_basic}, /* Make built-in */ |
||||
{"echo", FALSE, xsh_echo} |
||||
// {"argecho", TRUE, xsh_argecho},
|
||||
// {"cat", FALSE, xsh_cat},
|
||||
// {"clear", TRUE, xsh_clear},
|
||||
// {"date", FALSE, xsh_date},
|
||||
// {"devdump", FALSE, xsh_devdump},
|
||||
// {"echo", FALSE, xsh_echo},
|
||||
// {"exit", TRUE, xsh_exit},
|
||||
// {"help", FALSE, xsh_help},
|
||||
// {"kill", TRUE, xsh_kill},
|
||||
// {"memdump", FALSE, xsh_memdump},
|
||||
// {"ps", FALSE, xsh_ps},
|
||||
// {"sleep", FALSE, xsh_sleep},
|
||||
// {"uptime", FALSE, xsh_uptime},
|
||||
// {"?", FALSE, xsh_help}
|
||||
|
||||
}; |
||||
|
||||
uint32 ncmd = sizeof(cmdtab) / sizeof(struct cmdent); |
||||
|
||||
/************************************************************************/ |
||||
/* shell - Provide an interactive user interface that executes */ |
||||
/* commands. Each command begins with a command name, has */ |
||||
/* a set of optional arguments, has optional input or */ |
||||
/* output redirection, and an optional specification for */ |
||||
/* background execution (ampersand). The syntax is: */ |
||||
/* */ |
||||
/* command_name [args*] [redirection] [&] */ |
||||
/* */ |
||||
/* Redirection is either or both of: */ |
||||
/* */ |
||||
/* < input_file */ |
||||
/* or */ |
||||
/* > output_file */ |
||||
/* */ |
||||
/************************************************************************/ |
||||
|
||||
process main(void) |
||||
{ |
||||
char buf[SHELL_BUFLEN]; /* Input line (large enough for */ |
||||
int32 len; /* Length of line read */ |
||||
char tokbuf[SHELL_BUFLEN + /* Buffer to hold a set of */ |
||||
SHELL_MAXTOK]; /* Contiguous null-terminated */ |
||||
int32 tlen; /* Current length of all data */ |
||||
/* in array tokbuf */ |
||||
int32 tok[SHELL_MAXTOK]; /* Index of each token in */ |
||||
int32 toktyp[SHELL_MAXTOK]; /* Type of each token in tokbuf */ |
||||
int32 ntok; /* Number of tokens on line */ |
||||
pid32 child; /* Process ID of spawned child */ |
||||
bool8 backgnd; /* Run command in background? */ |
||||
char *outname, *inname; /* Pointers to strings for file */ |
||||
/* names that follow > and < */ |
||||
did32 stdinput, stdoutput; /* Descriptors for redirected */ |
||||
/* input and output */ |
||||
int32 i; /* Index into array of tokens */ |
||||
int32 j; /* Index into array of commands */ |
||||
int32 msg; /* Message from receive() for */ |
||||
/* child termination */ |
||||
int32 tmparg; /* Address of this var is used */ |
||||
/* when first creating child */ |
||||
/* process, but is replaced */ |
||||
char *src, *cmp; /* Pointers used during name */ |
||||
/* comparison */ |
||||
bool8 diff; /* Was difference found during */ |
||||
char *args[SHELL_MAXTOK]; /* Argument vector passed to */ |
||||
/* builtin commands */ |
||||
did32 dev = 0; /* ID of tty device from which */ |
||||
|
||||
/* Print shell banner and startup message */ |
||||
|
||||
/*
|
||||
fprintf(dev, "\n\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", |
||||
SHELL_BAN0,SHELL_BAN1,SHELL_BAN2,SHELL_BAN3,SHELL_BAN4, |
||||
SHELL_BAN5,SHELL_BAN6,SHELL_BAN7,SHELL_BAN8,SHELL_BAN9,SHELL_BAN10); |
||||
|
||||
fprintf(dev, "%s\n\n", SHELL_STRTMSG); |
||||
*/ |
||||
|
||||
/* Continually prompt the user, read input, and execute command */ |
||||
|
||||
|
||||
while (TRUE) { |
||||
|
||||
// RAFA
|
||||
// fprintf(dev, "\033[2J");
|
||||
// fprintf(dev, "\033[H");
|
||||
|
||||
/* Display prompt */ |
||||
fprintf(dev, SHELL_PROMPT); |
||||
|
||||
|
||||
len = read(dev, buf, sizeof(buf)); |
||||
|
||||
/* Exit gracefully on end-of-file */ |
||||
|
||||
if (len == EOF) { |
||||
break; |
||||
} |
||||
|
||||
/* If line contains only NEWLINE, go to next line */ |
||||
|
||||
if (len <= 1) { |
||||
continue; |
||||
} |
||||
|
||||
buf[len] = SH_NEWLINE; /* terminate line */ |
||||
|
||||
/* Parse input line and divide into tokens */ |
||||
|
||||
ntok = lexan(buf, len, tokbuf, &tlen, tok, toktyp); |
||||
|
||||
/* Handle parsing error */ |
||||
|
||||
if (ntok == SYSERR) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
|
||||
/* If line is empty, go to next input line */ |
||||
|
||||
if (ntok == 0) { |
||||
// fprintf(dev, "\n");
|
||||
continue; |
||||
} |
||||
|
||||
/* If last token is '&', set background */ |
||||
|
||||
if (toktyp[ntok-1] == SH_TOK_AMPER) { |
||||
ntok-- ; |
||||
tlen-= 2; |
||||
backgnd = TRUE; |
||||
} else { |
||||
backgnd = FALSE; |
||||
} |
||||
|
||||
|
||||
/* Check for input/output redirection (default is none) */ |
||||
|
||||
outname = inname = NULL; |
||||
if ( (ntok >=3) && ( (toktyp[ntok-2] == SH_TOK_LESS) |
||||
||(toktyp[ntok-2] == SH_TOK_GREATER))){ |
||||
if (toktyp[ntok-1] != SH_TOK_OTHER) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
if (toktyp[ntok-2] == SH_TOK_LESS) { |
||||
inname = &tokbuf[tok[ntok-1]]; |
||||
} else { |
||||
outname = &tokbuf[tok[ntok-1]]; |
||||
} |
||||
ntok -= 2; |
||||
tlen = tok[ntok]; |
||||
} |
||||
|
||||
|
||||
if ( (ntok >=3) && ( (toktyp[ntok-2] == SH_TOK_LESS) |
||||
||(toktyp[ntok-2] == SH_TOK_GREATER))){ |
||||
if (toktyp[ntok-1] != SH_TOK_OTHER) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
if (toktyp[ntok-2] == SH_TOK_LESS) { |
||||
if (inname != NULL) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
inname = &tokbuf[tok[ntok-1]]; |
||||
} else { |
||||
if (outname != NULL) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
outname = &tokbuf[tok[ntok-1]]; |
||||
} |
||||
ntok -= 2; |
||||
tlen = tok[ntok]; |
||||
} |
||||
|
||||
/* Verify remaining tokens are type "other" */ |
||||
|
||||
for (i=0; i<ntok; i++) { |
||||
if (toktyp[i] != SH_TOK_OTHER) { |
||||
break; |
||||
} |
||||
} |
||||
if ((ntok == 0) || (i < ntok)) { |
||||
// fprintf(dev, SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
|
||||
stdinput = stdoutput = dev; |
||||
|
||||
/* Lookup first token in the command table */ |
||||
|
||||
for (j = 0; j < ncmd; j++) { |
||||
src = cmdtab[j].cname; |
||||
cmp = tokbuf; |
||||
diff = FALSE; |
||||
while (*src != NULLCH) { |
||||
if (*cmp != *src) { |
||||
diff = TRUE; |
||||
break; |
||||
} |
||||
src++; |
||||
cmp++; |
||||
} |
||||
if (diff || (*cmp != NULLCH)) { |
||||
continue; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/* Handle command not found */ |
||||
|
||||
if (j >= ncmd) { |
||||
// fprintf(dev, "command %s not found\n", tokbuf);
|
||||
continue; |
||||
} |
||||
|
||||
/* Handle built-in command */ |
||||
|
||||
if (cmdtab[j].cbuiltin) { /* No background or redirect. */ |
||||
if (inname != NULL || outname != NULL || backgnd){ |
||||
// fprintf(dev, SHELL_BGERRMSG);
|
||||
continue; |
||||
} else { |
||||
/* Set up arg vector for call */ |
||||
|
||||
for (i=0; i<ntok; i++) { |
||||
args[i] = &tokbuf[tok[i]]; |
||||
} |
||||
|
||||
/* Call builtin shell function */ |
||||
|
||||
if ((*cmdtab[j].cfunc)(ntok, args) |
||||
== SHELL_EXIT) { |
||||
break; |
||||
} |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
/* Open files and redirect I/O if specified */ |
||||
|
||||
if (inname != NULL) { |
||||
stdinput = open(NAMESPACE,inname,"ro"); |
||||
if (stdinput == SYSERR) { |
||||
// fprintf(dev, SHELL_INERRMSG, inname);
|
||||
continue; |
||||
} |
||||
} |
||||
if (outname != NULL) { |
||||
stdoutput = open(NAMESPACE,outname,"w"); |
||||
if (stdoutput == SYSERR) { |
||||
// fprintf(dev, SHELL_OUTERRMSG, outname);
|
||||
continue; |
||||
} else { |
||||
control(stdoutput, F_CTL_TRUNC, 0, 0); |
||||
} |
||||
} |
||||
|
||||
// int eeprom_fd = open(RAM0, nombre, "w");
|
||||
// char raf[32] = "pepe";
|
||||
// write(fd, pepe, 32);
|
||||
// int eeprom_fd = open(RAM0, nombre, "w");
|
||||
|
||||
/* Spawn child thread for non-built-in commands */ |
||||
|
||||
// RAFA child = create(cmdtab[j].cfunc,
|
||||
// RAFA SHELL_CMDSTK, SHELL_CMDPRIO,
|
||||
// RAFA cmdtab[j].cname, 2, ntok, &tmparg);
|
||||
/* 160 bytes de stack perfecto */ |
||||
child = create(cmdtab[j].cfunc, |
||||
460, SHELL_CMDPRIO, |
||||
cmdtab[j].cname, 2, ntok, &tmparg); |
||||
|
||||
/* If creation or argument copy fails, report error */ |
||||
|
||||
// serial_put_char('X');
|
||||
// if (child == SYSERR)
|
||||
// serial_put_char('Y');
|
||||
if ((child == SYSERR) || |
||||
(addargs(child, ntok, tok, tlen, tokbuf, &tmparg) |
||||
== SYSERR) ) { |
||||
// serial_put_char('Z');
|
||||
fprintf(dev, SHELL_CREATMSG); |
||||
continue; |
||||
} |
||||
|
||||
/* Set stdinput and stdoutput in child to redirect I/O */ |
||||
|
||||
proctab[child].prdesc[0] = stdinput; |
||||
proctab[child].prdesc[1] = stdoutput; |
||||
|
||||
msg = recvclr(); |
||||
resume(child); |
||||
|
||||
// RAFA AGREGA
|
||||
resched(); |
||||
// serial_put_char('X');
|
||||
|
||||
if (! backgnd) { |
||||
msg = receive(); |
||||
while (msg != child) { |
||||
msg = receive(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Terminate the shell process by returning from the top level */ |
||||
|
||||
// fprintf(dev,SHELL_EXITMSG);
|
||||
return OK; |
||||
} |
||||
@ -0,0 +1,24 @@
|
||||
/* xsh_echo.c - xsh_echo */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xhs_echo - write argument strings to stdout |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_echo(int nargs, char *args[]) |
||||
{ |
||||
int32 i; /* walks through args array */ |
||||
|
||||
if (nargs > 1) { |
||||
printf("%s", args[1]); |
||||
|
||||
for (i = 2; i < nargs; i++) { |
||||
printf(" %s", args[i]); |
||||
} |
||||
} |
||||
printf("\n"); |
||||
|
||||
return 0; |
||||
} |
||||
@ -0,0 +1,101 @@
|
||||
/* xsh_editor.c - xsh_editor */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
|
||||
// #include "text_buffer.h"
|
||||
#define NLINES 3 |
||||
#define LINE_LEN 24 |
||||
|
||||
//extern unsigned char program[NLINES*LINE_LEN];
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xhs_editor - text editor
|
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_editor(int nargs, char *args[]) |
||||
{ |
||||
|
||||
/*
|
||||
int32 i; |
||||
|
||||
if (nargs > 1) { |
||||
printf("%s", args[1]); |
||||
|
||||
for (i = 2; i < nargs; i++) { |
||||
printf(" %s", args[i]); |
||||
} |
||||
} |
||||
printf("\n"); |
||||
*/ |
||||
char buffer[NLINES*LINE_LEN]; |
||||
int page = 0; |
||||
int i = 0; |
||||
int j = 0; |
||||
int dev = 0; |
||||
int c; |
||||
int cursor = 0; |
||||
int line = 0; |
||||
|
||||
fprintf(dev, "\033[2J"); |
||||
fprintf(dev, "\033[H"); |
||||
fprintf(dev, "Text editor. page: %i\n", page); |
||||
|
||||
for (i=0; i<NLINES*LINE_LEN; i++) |
||||
buffer[i] = 0; |
||||
|
||||
// control(dev, TC_NOECHO, 0, 0);
|
||||
|
||||
control(dev, TC_MODER, 0, 0); |
||||
|
||||
while (TRUE) { |
||||
// c = -1;
|
||||
c = getc(0); |
||||
//printf("%i \n", c);
|
||||
if (c == '!') { |
||||
control(dev, TC_MODEC, 0, 0); |
||||
return 0; |
||||
}; |
||||
if (c == 27) { |
||||
c = getc(0); |
||||
if (c == '[') { |
||||
c = getc(0); |
||||
switch (c) { |
||||
case 'D':
|
||||
cursor--; if (cursor < 0) cursor = 0; |
||||
printf("\033[D"); |
||||
break; |
||||
case 'C':
|
||||
cursor++;
|
||||
printf("\033[C"); |
||||
if (cursor > LINE_LEN) { |
||||
cursor = 0; |
||||
line++; |
||||
printf("\n\r"); |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
printf("%c", c); |
||||
buffer[line*LINE_LEN+cursor] = c; |
||||
cursor++; |
||||
if (cursor > LINE_LEN) { |
||||
cursor = 0; |
||||
line++; |
||||
printf("\n\r"); |
||||
if (line > NLINES) { |
||||
// pasar_pagina();
|
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
// RAFA
|
||||
return 0; |
||||
} |
||||
@ -0,0 +1,114 @@
|
||||
/* xsh_memstat.c - xsh_memstat */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
|
||||
// RAFA
|
||||
#include <avr/interrupt.h> |
||||
|
||||
|
||||
static void printMemUse(void); |
||||
static void printFreeList(void); |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xsh_memstat - Print statistics about memory use and dump the free list |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_memstat(int nargs, char *args[]) |
||||
{ |
||||
|
||||
|
||||
// printMemUse();
|
||||
printFreeList(); |
||||
|
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* printFreeList - Walk the list of free memory blocks and print the |
||||
* location and size of each |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
static void printFreeList(void) |
||||
{ |
||||
// char t[80];
|
||||
struct memblk *block; |
||||
|
||||
/* Output a heading for the free list */ |
||||
|
||||
// printf("Free:\n");
|
||||
printf("FreeMEM: addr len\n"); |
||||
|
||||
// avr_printf(m11);
|
||||
for (block = memlist.mnext; block != NULL; block = block->mnext) { |
||||
printf("0x%08x %d\n", block, |
||||
(uint32) block->mlength); |
||||
} |
||||
long i; |
||||
int j=0; |
||||
char * c = 0; |
||||
for (i=0; i<0x5bd ; i++) { |
||||
c = (char *)i; |
||||
if (j==0) { |
||||
serial_put_char('\n'); |
||||
serial_put_char('\r'); |
||||
printf ("0x%08x ", c); |
||||
} |
||||
j++; |
||||
if (j==16) j=0; |
||||
if (*c < 33) |
||||
serial_put_char('-'); |
||||
else |
||||
serial_put_char(*c); |
||||
} |
||||
} |
||||
|
||||
extern void start(void); |
||||
extern void *_end; |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* printMemUse - Print statistics about memory use |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
static void printMemUse(void) |
||||
{ |
||||
int i; /* Index into process table */ |
||||
uint32 code = 0; /* Total Xinu code memory */ |
||||
uint32 stack = 0; /* Total used stack memory */ |
||||
uint32 kheap = 0; /* Free kernel heap memory */ |
||||
uint32 kfree = 0; /* Total free memory */ |
||||
struct memblk *block; /* Ptr to memory block */ |
||||
|
||||
/* Calculate amount of text memory */ |
||||
|
||||
// code = (uint32)&etext - (uint32)&text;
|
||||
|
||||
/* Calculate amount of allocated stack memory */ |
||||
/* Skip the NULL process since it has a private stack */ |
||||
|
||||
for (i = 0; i < NPROC; i++) { |
||||
if (proctab[i].prstate != PR_FREE) { |
||||
stack += (uint32)proctab[i].prstklen; |
||||
} |
||||
} |
||||
|
||||
/* Calculate the amount of memory on the free list */ |
||||
|
||||
for (block = memlist.mnext; block != NULL; block = block->mnext) { |
||||
kfree += block->mlength; |
||||
} |
||||
|
||||
/* Calculate the amount of free kernel heap memory */ |
||||
|
||||
kheap = kfree - stack; |
||||
|
||||
/* Output statistics on current memory use */ |
||||
|
||||
// printf("code: %10d\n", (uint32) code);
|
||||
// printf("stack:%10d bytes\n", (uint32) stack);
|
||||
// printf("kernel stk:%10d bytes\n", (uint32) mspstack);
|
||||
// printf("heap:%10d bytes\n\n", (uint32) kheap);
|
||||
} |
||||
@ -0,0 +1,6 @@
|
||||
|
||||
This app needs the below modificationes into conf/Configuration file: |
||||
|
||||
#define NPROC 3 /* number of user processes */ |
||||
#define NSEM 2 /* number of semaphores */ |
||||
|
||||
@ -0,0 +1,119 @@
|
||||
/* addargs.c - addargs */ |
||||
|
||||
#include <xinu.h> |
||||
#include "shprototypes.h" |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* addargs - Add local copy of argv-style arguments to the stack of |
||||
* a command process that has been created by the shell |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
status addargs( |
||||
pid32 pid, /* ID of process to use */ |
||||
int32 ntok, /* Count of arguments */ |
||||
int32 tok[], /* Index of tokens in tokbuf */ |
||||
int32 tlen, /* Length of data in tokbuf */ |
||||
char *tokbuf, /* Array of null-term. tokens */ |
||||
void *dummy /* Dummy argument that was */ |
||||
/* used at creation and must */ |
||||
/* be replaced by a pointer */ |
||||
/* to an argument vector */ |
||||
) |
||||
{ |
||||
intmask mask; /* Saved interrupt mask */ |
||||
struct procent *prptr; /* Ptr to process' table entry */ |
||||
uint32 aloc; /* Argument location in process */ |
||||
/* stack as an integer */ |
||||
uint32 *argloc; /* Location in process's stack */ |
||||
/* to place args vector */ |
||||
char *argstr; /* Location in process's stack */ |
||||
/* to place arg strings */ |
||||
uint32 *search; /* pointer that searches for */ |
||||
/* dummy argument on stack */ |
||||
uint32 *aptr; /* Walks through args array */ |
||||
int32 i; /* Index into tok array */ |
||||
|
||||
mask = disable(); |
||||
|
||||
/* Check argument count and data length */ |
||||
|
||||
if ( (ntok <= 0) || (tlen < 0) ) { |
||||
// serial_put_char('M');
|
||||
restore(mask); |
||||
return SYSERR; |
||||
} |
||||
|
||||
prptr = &proctab[pid]; |
||||
|
||||
/* Compute lowest location in the process stack where the */ |
||||
/* args array will be stored followed by the argument */ |
||||
/* strings */ |
||||
|
||||
// aloc = (uint32) (prptr->prstkbase
|
||||
// - prptr->prstklen + sizeof(uint32));
|
||||
// argloc = (uint32*) ((aloc + 3) & ~0x3); /* round multiple of 4 */
|
||||
|
||||
/* Compute the first location beyond args array for the strings */ |
||||
//
|
||||
// argstr = (char *) (argloc + (ntok+1)); /* +1 for a null ptr */
|
||||
|
||||
/* Set each location in the args vector to be the address of */ |
||||
/* string area plus the offset of this argument */ |
||||
|
||||
// for (aptr=argloc, i=0; i < ntok; i++) {
|
||||
// *aptr++ = (uint32) (argstr + tok[i]);
|
||||
// }
|
||||
|
||||
/* Add a null pointer to the args array */ |
||||
|
||||
// *aptr++ = (uint32)NULL;
|
||||
|
||||
/* Copy the argument strings from tokbuf into process's stack */ |
||||
/* just beyond the args vector */ |
||||
|
||||
// memcpy(aptr, tokbuf, tlen);
|
||||
|
||||
/* Find the second argument in process's stack */ |
||||
|
||||
// for (search = (uint32 *)prptr->prstkptr;
|
||||
// search < (uint32 *)prptr->prstkbase; search++) {
|
||||
|
||||
/* If found, replace with the address of the args vector*/ |
||||
|
||||
// if (*search == (uint32)dummy) {
|
||||
// *search = (uint32)argloc;
|
||||
// restore(mask);
|
||||
// return OK;
|
||||
// }
|
||||
// }
|
||||
|
||||
/* Argument value not found on the stack - report an error */ |
||||
|
||||
// serial_put_char('\n');
|
||||
|
||||
// for (fromarg=Shl.shtok ; nargs > 0 ; nargs--) {
|
||||
for (i=0 ; i < ntok; i++) { |
||||
// prptr->parg[i+prptr->pargs] = (int)tok[i]; /******** change int parg[] TO void *parg[] in proc.h ******/
|
||||
// prptr->parg[i+prptr->pargs] = (void *)tok[i]; /******** change int parg[] TO void *parg[] in proc.h ******/
|
||||
// serial_put_char(48+i);
|
||||
// serial_put_char(' ');
|
||||
// serial_put_char(tokbuf[tok[i]]);
|
||||
// serial_put_char(' ');
|
||||
prptr->parg[i] = &tokbuf[tok[i]]; |
||||
|
||||
} |
||||
// *toarg = 0;
|
||||
prptr->pargs = ntok; |
||||
prptr->parg[ntok] = 0; |
||||
|
||||
// RAFA prptr->pargs += ntok;
|
||||
// RAFA prptr->parg[prptr->pargs] = 0;
|
||||
/* machine/compiler dependent pass arguments to created process */ |
||||
prptr->pregs[24] = lobyte((unsigned)prptr->pargs); /*r24*/ |
||||
prptr->pregs[25] = hibyte((unsigned)prptr->pargs); |
||||
|
||||
|
||||
restore(mask); |
||||
return OK; |
||||
// return SYSERR;
|
||||
} |
||||
@ -0,0 +1,148 @@
|
||||
/* lexan.c - lexan */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* lexan - Ad hoc lexical analyzer to divide command line into tokens |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
|
||||
int32 lexan ( |
||||
char *line, /* Input line terminated with */ |
||||
/* NEWLINE or NULLCH */ |
||||
int32 len, /* Length of the input line, */ |
||||
/* including NEWLINE */ |
||||
char *tokbuf, /* Buffer into which tokens are */ |
||||
/* stored with a null */ |
||||
/* following each token */ |
||||
int32 *tlen, /* Place to store number of */ |
||||
/* chars in tokbuf */ |
||||
int32 tok[], /* Array of pointers to the */ |
||||
/* start of each token */ |
||||
int32 toktyp[] /* Array that gives the type */ |
||||
/* of each token */ |
||||
) |
||||
{ |
||||
char quote; /* Character for quoted string */ |
||||
uint32 ntok; /* Number of tokens found */ |
||||
char *p; /* Pointer that walks along the */ |
||||
/* input line */ |
||||
int32 tbindex; /* Index into tokbuf */ |
||||
char ch; /* Next char from input line */ |
||||
|
||||
/* Start at the beginning of the line with no tokens */ |
||||
|
||||
ntok = 0; |
||||
p = line; |
||||
tbindex = 0; |
||||
|
||||
/* While not yet at end of line, get next token */ |
||||
|
||||
while ( (*p != NULLCH) && (*p != SH_NEWLINE) ) { |
||||
|
||||
/* If too many tokens, return error */ |
||||
|
||||
if (ntok >= SHELL_MAXTOK) { |
||||
return SYSERR; |
||||
} |
||||
|
||||
/* Skip whitespace before token */ |
||||
|
||||
while ( (*p == SH_BLANK) || (*p == SH_TAB) ) { |
||||
p++; |
||||
} |
||||
|
||||
/* Stop parsing at end of line (or end of string) */ |
||||
|
||||
ch = *p; |
||||
if ( (ch==SH_NEWLINE) || (ch==NULLCH) ) { |
||||
*tlen = tbindex; |
||||
return ntok; |
||||
} |
||||
|
||||
/* Set next entry in tok array to be an index to the */ |
||||
/* current location in the token buffer */ |
||||
|
||||
tok[ntok] = tbindex; /* the start of the token */ |
||||
|
||||
/* Set the token type */ |
||||
|
||||
switch (ch) { |
||||
|
||||
case SH_AMPER: toktyp[ntok] = SH_TOK_AMPER; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
case SH_LESS: toktyp[ntok] = SH_TOK_LESS; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
case SH_GREATER: toktyp[ntok] = SH_TOK_GREATER; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
default: toktyp[ntok] = SH_TOK_OTHER; |
||||
}; |
||||
|
||||
/* Handle quoted string (single or double quote) */ |
||||
|
||||
if ( (ch==SH_SQUOTE) || (ch==SH_DQUOTE) ) { |
||||
quote = ch; /* remember opening quote */ |
||||
|
||||
/* Copy quoted string to arg area */ |
||||
|
||||
p++; /* Move past starting quote */ |
||||
|
||||
while ( ((ch=*p++) != quote) && (ch != SH_NEWLINE) |
||||
&& (ch != NULLCH) ) { |
||||
tokbuf[tbindex++] = ch; |
||||
} |
||||
if (ch != quote) { /* string missing end quote */ |
||||
return SYSERR; |
||||
} |
||||
|
||||
/* Finished string - count token and go on */ |
||||
|
||||
tokbuf[tbindex++] = NULLCH; /* terminate token */ |
||||
ntok++; /* count string as one token */ |
||||
continue; /* go to next token */ |
||||
} |
||||
|
||||
/* Handle a token other than a quoted string */ |
||||
|
||||
tokbuf[tbindex++] = ch; /* put first character in buffer*/ |
||||
p++; |
||||
|
||||
while ( ((ch = *p) != SH_NEWLINE) && (ch != NULLCH) |
||||
&& (ch != SH_LESS) && (ch != SH_GREATER) |
||||
&& (ch != SH_BLANK) && (ch != SH_TAB) |
||||
&& (ch != SH_AMPER) && (ch != SH_SQUOTE) |
||||
&& (ch != SH_DQUOTE) ) { |
||||
tokbuf[tbindex++] = ch; |
||||
p++; |
||||
} |
||||
|
||||
/* Report error if other token is appended */ |
||||
|
||||
if ( (ch == SH_SQUOTE) || (ch == SH_DQUOTE) |
||||
|| (ch == SH_LESS) || (ch == SH_GREATER) ) { |
||||
return SYSERR; |
||||
} |
||||
|
||||
tokbuf[tbindex++] = NULLCH; /* terminate the token */ |
||||
|
||||
ntok++; /* count valid token */ |
||||
|
||||
} |
||||
*tlen = tbindex; |
||||
return ntok; |
||||
} |
||||
@ -0,0 +1,343 @@
|
||||
/* main.c - main */ |
||||
|
||||
/* shell.c - shell */ |
||||
|
||||
|
||||
#include <xinu.h> |
||||
//#include <stdio.h>
|
||||
#include "shprototypes.h" |
||||
|
||||
void xsh_help(void)
|
||||
{ |
||||
int i; |
||||
|
||||
printf("\n\rCommands:\n\n\r"); |
||||
for (i=0; i<ncmd; i++)
|
||||
printf("%s\n", cmdtab[i].cname); |
||||
printf("\n\r"); |
||||
|
||||
} |
||||
|
||||
/************************************************************************/ |
||||
/* Table of Xinu shell commands and the function associated with each */ |
||||
/************************************************************************/ |
||||
const struct cmdent cmdtab[] = { |
||||
{"memstat", FALSE, xsh_memstat}, /* Make built-in */ |
||||
{"editor", FALSE, xsh_editor}, /* Make built-in */ |
||||
{"basic", FALSE, xsh_basic}, /* Make built-in */ |
||||
{"help", TRUE, xsh_help}, /* Make built-in */ |
||||
{"echo", FALSE, xsh_echo} |
||||
// {"argecho", TRUE, xsh_argecho},
|
||||
// {"cat", FALSE, xsh_cat},
|
||||
// {"clear", TRUE, xsh_clear},
|
||||
// {"date", FALSE, xsh_date},
|
||||
// {"devdump", FALSE, xsh_devdump},
|
||||
// {"echo", FALSE, xsh_echo},
|
||||
// {"exit", TRUE, xsh_exit},
|
||||
// {"help", FALSE, xsh_help},
|
||||
// {"kill", TRUE, xsh_kill},
|
||||
// {"memdump", FALSE, xsh_memdump},
|
||||
// {"ps", FALSE, xsh_ps},
|
||||
// {"sleep", FALSE, xsh_sleep},
|
||||
// {"uptime", FALSE, xsh_uptime},
|
||||
// {"?", FALSE, xsh_help}
|
||||
|
||||
}; |
||||
|
||||
uint32 ncmd = sizeof(cmdtab) / sizeof(struct cmdent); |
||||
|
||||
/************************************************************************/ |
||||
/* shell - Provide an interactive user interface that executes */ |
||||
/* commands. Each command begins with a command name, has */ |
||||
/* a set of optional arguments, has optional input or */ |
||||
/* output redirection, and an optional specification for */ |
||||
/* background execution (ampersand). The syntax is: */ |
||||
/* */ |
||||
/* command_name [args*] [redirection] [&] */ |
||||
/* */ |
||||
/* Redirection is either or both of: */ |
||||
/* */ |
||||
/* < input_file */ |
||||
/* or */ |
||||
/* > output_file */ |
||||
/* */ |
||||
/************************************************************************/ |
||||
|
||||
process main(void) |
||||
{ |
||||
char buf[SHELL_BUFLEN]; /* Input line (large enough for */ |
||||
int32 len; /* Length of line read */ |
||||
char tokbuf[SHELL_BUFLEN + /* Buffer to hold a set of */ |
||||
SHELL_MAXTOK]; /* Contiguous null-terminated */ |
||||
int32 tlen; /* Current length of all data */ |
||||
/* in array tokbuf */ |
||||
int32 tok[SHELL_MAXTOK]; /* Index of each token in */ |
||||
int32 toktyp[SHELL_MAXTOK]; /* Type of each token in tokbuf */ |
||||
int32 ntok; /* Number of tokens on line */ |
||||
pid32 child; /* Process ID of spawned child */ |
||||
bool8 backgnd; /* Run command in background? */ |
||||
char *outname, *inname; /* Pointers to strings for file */ |
||||
/* names that follow > and < */ |
||||
did32 stdinput, stdoutput; /* Descriptors for redirected */ |
||||
/* input and output */ |
||||
int32 i; /* Index into array of tokens */ |
||||
int32 j; /* Index into array of commands */ |
||||
int32 msg; /* Message from receive() for */ |
||||
/* child termination */ |
||||
int32 tmparg; /* Address of this var is used */ |
||||
/* when first creating child */ |
||||
/* process, but is replaced */ |
||||
char *src, *cmp; /* Pointers used during name */ |
||||
/* comparison */ |
||||
bool8 diff; /* Was difference found during */ |
||||
char *args[SHELL_MAXTOK]; /* Argument vector passed to */ |
||||
/* builtin commands */ |
||||
did32 dev = 0; /* ID of tty device from which */ |
||||
|
||||
/* Print shell banner and startup message */ |
||||
|
||||
/*
|
||||
fprintf(dev, "\n\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", |
||||
SHELL_BAN0,SHELL_BAN1,SHELL_BAN2,SHELL_BAN3,SHELL_BAN4, |
||||
SHELL_BAN5,SHELL_BAN6,SHELL_BAN7,SHELL_BAN8,SHELL_BAN9,SHELL_BAN10); |
||||
|
||||
fprintf(dev, "%s\n\n", SHELL_STRTMSG); |
||||
*/ |
||||
|
||||
/* Continually prompt the user, read input, and execute command */ |
||||
|
||||
|
||||
while (TRUE) { |
||||
|
||||
// RAFA
|
||||
// fprintf(dev, "\033[2J");
|
||||
// fprintf(dev, "\033[H");
|
||||
|
||||
/* Display prompt */ |
||||
fprintf(dev, SHELL_PROMPT); |
||||
|
||||
|
||||
len = read(dev, buf, sizeof(buf)); |
||||
|
||||
/* Exit gracefully on end-of-file */ |
||||
|
||||
if (len == EOF) { |
||||
break; |
||||
} |
||||
|
||||
/* If line contains only NEWLINE, go to next line */ |
||||
|
||||
if (len <= 1) { |
||||
continue; |
||||
} |
||||
|
||||
buf[len] = SH_NEWLINE; /* terminate line */ |
||||
|
||||
/* Parse input line and divide into tokens */ |
||||
|
||||
ntok = lexan(buf, len, tokbuf, &tlen, tok, toktyp); |
||||
|
||||
/* Handle parsing error */ |
||||
|
||||
if (ntok == SYSERR) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
|
||||
/* If line is empty, go to next input line */ |
||||
|
||||
if (ntok == 0) { |
||||
// fprintf(dev, "\n");
|
||||
continue; |
||||
} |
||||
|
||||
/* If last token is '&', set background */ |
||||
|
||||
if (toktyp[ntok-1] == SH_TOK_AMPER) { |
||||
ntok-- ; |
||||
tlen-= 2; |
||||
backgnd = TRUE; |
||||
} else { |
||||
backgnd = FALSE; |
||||
} |
||||
|
||||
|
||||
/* Check for input/output redirection (default is none) */ |
||||
|
||||
outname = inname = NULL; |
||||
if ( (ntok >=3) && ( (toktyp[ntok-2] == SH_TOK_LESS) |
||||
||(toktyp[ntok-2] == SH_TOK_GREATER))){ |
||||
if (toktyp[ntok-1] != SH_TOK_OTHER) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
if (toktyp[ntok-2] == SH_TOK_LESS) { |
||||
inname = &tokbuf[tok[ntok-1]]; |
||||
} else { |
||||
outname = &tokbuf[tok[ntok-1]]; |
||||
} |
||||
ntok -= 2; |
||||
tlen = tok[ntok]; |
||||
} |
||||
|
||||
|
||||
if ( (ntok >=3) && ( (toktyp[ntok-2] == SH_TOK_LESS) |
||||
||(toktyp[ntok-2] == SH_TOK_GREATER))){ |
||||
if (toktyp[ntok-1] != SH_TOK_OTHER) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
if (toktyp[ntok-2] == SH_TOK_LESS) { |
||||
if (inname != NULL) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
inname = &tokbuf[tok[ntok-1]]; |
||||
} else { |
||||
if (outname != NULL) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
outname = &tokbuf[tok[ntok-1]]; |
||||
} |
||||
ntok -= 2; |
||||
tlen = tok[ntok]; |
||||
} |
||||
|
||||
/* Verify remaining tokens are type "other" */ |
||||
|
||||
for (i=0; i<ntok; i++) { |
||||
if (toktyp[i] != SH_TOK_OTHER) { |
||||
break; |
||||
} |
||||
} |
||||
if ((ntok == 0) || (i < ntok)) { |
||||
// fprintf(dev, SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
|
||||
stdinput = stdoutput = dev; |
||||
|
||||
/* Lookup first token in the command table */ |
||||
|
||||
for (j = 0; j < ncmd; j++) { |
||||
src = cmdtab[j].cname; |
||||
cmp = tokbuf; |
||||
diff = FALSE; |
||||
while (*src != NULLCH) { |
||||
if (*cmp != *src) { |
||||
diff = TRUE; |
||||
break; |
||||
} |
||||
src++; |
||||
cmp++; |
||||
} |
||||
if (diff || (*cmp != NULLCH)) { |
||||
continue; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/* Handle command not found */ |
||||
|
||||
if (j >= ncmd) { |
||||
// fprintf(dev, "command %s not found\n", tokbuf);
|
||||
continue; |
||||
} |
||||
|
||||
/* Handle built-in command */ |
||||
|
||||
if (cmdtab[j].cbuiltin) { /* No background or redirect. */ |
||||
if (inname != NULL || outname != NULL || backgnd){ |
||||
// fprintf(dev, SHELL_BGERRMSG);
|
||||
continue; |
||||
} else { |
||||
/* Set up arg vector for call */ |
||||
|
||||
for (i=0; i<ntok; i++) { |
||||
args[i] = &tokbuf[tok[i]]; |
||||
} |
||||
|
||||
/* Call builtin shell function */ |
||||
|
||||
if ((*cmdtab[j].cfunc)(ntok, args) |
||||
== SHELL_EXIT) { |
||||
break; |
||||
} |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
/* Open files and redirect I/O if specified */ |
||||
|
||||
if (inname != NULL) { |
||||
stdinput = open(NAMESPACE,inname,"ro"); |
||||
if (stdinput == SYSERR) { |
||||
// fprintf(dev, SHELL_INERRMSG, inname);
|
||||
continue; |
||||
} |
||||
} |
||||
if (outname != NULL) { |
||||
stdoutput = open(NAMESPACE,outname,"w"); |
||||
if (stdoutput == SYSERR) { |
||||
// fprintf(dev, SHELL_OUTERRMSG, outname);
|
||||
continue; |
||||
} else { |
||||
control(stdoutput, F_CTL_TRUNC, 0, 0); |
||||
} |
||||
} |
||||
|
||||
// int eeprom_fd = open(RAM0, nombre, "w");
|
||||
// char raf[32] = "pepe";
|
||||
// write(fd, pepe, 32);
|
||||
// int eeprom_fd = open(RAM0, nombre, "w");
|
||||
|
||||
/* Spawn child thread for non-built-in commands */ |
||||
|
||||
// RAFA child = create(cmdtab[j].cfunc,
|
||||
// RAFA SHELL_CMDSTK, SHELL_CMDPRIO,
|
||||
// RAFA cmdtab[j].cname, 2, ntok, &tmparg);
|
||||
/* 160 bytes de stack perfecto */ |
||||
child = create(cmdtab[j].cfunc, |
||||
460, SHELL_CMDPRIO, |
||||
cmdtab[j].cname, 2, ntok, &tmparg); |
||||
|
||||
/* If creation or argument copy fails, report error */ |
||||
|
||||
// serial_put_char('X');
|
||||
// if (child == SYSERR)
|
||||
// serial_put_char('Y');
|
||||
if ((child == SYSERR) || |
||||
(addargs(child, ntok, tok, tlen, tokbuf, &tmparg) |
||||
== SYSERR) ) { |
||||
// serial_put_char('Z');
|
||||
fprintf(dev, SHELL_CREATMSG); |
||||
continue; |
||||
} |
||||
|
||||
/* Set stdinput and stdoutput in child to redirect I/O */ |
||||
|
||||
proctab[child].prdesc[0] = stdinput; |
||||
proctab[child].prdesc[1] = stdoutput; |
||||
|
||||
msg = recvclr(); |
||||
resume(child); |
||||
|
||||
// RAFA AGREGA
|
||||
resched(); |
||||
// serial_put_char('X');
|
||||
|
||||
if (! backgnd) { |
||||
msg = receive(); |
||||
while (msg != child) { |
||||
msg = receive(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Terminate the shell process by returning from the top level */ |
||||
|
||||
// fprintf(dev,SHELL_EXITMSG);
|
||||
return OK; |
||||
} |
||||
@ -0,0 +1,24 @@
|
||||
/* xsh_echo.c - xsh_echo */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xhs_echo - write argument strings to stdout |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_echo(int nargs, char *args[]) |
||||
{ |
||||
int32 i; /* walks through args array */ |
||||
|
||||
if (nargs > 1) { |
||||
printf("%s", args[1]); |
||||
|
||||
for (i = 2; i < nargs; i++) { |
||||
printf(" %s", args[i]); |
||||
} |
||||
} |
||||
printf("\n"); |
||||
|
||||
return 0; |
||||
} |
||||
@ -0,0 +1,101 @@
|
||||
/* xsh_editor.c - xsh_editor */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
|
||||
// #include "text_buffer.h"
|
||||
#define NLINES 3 |
||||
#define LINE_LEN 24 |
||||
|
||||
//extern unsigned char program[NLINES*LINE_LEN];
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xhs_editor - text editor
|
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_editor(int nargs, char *args[]) |
||||
{ |
||||
|
||||
/*
|
||||
int32 i; |
||||
|
||||
if (nargs > 1) { |
||||
printf("%s", args[1]); |
||||
|
||||
for (i = 2; i < nargs; i++) { |
||||
printf(" %s", args[i]); |
||||
} |
||||
} |
||||
printf("\n"); |
||||
*/ |
||||
char buffer[NLINES*LINE_LEN]; |
||||
int page = 0; |
||||
int i = 0; |
||||
int j = 0; |
||||
int dev = 0; |
||||
int c; |
||||
int cursor = 0; |
||||
int line = 0; |
||||
|
||||
fprintf(dev, "\033[2J"); |
||||
fprintf(dev, "\033[H"); |
||||
fprintf(dev, "Text editor. page: %i\n", page); |
||||
|
||||
for (i=0; i<NLINES*LINE_LEN; i++) |
||||
buffer[i] = 0; |
||||
|
||||
// control(dev, TC_NOECHO, 0, 0);
|
||||
|
||||
control(dev, TC_MODER, 0, 0); |
||||
|
||||
while (TRUE) { |
||||
// c = -1;
|
||||
c = getc(0); |
||||
//printf("%i \n", c);
|
||||
if (c == '!') { |
||||
control(dev, TC_MODEC, 0, 0); |
||||
return 0; |
||||
}; |
||||
if (c == 27) { |
||||
c = getc(0); |
||||
if (c == '[') { |
||||
c = getc(0); |
||||
switch (c) { |
||||
case 'D':
|
||||
cursor--; if (cursor < 0) cursor = 0; |
||||
printf("\033[D"); |
||||
break; |
||||
case 'C':
|
||||
cursor++;
|
||||
printf("\033[C"); |
||||
if (cursor > LINE_LEN) { |
||||
cursor = 0; |
||||
line++; |
||||
printf("\n\r"); |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
printf("%c", c); |
||||
buffer[line*LINE_LEN+cursor] = c; |
||||
cursor++; |
||||
if (cursor > LINE_LEN) { |
||||
cursor = 0; |
||||
line++; |
||||
printf("\n\r"); |
||||
if (line > NLINES) { |
||||
// pasar_pagina();
|
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
// RAFA
|
||||
return 0; |
||||
} |
||||
@ -0,0 +1,114 @@
|
||||
/* xsh_memstat.c - xsh_memstat */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
|
||||
// RAFA
|
||||
#include <avr/interrupt.h> |
||||
|
||||
|
||||
static void printMemUse(void); |
||||
static void printFreeList(void); |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xsh_memstat - Print statistics about memory use and dump the free list |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_memstat(int nargs, char *args[]) |
||||
{ |
||||
|
||||
|
||||
// printMemUse();
|
||||
printFreeList(); |
||||
|
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* printFreeList - Walk the list of free memory blocks and print the |
||||
* location and size of each |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
static void printFreeList(void) |
||||
{ |
||||
// char t[80];
|
||||
struct memblk *block; |
||||
|
||||
/* Output a heading for the free list */ |
||||
|
||||
// printf("Free:\n");
|
||||
printf("FreeMEM: addr len\n"); |
||||
|
||||
// avr_printf(m11);
|
||||
for (block = memlist.mnext; block != NULL; block = block->mnext) { |
||||
printf("0x%08x %d\n", block, |
||||
(uint32) block->mlength); |
||||
} |
||||
long i; |
||||
int j=0; |
||||
char * c = 0; |
||||
for (i=0; i<0x5bd ; i++) { |
||||
c = (char *)i; |
||||
if (j==0) { |
||||
serial_put_char('\n'); |
||||
serial_put_char('\r'); |
||||
printf ("0x%08x ", c); |
||||
} |
||||
j++; |
||||
if (j==16) j=0; |
||||
if (*c < 33) |
||||
serial_put_char('-'); |
||||
else |
||||
serial_put_char(*c); |
||||
} |
||||
} |
||||
|
||||
extern void start(void); |
||||
extern void *_end; |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* printMemUse - Print statistics about memory use |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
static void printMemUse(void) |
||||
{ |
||||
int i; /* Index into process table */ |
||||
uint32 code = 0; /* Total Xinu code memory */ |
||||
uint32 stack = 0; /* Total used stack memory */ |
||||
uint32 kheap = 0; /* Free kernel heap memory */ |
||||
uint32 kfree = 0; /* Total free memory */ |
||||
struct memblk *block; /* Ptr to memory block */ |
||||
|
||||
/* Calculate amount of text memory */ |
||||
|
||||
// code = (uint32)&etext - (uint32)&text;
|
||||
|
||||
/* Calculate amount of allocated stack memory */ |
||||
/* Skip the NULL process since it has a private stack */ |
||||
|
||||
for (i = 0; i < NPROC; i++) { |
||||
if (proctab[i].prstate != PR_FREE) { |
||||
stack += (uint32)proctab[i].prstklen; |
||||
} |
||||
} |
||||
|
||||
/* Calculate the amount of memory on the free list */ |
||||
|
||||
for (block = memlist.mnext; block != NULL; block = block->mnext) { |
||||
kfree += block->mlength; |
||||
} |
||||
|
||||
/* Calculate the amount of free kernel heap memory */ |
||||
|
||||
kheap = kfree - stack; |
||||
|
||||
/* Output statistics on current memory use */ |
||||
|
||||
// printf("code: %10d\n", (uint32) code);
|
||||
// printf("stack:%10d bytes\n", (uint32) stack);
|
||||
// printf("kernel stk:%10d bytes\n", (uint32) mspstack);
|
||||
// printf("heap:%10d bytes\n\n", (uint32) kheap);
|
||||
} |
||||
@ -0,0 +1,6 @@
|
||||
|
||||
This app needs the below modificationes into conf/Configuration file: |
||||
|
||||
#define NPROC 3 /* number of user processes */ |
||||
#define NSEM 2 /* number of semaphores */ |
||||
|
||||
@ -0,0 +1,119 @@
|
||||
/* addargs.c - addargs */ |
||||
|
||||
#include <xinu.h> |
||||
#include "shprototypes.h" |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* addargs - Add local copy of argv-style arguments to the stack of |
||||
* a command process that has been created by the shell |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
status addargs( |
||||
pid32 pid, /* ID of process to use */ |
||||
int32 ntok, /* Count of arguments */ |
||||
int32 tok[], /* Index of tokens in tokbuf */ |
||||
int32 tlen, /* Length of data in tokbuf */ |
||||
char *tokbuf, /* Array of null-term. tokens */ |
||||
void *dummy /* Dummy argument that was */ |
||||
/* used at creation and must */ |
||||
/* be replaced by a pointer */ |
||||
/* to an argument vector */ |
||||
) |
||||
{ |
||||
intmask mask; /* Saved interrupt mask */ |
||||
struct procent *prptr; /* Ptr to process' table entry */ |
||||
uint32 aloc; /* Argument location in process */ |
||||
/* stack as an integer */ |
||||
uint32 *argloc; /* Location in process's stack */ |
||||
/* to place args vector */ |
||||
char *argstr; /* Location in process's stack */ |
||||
/* to place arg strings */ |
||||
uint32 *search; /* pointer that searches for */ |
||||
/* dummy argument on stack */ |
||||
uint32 *aptr; /* Walks through args array */ |
||||
int32 i; /* Index into tok array */ |
||||
|
||||
mask = disable(); |
||||
|
||||
/* Check argument count and data length */ |
||||
|
||||
if ( (ntok <= 0) || (tlen < 0) ) { |
||||
// serial_put_char('M');
|
||||
restore(mask); |
||||
return SYSERR; |
||||
} |
||||
|
||||
prptr = &proctab[pid]; |
||||
|
||||
/* Compute lowest location in the process stack where the */ |
||||
/* args array will be stored followed by the argument */ |
||||
/* strings */ |
||||
|
||||
// aloc = (uint32) (prptr->prstkbase
|
||||
// - prptr->prstklen + sizeof(uint32));
|
||||
// argloc = (uint32*) ((aloc + 3) & ~0x3); /* round multiple of 4 */
|
||||
|
||||
/* Compute the first location beyond args array for the strings */ |
||||
//
|
||||
// argstr = (char *) (argloc + (ntok+1)); /* +1 for a null ptr */
|
||||
|
||||
/* Set each location in the args vector to be the address of */ |
||||
/* string area plus the offset of this argument */ |
||||
|
||||
// for (aptr=argloc, i=0; i < ntok; i++) {
|
||||
// *aptr++ = (uint32) (argstr + tok[i]);
|
||||
// }
|
||||
|
||||
/* Add a null pointer to the args array */ |
||||
|
||||
// *aptr++ = (uint32)NULL;
|
||||
|
||||
/* Copy the argument strings from tokbuf into process's stack */ |
||||
/* just beyond the args vector */ |
||||
|
||||
// memcpy(aptr, tokbuf, tlen);
|
||||
|
||||
/* Find the second argument in process's stack */ |
||||
|
||||
// for (search = (uint32 *)prptr->prstkptr;
|
||||
// search < (uint32 *)prptr->prstkbase; search++) {
|
||||
|
||||
/* If found, replace with the address of the args vector*/ |
||||
|
||||
// if (*search == (uint32)dummy) {
|
||||
// *search = (uint32)argloc;
|
||||
// restore(mask);
|
||||
// return OK;
|
||||
// }
|
||||
// }
|
||||
|
||||
/* Argument value not found on the stack - report an error */ |
||||
|
||||
// serial_put_char('\n');
|
||||
|
||||
// for (fromarg=Shl.shtok ; nargs > 0 ; nargs--) {
|
||||
for (i=0 ; i < ntok; i++) { |
||||
// prptr->parg[i+prptr->pargs] = (int)tok[i]; /******** change int parg[] TO void *parg[] in proc.h ******/
|
||||
// prptr->parg[i+prptr->pargs] = (void *)tok[i]; /******** change int parg[] TO void *parg[] in proc.h ******/
|
||||
// serial_put_char(48+i);
|
||||
// serial_put_char(' ');
|
||||
// serial_put_char(tokbuf[tok[i]]);
|
||||
// serial_put_char(' ');
|
||||
prptr->parg[i] = &tokbuf[tok[i]]; |
||||
|
||||
} |
||||
// *toarg = 0;
|
||||
prptr->pargs = ntok; |
||||
prptr->parg[ntok] = 0; |
||||
|
||||
// RAFA prptr->pargs += ntok;
|
||||
// RAFA prptr->parg[prptr->pargs] = 0;
|
||||
/* machine/compiler dependent pass arguments to created process */ |
||||
prptr->pregs[24] = lobyte((unsigned)prptr->pargs); /*r24*/ |
||||
prptr->pregs[25] = hibyte((unsigned)prptr->pargs); |
||||
|
||||
|
||||
restore(mask); |
||||
return OK; |
||||
// return SYSERR;
|
||||
} |
||||
@ -0,0 +1,148 @@
|
||||
/* lexan.c - lexan */ |
||||
|
||||
#include <xinu.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* lexan - Ad hoc lexical analyzer to divide command line into tokens |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
|
||||
int32 lexan ( |
||||
char *line, /* Input line terminated with */ |
||||
/* NEWLINE or NULLCH */ |
||||
int32 len, /* Length of the input line, */ |
||||
/* including NEWLINE */ |
||||
char *tokbuf, /* Buffer into which tokens are */ |
||||
/* stored with a null */ |
||||
/* following each token */ |
||||
int32 *tlen, /* Place to store number of */ |
||||
/* chars in tokbuf */ |
||||
int32 tok[], /* Array of pointers to the */ |
||||
/* start of each token */ |
||||
int32 toktyp[] /* Array that gives the type */ |
||||
/* of each token */ |
||||
) |
||||
{ |
||||
char quote; /* Character for quoted string */ |
||||
uint32 ntok; /* Number of tokens found */ |
||||
char *p; /* Pointer that walks along the */ |
||||
/* input line */ |
||||
int32 tbindex; /* Index into tokbuf */ |
||||
char ch; /* Next char from input line */ |
||||
|
||||
/* Start at the beginning of the line with no tokens */ |
||||
|
||||
ntok = 0; |
||||
p = line; |
||||
tbindex = 0; |
||||
|
||||
/* While not yet at end of line, get next token */ |
||||
|
||||
while ( (*p != NULLCH) && (*p != SH_NEWLINE) ) { |
||||
|
||||
/* If too many tokens, return error */ |
||||
|
||||
if (ntok >= SHELL_MAXTOK) { |
||||
return SYSERR; |
||||
} |
||||
|
||||
/* Skip whitespace before token */ |
||||
|
||||
while ( (*p == SH_BLANK) || (*p == SH_TAB) ) { |
||||
p++; |
||||
} |
||||
|
||||
/* Stop parsing at end of line (or end of string) */ |
||||
|
||||
ch = *p; |
||||
if ( (ch==SH_NEWLINE) || (ch==NULLCH) ) { |
||||
*tlen = tbindex; |
||||
return ntok; |
||||
} |
||||
|
||||
/* Set next entry in tok array to be an index to the */ |
||||
/* current location in the token buffer */ |
||||
|
||||
tok[ntok] = tbindex; /* the start of the token */ |
||||
|
||||
/* Set the token type */ |
||||
|
||||
switch (ch) { |
||||
|
||||
case SH_AMPER: toktyp[ntok] = SH_TOK_AMPER; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
case SH_LESS: toktyp[ntok] = SH_TOK_LESS; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
case SH_GREATER: toktyp[ntok] = SH_TOK_GREATER; |
||||
tokbuf[tbindex++] = ch; |
||||
tokbuf[tbindex++] = NULLCH; |
||||
ntok++; |
||||
p++; |
||||
continue; |
||||
|
||||
default: toktyp[ntok] = SH_TOK_OTHER; |
||||
}; |
||||
|
||||
/* Handle quoted string (single or double quote) */ |
||||
|
||||
if ( (ch==SH_SQUOTE) || (ch==SH_DQUOTE) ) { |
||||
quote = ch; /* remember opening quote */ |
||||
|
||||
/* Copy quoted string to arg area */ |
||||
|
||||
p++; /* Move past starting quote */ |
||||
|
||||
while ( ((ch=*p++) != quote) && (ch != SH_NEWLINE) |
||||
&& (ch != NULLCH) ) { |
||||
tokbuf[tbindex++] = ch; |
||||
} |
||||
if (ch != quote) { /* string missing end quote */ |
||||
return SYSERR; |
||||
} |
||||
|
||||
/* Finished string - count token and go on */ |
||||
|
||||
tokbuf[tbindex++] = NULLCH; /* terminate token */ |
||||
ntok++; /* count string as one token */ |
||||
continue; /* go to next token */ |
||||
} |
||||
|
||||
/* Handle a token other than a quoted string */ |
||||
|
||||
tokbuf[tbindex++] = ch; /* put first character in buffer*/ |
||||
p++; |
||||
|
||||
while ( ((ch = *p) != SH_NEWLINE) && (ch != NULLCH) |
||||
&& (ch != SH_LESS) && (ch != SH_GREATER) |
||||
&& (ch != SH_BLANK) && (ch != SH_TAB) |
||||
&& (ch != SH_AMPER) && (ch != SH_SQUOTE) |
||||
&& (ch != SH_DQUOTE) ) { |
||||
tokbuf[tbindex++] = ch; |
||||
p++; |
||||
} |
||||
|
||||
/* Report error if other token is appended */ |
||||
|
||||
if ( (ch == SH_SQUOTE) || (ch == SH_DQUOTE) |
||||
|| (ch == SH_LESS) || (ch == SH_GREATER) ) { |
||||
return SYSERR; |
||||
} |
||||
|
||||
tokbuf[tbindex++] = NULLCH; /* terminate the token */ |
||||
|
||||
ntok++; /* count valid token */ |
||||
|
||||
} |
||||
*tlen = tbindex; |
||||
return ntok; |
||||
} |
||||
@ -0,0 +1,24 @@
|
||||
/* xsh_echo.c - xsh_echo */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xhs_echo - write argument strings to stdout |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_echo(int nargs, char *args[]) |
||||
{ |
||||
int32 i; /* walks through args array */ |
||||
|
||||
if (nargs > 1) { |
||||
printf("%s", args[1]); |
||||
|
||||
for (i = 2; i < nargs; i++) { |
||||
printf(" %s", args[i]); |
||||
} |
||||
} |
||||
printf("\n"); |
||||
|
||||
return 0; |
||||
} |
||||
@ -0,0 +1,94 @@
|
||||
/* xsh_editor.c - xsh_editor */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
|
||||
#define NLINES 10 |
||||
#define LINE_LEN 24 |
||||
/*------------------------------------------------------------------------
|
||||
* xhs_editor - text editor
|
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_editor(int nargs, char *args[]) |
||||
{ |
||||
|
||||
/*
|
||||
int32 i; |
||||
|
||||
if (nargs > 1) { |
||||
printf("%s", args[1]); |
||||
|
||||
for (i = 2; i < nargs; i++) { |
||||
printf(" %s", args[i]); |
||||
} |
||||
} |
||||
printf("\n"); |
||||
*/ |
||||
char buffer[NLINES][LINE_LEN+1]; |
||||
int page = 0; |
||||
int i = 0; |
||||
int dev = 0; |
||||
int c; |
||||
int cursor = 0; |
||||
int line = 0; |
||||
|
||||
fprintf(dev, "\033[2J"); |
||||
fprintf(dev, "\033[H"); |
||||
fprintf(dev, "Text editor. page: %i\n", page); |
||||
|
||||
memset(buffer, NLINES*(LINE_LEN+1), 0); |
||||
for (i=0; i<LINE_LEN; i++) |
||||
printf("%s\n",buffer[i]); |
||||
|
||||
// control(dev, TC_NOECHO, 0, 0);
|
||||
|
||||
control(dev, TC_MODER, 0, 0); |
||||
|
||||
while (TRUE) { |
||||
// c = -1;
|
||||
c = getc(0); |
||||
//printf("%i \n", c);
|
||||
|
||||
if (c == 27) { |
||||
c = getc(0); |
||||
if (c == '[') { |
||||
c = getc(0); |
||||
switch (c) { |
||||
case 'D':
|
||||
cursor--; if (cursor < 0) cursor = 0; |
||||
printf("\033[D"); |
||||
break; |
||||
case 'C':
|
||||
cursor++;
|
||||
printf("\033[C"); |
||||
if (cursor > LINE_LEN) { |
||||
cursor = 0; |
||||
line++; |
||||
printf("\n\r"); |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
} |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
printf("%c", c); |
||||
buffer[line][cursor] = c; |
||||
cursor++; |
||||
if (cursor > LINE_LEN) { |
||||
cursor = 0; |
||||
line++; |
||||
printf("\n\r"); |
||||
if (line > NLINES) { |
||||
// pasar_pagina();
|
||||
} |
||||
} |
||||
|
||||
} |
||||
|
||||
|
||||
// RAFA
|
||||
return 0; |
||||
} |
||||
@ -0,0 +1,116 @@
|
||||
/* xsh_memstat.c - xsh_memstat */ |
||||
|
||||
#include <xinu.h> |
||||
#include <stdio.h> |
||||
#include <string.h> |
||||
|
||||
static void printMemUse(void); |
||||
static void printFreeList(void); |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* xsh_memstat - Print statistics about memory use and dump the free list |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
shellcmd xsh_memstat(int nargs, char *args[]) |
||||
{ |
||||
|
||||
/* For argument '--help', emit help about the 'memstat' command */ |
||||
|
||||
/*
|
||||
if (nargs == 2 && strncmp(args[1], "--help", 7) == 0) { |
||||
printf("use: %s \n\n", args[0]); |
||||
printf("Description:\n"); |
||||
printf("\tDisplays the current memory use and prints the\n"); |
||||
printf("\tfree list.\n"); |
||||
printf("Options:\n"); |
||||
printf("\t--help\t\tdisplay this help and exit\n"); |
||||
return 0; |
||||
} |
||||
*/ |
||||
|
||||
/* Check for valid number of arguments */ |
||||
|
||||
/*
|
||||
if (nargs > 1) { |
||||
fprintf(stderr, "%s: too many arguments\n", args[0]); |
||||
fprintf(stderr, "Try '%s --help' for more information\n", |
||||
args[0]); |
||||
return 1; |
||||
} |
||||
*/ |
||||
|
||||
printMemUse(); |
||||
printFreeList(); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* printFreeList - Walk the list of free memory blocks and print the |
||||
* location and size of each |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
static void printFreeList(void) |
||||
{ |
||||
char t[80]; |
||||
struct memblk *block; |
||||
|
||||
/* Output a heading for the free list */ |
||||
|
||||
// printf("Free:\n");
|
||||
printf("FreeMEM: addr len\n"); |
||||
|
||||
// avr_printf(m11);
|
||||
for (block = memlist.mnext; block != NULL; block = block->mnext) { |
||||
printf("0x%08x %d\n", block, |
||||
(uint32) block->mlength); |
||||
} |
||||
} |
||||
|
||||
extern void start(void); |
||||
extern void *_end; |
||||
|
||||
/*------------------------------------------------------------------------
|
||||
* printMemUse - Print statistics about memory use |
||||
*------------------------------------------------------------------------ |
||||
*/ |
||||
static void printMemUse(void) |
||||
{ |
||||
int i; /* Index into process table */ |
||||
uint32 code = 0; /* Total Xinu code memory */ |
||||
uint32 stack = 0; /* Total used stack memory */ |
||||
uint32 kheap = 0; /* Free kernel heap memory */ |
||||
uint32 kfree = 0; /* Total free memory */ |
||||
struct memblk *block; /* Ptr to memory block */ |
||||
|
||||
/* Calculate amount of text memory */ |
||||
|
||||
// code = (uint32)&etext - (uint32)&text;
|
||||
|
||||
/* Calculate amount of allocated stack memory */ |
||||
/* Skip the NULL process since it has a private stack */ |
||||
|
||||
for (i = 0; i < NPROC; i++) { |
||||
if (proctab[i].prstate != PR_FREE) { |
||||
stack += (uint32)proctab[i].prstklen; |
||||
} |
||||
} |
||||
|
||||
/* Calculate the amount of memory on the free list */ |
||||
|
||||
for (block = memlist.mnext; block != NULL; block = block->mnext) { |
||||
kfree += block->mlength; |
||||
} |
||||
|
||||
/* Calculate the amount of free kernel heap memory */ |
||||
|
||||
kheap = kfree - stack; |
||||
|
||||
/* Output statistics on current memory use */ |
||||
|
||||
// printf("code: %10d\n", (uint32) code);
|
||||
// printf("stack:%10d bytes\n", (uint32) stack);
|
||||
// printf("kernel stk:%10d bytes\n", (uint32) mspstack);
|
||||
// printf("heap:%10d bytes\n\n", (uint32) kheap);
|
||||
} |
||||
@ -0,0 +1,343 @@
|
||||
/* main.c - main */ |
||||
|
||||
/* shell.c - shell */ |
||||
|
||||
|
||||
#include <xinu.h> |
||||
//#include <stdio.h>
|
||||
#include "shprototypes.h" |
||||
|
||||
void xsh_help(void)
|
||||
{ |
||||
int i; |
||||
|
||||
printf("\n\rCommands:\n\n\r"); |
||||
for (i=0; i<ncmd; i++)
|
||||
printf("%s\n", cmdtab[i].cname); |
||||
printf("\n\r"); |
||||
|
||||
} |
||||
|
||||
/************************************************************************/ |
||||
/* Table of Xinu shell commands and the function associated with each */ |
||||
/************************************************************************/ |
||||
const struct cmdent cmdtab[] = { |
||||
{"memstat", FALSE, xsh_memstat}, /* Make built-in */ |
||||
{"editor", FALSE, xsh_editor}, /* Make built-in */ |
||||
{"basic", FALSE, xsh_basic}, /* Make built-in */ |
||||
{"help", TRUE, xsh_help}, /* Make built-in */ |
||||
{"echo", FALSE, xsh_echo} |
||||
// {"argecho", TRUE, xsh_argecho},
|
||||
// {"cat", FALSE, xsh_cat},
|
||||
// {"clear", TRUE, xsh_clear},
|
||||
// {"date", FALSE, xsh_date},
|
||||
// {"devdump", FALSE, xsh_devdump},
|
||||
// {"echo", FALSE, xsh_echo},
|
||||
// {"exit", TRUE, xsh_exit},
|
||||
// {"help", FALSE, xsh_help},
|
||||
// {"kill", TRUE, xsh_kill},
|
||||
// {"memdump", FALSE, xsh_memdump},
|
||||
// {"ps", FALSE, xsh_ps},
|
||||
// {"sleep", FALSE, xsh_sleep},
|
||||
// {"uptime", FALSE, xsh_uptime},
|
||||
// {"?", FALSE, xsh_help}
|
||||
|
||||
}; |
||||
|
||||
uint32 ncmd = sizeof(cmdtab) / sizeof(struct cmdent); |
||||
|
||||
/************************************************************************/ |
||||
/* shell - Provide an interactive user interface that executes */ |
||||
/* commands. Each command begins with a command name, has */ |
||||
/* a set of optional arguments, has optional input or */ |
||||
/* output redirection, and an optional specification for */ |
||||
/* background execution (ampersand). The syntax is: */ |
||||
/* */ |
||||
/* command_name [args*] [redirection] [&] */ |
||||
/* */ |
||||
/* Redirection is either or both of: */ |
||||
/* */ |
||||
/* < input_file */ |
||||
/* or */ |
||||
/* > output_file */ |
||||
/* */ |
||||
/************************************************************************/ |
||||
|
||||
process main(void) |
||||
{ |
||||
char buf[SHELL_BUFLEN]; /* Input line (large enough for */ |
||||
int32 len; /* Length of line read */ |
||||
char tokbuf[SHELL_BUFLEN + /* Buffer to hold a set of */ |
||||
SHELL_MAXTOK]; /* Contiguous null-terminated */ |
||||
int32 tlen; /* Current length of all data */ |
||||
/* in array tokbuf */ |
||||
int32 tok[SHELL_MAXTOK]; /* Index of each token in */ |
||||
int32 toktyp[SHELL_MAXTOK]; /* Type of each token in tokbuf */ |
||||
int32 ntok; /* Number of tokens on line */ |
||||
pid32 child; /* Process ID of spawned child */ |
||||
bool8 backgnd; /* Run command in background? */ |
||||
char *outname, *inname; /* Pointers to strings for file */ |
||||
/* names that follow > and < */ |
||||
did32 stdinput, stdoutput; /* Descriptors for redirected */ |
||||
/* input and output */ |
||||
int32 i; /* Index into array of tokens */ |
||||
int32 j; /* Index into array of commands */ |
||||
int32 msg; /* Message from receive() for */ |
||||
/* child termination */ |
||||
int32 tmparg; /* Address of this var is used */ |
||||
/* when first creating child */ |
||||
/* process, but is replaced */ |
||||
char *src, *cmp; /* Pointers used during name */ |
||||
/* comparison */ |
||||
bool8 diff; /* Was difference found during */ |
||||
char *args[SHELL_MAXTOK]; /* Argument vector passed to */ |
||||
/* builtin commands */ |
||||
did32 dev = 0; /* ID of tty device from which */ |
||||
|
||||
/* Print shell banner and startup message */ |
||||
|
||||
/*
|
||||
fprintf(dev, "\n\n%s%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n", |
||||
SHELL_BAN0,SHELL_BAN1,SHELL_BAN2,SHELL_BAN3,SHELL_BAN4, |
||||
SHELL_BAN5,SHELL_BAN6,SHELL_BAN7,SHELL_BAN8,SHELL_BAN9,SHELL_BAN10); |
||||
|
||||
fprintf(dev, "%s\n\n", SHELL_STRTMSG); |
||||
*/ |
||||
|
||||
/* Continually prompt the user, read input, and execute command */ |
||||
|
||||
|
||||
while (TRUE) { |
||||
|
||||
// RAFA
|
||||
// fprintf(dev, "\033[2J");
|
||||
// fprintf(dev, "\033[H");
|
||||
|
||||
/* Display prompt */ |
||||
fprintf(dev, SHELL_PROMPT); |
||||
|
||||
|
||||
len = read(dev, buf, sizeof(buf)); |
||||
|
||||
/* Exit gracefully on end-of-file */ |
||||
|
||||
if (len == EOF) { |
||||
break; |
||||
} |
||||
|
||||
/* If line contains only NEWLINE, go to next line */ |
||||
|
||||
if (len <= 1) { |
||||
continue; |
||||
} |
||||
|
||||
buf[len] = SH_NEWLINE; /* terminate line */ |
||||
|
||||
/* Parse input line and divide into tokens */ |
||||
|
||||
ntok = lexan(buf, len, tokbuf, &tlen, tok, toktyp); |
||||
|
||||
/* Handle parsing error */ |
||||
|
||||
if (ntok == SYSERR) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
|
||||
/* If line is empty, go to next input line */ |
||||
|
||||
if (ntok == 0) { |
||||
// fprintf(dev, "\n");
|
||||
continue; |
||||
} |
||||
|
||||
/* If last token is '&', set background */ |
||||
|
||||
if (toktyp[ntok-1] == SH_TOK_AMPER) { |
||||
ntok-- ; |
||||
tlen-= 2; |
||||
backgnd = TRUE; |
||||
} else { |
||||
backgnd = FALSE; |
||||
} |
||||
|
||||
|
||||
/* Check for input/output redirection (default is none) */ |
||||
|
||||
outname = inname = NULL; |
||||
if ( (ntok >=3) && ( (toktyp[ntok-2] == SH_TOK_LESS) |
||||
||(toktyp[ntok-2] == SH_TOK_GREATER))){ |
||||
if (toktyp[ntok-1] != SH_TOK_OTHER) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
if (toktyp[ntok-2] == SH_TOK_LESS) { |
||||
inname = &tokbuf[tok[ntok-1]]; |
||||
} else { |
||||
outname = &tokbuf[tok[ntok-1]]; |
||||
} |
||||
ntok -= 2; |
||||
tlen = tok[ntok]; |
||||
} |
||||
|
||||
|
||||
if ( (ntok >=3) && ( (toktyp[ntok-2] == SH_TOK_LESS) |
||||
||(toktyp[ntok-2] == SH_TOK_GREATER))){ |
||||
if (toktyp[ntok-1] != SH_TOK_OTHER) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
if (toktyp[ntok-2] == SH_TOK_LESS) { |
||||
if (inname != NULL) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
inname = &tokbuf[tok[ntok-1]]; |
||||
} else { |
||||
if (outname != NULL) { |
||||
// fprintf(dev,"%s\n", SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
outname = &tokbuf[tok[ntok-1]]; |
||||
} |
||||
ntok -= 2; |
||||
tlen = tok[ntok]; |
||||
} |
||||
|
||||
/* Verify remaining tokens are type "other" */ |
||||
|
||||
for (i=0; i<ntok; i++) { |
||||
if (toktyp[i] != SH_TOK_OTHER) { |
||||
break; |
||||
} |
||||
} |
||||
if ((ntok == 0) || (i < ntok)) { |
||||
// fprintf(dev, SHELL_SYNERRMSG);
|
||||
continue; |
||||
} |
||||
|
||||
stdinput = stdoutput = dev; |
||||
|
||||
/* Lookup first token in the command table */ |
||||
|
||||
for (j = 0; j < ncmd; j++) { |
||||
src = cmdtab[j].cname; |
||||
cmp = tokbuf; |
||||
diff = FALSE; |
||||
while (*src != NULLCH) { |
||||
if (*cmp != *src) { |
||||
diff = TRUE; |
||||
break; |
||||
} |
||||
src++; |
||||
cmp++; |
||||
} |
||||
if (diff || (*cmp != NULLCH)) { |
||||
continue; |
||||
} else { |
||||
break; |
||||
} |
||||
} |
||||
|
||||
/* Handle command not found */ |
||||
|
||||
if (j >= ncmd) { |
||||
// fprintf(dev, "command %s not found\n", tokbuf);
|
||||
continue; |
||||
} |
||||
|
||||
/* Handle built-in command */ |
||||
|
||||
if (cmdtab[j].cbuiltin) { /* No background or redirect. */ |
||||
if (inname != NULL || outname != NULL || backgnd){ |
||||
// fprintf(dev, SHELL_BGERRMSG);
|
||||
continue; |
||||
} else { |
||||
/* Set up arg vector for call */ |
||||
|
||||
for (i=0; i<ntok; i++) { |
||||
args[i] = &tokbuf[tok[i]]; |
||||
} |
||||
|
||||
/* Call builtin shell function */ |
||||
|
||||
if ((*cmdtab[j].cfunc)(ntok, args) |
||||
== SHELL_EXIT) { |
||||
break; |
||||
} |
||||
} |
||||
continue; |
||||
} |
||||
|
||||
/* Open files and redirect I/O if specified */ |
||||
|
||||
if (inname != NULL) { |
||||
stdinput = open(NAMESPACE,inname,"ro"); |
||||
if (stdinput == SYSERR) { |
||||
// fprintf(dev, SHELL_INERRMSG, inname);
|
||||
continue; |
||||
} |
||||
} |
||||
if (outname != NULL) { |
||||
stdoutput = open(NAMESPACE,outname,"w"); |
||||
if (stdoutput == SYSERR) { |
||||
// fprintf(dev, SHELL_OUTERRMSG, outname);
|
||||
continue; |
||||
} else { |
||||
control(stdoutput, F_CTL_TRUNC, 0, 0); |
||||
} |
||||
} |
||||
|
||||
// int eeprom_fd = open(RAM0, nombre, "w");
|
||||
// char raf[32] = "pepe";
|
||||
// write(fd, pepe, 32);
|
||||
// int eeprom_fd = open(RAM0, nombre, "w");
|
||||
|
||||
/* Spawn child thread for non-built-in commands */ |
||||
|
||||
// RAFA child = create(cmdtab[j].cfunc,
|
||||
// RAFA SHELL_CMDSTK, SHELL_CMDPRIO,
|
||||
// RAFA cmdtab[j].cname, 2, ntok, &tmparg);
|
||||
/* 160 bytes de stack perfecto */ |
||||
child = create(cmdtab[j].cfunc, |
||||
460, SHELL_CMDPRIO, |
||||
cmdtab[j].cname, 2, ntok, &tmparg); |
||||
|
||||
/* If creation or argument copy fails, report error */ |
||||
|
||||
// serial_put_char('X');
|
||||
// if (child == SYSERR)
|
||||
// serial_put_char('Y');
|
||||
if ((child == SYSERR) || |
||||
(addargs(child, ntok, tok, tlen, tokbuf, &tmparg) |
||||
== SYSERR) ) { |
||||
// serial_put_char('Z');
|
||||
fprintf(dev, SHELL_CREATMSG); |
||||
continue; |
||||
} |
||||
|
||||
/* Set stdinput and stdoutput in child to redirect I/O */ |
||||
|
||||
proctab[child].prdesc[0] = stdinput; |
||||
proctab[child].prdesc[1] = stdoutput; |
||||
|
||||
msg = recvclr(); |
||||
resume(child); |
||||
|
||||
// RAFA AGREGA
|
||||
resched(); |
||||
// serial_put_char('X');
|
||||
|
||||
if (! backgnd) { |
||||
msg = receive(); |
||||
while (msg != child) { |
||||
msg = receive(); |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Terminate the shell process by returning from the top level */ |
||||
|
||||
// fprintf(dev,SHELL_EXITMSG);
|
||||
return OK; |
||||
} |
||||
Loading…
Reference in new issue