mirror of https://github.com/zrafa/xinu-avr.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.7 KiB
128 lines
3.7 KiB
/* create.c - create, newpid */ |
|
|
|
/* avr specific */ |
|
|
|
#include <stdarg.h> |
|
#include <xinu.h> |
|
|
|
local pid32 newpid(); |
|
|
|
#define roundew(x) ( (x+3)& ~0x3) |
|
|
|
/* avr specific */ |
|
#define MAGIC 0xaa /* unusual value for top of stk */ |
|
|
|
|
|
/*------------------------------------------------------------------------ |
|
* create - create a process to start running a procedure |
|
*------------------------------------------------------------------------ |
|
*/ |
|
pid32 create( |
|
int (*procaddr)(), /* procedure address */ |
|
int ssize, /* stack size in bytes */ |
|
int priority, /* process priority > 0 */ |
|
char *name, /* name (for debugging) */ |
|
int nargs, /* number of args that follow */ |
|
... |
|
) |
|
{ |
|
intmask mask; /* interrupt mask */ |
|
pid32 pid; /* stores new process id */ |
|
struct procent *prptr; /* pointer to proc. table entry */ |
|
int i; |
|
unsigned char *saddr; /* stack address */ |
|
va_list ap; |
|
|
|
mask = disable(); |
|
if (ssize < MINSTK) |
|
ssize = MINSTK; |
|
ssize = (int) roundew(ssize); |
|
if (((saddr = (unsigned char *)getstk(ssize)) == |
|
(uint32 *)SYSERR ) || |
|
(pid=newpid()) == SYSERR || priority < 1 ) { |
|
avr_kprintf(m10); |
|
restore(mask); |
|
return SYSERR; |
|
} |
|
|
|
|
|
|
|
prcount++; |
|
prptr = &proctab[pid]; |
|
|
|
/* initialize process table entry for new process */ |
|
prptr->prstate = PR_SUSP; /* initial state is suspended */ |
|
prptr->prprio = priority; |
|
prptr->prstkbase = (char *)saddr; |
|
prptr->prstklen = ssize; |
|
prptr->prname[PNMLEN-1] = NULLCH; |
|
for (i=0 ; i<PNMLEN-1 && (prptr->prname[i]=name[i])!=NULLCH; i++) |
|
; |
|
prptr->prsem = -1; |
|
prptr->prparent = (pid32)getpid(); |
|
prptr->prhasmsg = FALSE; |
|
|
|
/* set up initial device descriptors for the shell */ |
|
prptr->prdesc[0] = CONSOLE; /* stdin is CONSOLE device */ |
|
prptr->prdesc[1] = CONSOLE; /* stdout is CONSOLE device */ |
|
prptr->prdesc[2] = CONSOLE; /* stderr is CONSOLE device */ |
|
|
|
|
|
/* Initialize stack as if the process was called */ |
|
*saddr-- = (char)MAGIC; /* Bottom of stack */ |
|
prptr->pargs = nargs; |
|
for (i=0 ; i<PNREGS ; i++) // VER TAMANIO PARA AVR |
|
prptr->pregs[i] = INITREG; |
|
prptr->paddr = (int *)procaddr; |
|
prptr->pregs[SPC_L] = lobyte((unsigned) procaddr); // GUARDAR SPC_L |
|
prptr->pregs[SPC_H] = hibyte((unsigned) procaddr); |
|
prptr->pregs[SSREG] = INITPS; |
|
// POR AHORA NO (usado en kill.c en avr orig : prptr->pnxtkin = BADPID; |
|
// POR AHORA NO prptr->pdevs[0] = prptr->pdevs[1] = BADDEV; |
|
|
|
int * a = (int *)(&nargs + 1); |
|
for (i = 0; i < nargs; i++) { |
|
prptr->parg[i] = (int) *a++; |
|
} |
|
prptr->parg[nargs] = 0; |
|
|
|
/* machine/compiler dependent pass arguments to created process */ |
|
prptr->pregs[24] = lobyte((unsigned)prptr->pargs); /*r24*/ |
|
prptr->pregs[25] = hibyte((unsigned)prptr->pargs); |
|
prptr->pregs[22] = lobyte((unsigned)&prptr->parg[0]); /*r22*/ |
|
prptr->pregs[23] = hibyte((unsigned)&prptr->parg[0]); |
|
|
|
*saddr-- = lobyte((unsigned)INITRET); /* push on initial return address*/ |
|
*saddr-- = hibyte((unsigned)INITRET); |
|
*saddr-- = lobyte((unsigned)procaddr); /* push on procedure address */ |
|
*saddr-- = hibyte((unsigned)procaddr); |
|
prptr->pregs[SSP_L] = lobyte((unsigned) saddr); |
|
prptr->pregs[SSP_H] = hibyte((unsigned) saddr); |
|
|
|
restore(mask); |
|
return pid; |
|
} |
|
|
|
/*------------------------------------------------------------------------ |
|
* newpid - Obtain a new (free) process ID |
|
*------------------------------------------------------------------------ |
|
*/ |
|
local pid32 newpid(void) |
|
{ |
|
uint32 i; /* iterate through all processes*/ |
|
// static pid32 nextpid = 1; /* position in table to try or */ |
|
static pid32 nextpid = 0; /* position in table to try or */ |
|
/* one beyond end of table */ |
|
|
|
/* check all NPROC slots */ |
|
|
|
for (i = 0; i < NPROC; i++) { |
|
nextpid %= NPROC; /* wrap around to beginning */ |
|
if (proctab[nextpid].prstate == PR_FREE) { |
|
return nextpid++; |
|
} else { |
|
nextpid++; |
|
} |
|
} |
|
return (pid32) SYSERR; |
|
}
|
|
|