Browse Source

platinit meminit ttyinit kprintf works

pull/1/head
Rafael Zurita 6 years ago
parent
commit
e35517485c
  1. 3
      compile/Makefile
  2. 4
      config/Configuration
  3. 11
      config/config.y
  4. 58
      device/tty/ttycontrol.c
  5. 41
      device/tty/ttygetc.c
  6. 272
      device/tty/ttyhandle_in.c
  7. 85
      device/tty/ttyhandle_out.c
  8. 122
      device/tty/ttyhandler.c
  9. 83
      device/tty/ttyinit.c
  10. 25
      device/tty/ttykickout.c
  11. 44
      device/tty/ttyputc.c
  12. 68
      device/tty/ttyread.c
  13. 29
      device/tty/ttywrite.c
  14. 3
      include/mark.h
  15. 1
      include/messages.h
  16. 6
      include/prototypes.h
  17. 2
      include/tty.h
  18. 1
      lib/messages.c
  19. 9
      system/clkhandler.c
  20. 58
      system/clkinit.c
  21. 12
      system/evec.c
  22. 10
      system/init.c
  23. 13
      system/initialize.c
  24. 49
      system/intr.c
  25. 9
      system/kprintf.c
  26. 10
      system/meminit.c
  27. 2
      system/ptinit.c
  28. 75
      system/serial_avr.c

3
compile/Makefile

@ -43,11 +43,12 @@ REBUILDFLAGS = -s $(TOPDIR)/system debug.c \
REBUILDFLAGS = -s $(TOPDIR)/system \
-s $(TOPDIR)/lib \
-s $(TOPDIR)/device/nam \
-s $(TOPDIR)/device/tty \
-s $(TOPDIR)/shell 'xsh_rdstest*'
INCLUDE = -I$(TOPDIR)/include
# RAFA DEFS = -DBSDURG -DVERSION=\""`cat $(VERSIONFILE)`"\"
DEFS = -DVERSION=\""Rafa"\"
DEFS = -DVERSION=\""Xinu AVR 0.1 RAFA"\"
# Compiler flags
# CFLAGS = -mcpu=cortex-m3 -mno-unaligned-access -mthumb -fno-builtin -fno-stack-protector -nostdlib -c -Wall -O ${DEFS} ${INCLUDE}

4
config/Configuration

@ -36,18 +36,18 @@ FIN DE RAFA */
/* type of a tty device */
tty:
/* RAFA
on uart
-i ttyinit -o ionull -c ionull
-r ttyread -g ttygetc -p ttyputc
-w ttywrite -s ioerr -n ttycontrol
-intr ttyhandler
FIN DE RAFA */
/* RAFA
on uart
-i ionull -o ionull -c ionull
-r ionull -g ionull -p ionull
-w ionull -s ioerr -n ionull
-intr ionull
FIN DE RAFA */
/* type of ram disk */
/* RAFA

11
config/config.y

@ -110,7 +110,7 @@ char *devstab[] = {
"\tvoid (*dvintr)(void);",
"\tbyte dvirq;",
"};\n",
"extern const struct dentry devtab[]; /* one entry per device */",
"extern struct dentry devtab[]; /* one entry per device */",
NULL
};
@ -390,11 +390,10 @@ int main(int argc, char **argv) {
fprintf(confc, "/* Device independent I/O switch */\n\n");
if (ndevs > 0)
{
// RAFA fprintf(confc, "const struct dentry devtab[NDEVS] =\n{\n");
fprintf(confc, "typedef unsigned int size_t;\n");
fprintf(confc, "#include <avr/pgmspace.h>\n");
fprintf(confc, "const struct dentry devtab[] PROGMEM =\n{\n");
// RAFA fprintf(confc, "const struct dentry devtab[] PROGMEM =\n{\n");
// fprintf(confc, "typedef unsigned int size_t;\n");
// fprintf(confc, "#include <avr/pgmspace.h>\n");
// fprintf(confc, "const struct dentry devtab[] PROGMEM =\n{\n");
fprintf(confc, "struct dentry devtab[] =\n{\n");
fprintf(confc, "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n\n",
"/**",
" * Format of entries is:",

58
device/tty/ttycontrol.c

@ -0,0 +1,58 @@
/* ttycontrol.c - ttycontrol */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttycontrol - Control a tty device by setting modes
*------------------------------------------------------------------------
*/
devcall ttycontrol(
struct dentry *devptr, /* Entry in device switch table */
int32 func, /* Function to perform */
int32 arg1, /* Argument 1 for request */
int32 arg2 /* Argument 2 for request */
)
{
struct ttycblk *typtr; /* Pointer to tty control block */
char ch; /* Character for lookahead */
typtr = &ttytab[devptr->dvminor];
/* Process the request */
switch ( func ) {
case TC_NEXTC:
wait(typtr->tyisem);
ch = *typtr->tyitail;
signal(typtr->tyisem);
return (devcall)ch;
case TC_MODER:
typtr->tyimode = TY_IMRAW;
return (devcall)OK;
case TC_MODEC:
typtr->tyimode = TY_IMCOOKED;
return (devcall)OK;
case TC_MODEK:
typtr->tyimode = TY_IMCBREAK;
return (devcall)OK;
case TC_ICHARS:
return(semcount(typtr->tyisem));
case TC_ECHO:
typtr->tyiecho = TRUE;
return (devcall)OK;
case TC_NOECHO:
typtr->tyiecho = FALSE;
return (devcall)OK;
default:
return (devcall)SYSERR;
}
}

41
device/tty/ttygetc.c

@ -0,0 +1,41 @@
/* ttygetc.c - ttygetc */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttygetc - Read one character from a tty device (interrupts disabled)
*------------------------------------------------------------------------
*/
devcall ttygetc(
struct dentry *devptr /* Entry in device switch table */
)
{
char ch; /* Character to return */
struct ttycblk *typtr; /* Pointer to ttytab entry */
typtr = &ttytab[devptr->dvminor];
/* Wait for a character in the buffer and extract one character */
// struct sentry * semptr;
// semptr = &semtab[typtr->tyisem];
// while(--(semptr->scount) < 0);
wait(typtr->tyisem);
ch = *typtr->tyihead++;
/* Wrap around to beginning of buffer, if needed */
if (typtr->tyihead >= &typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyihead = typtr->tyibuff;
}
/* In cooked mode, check for the EOF character */
if ( (typtr->tyimode == TY_IMCOOKED) && (typtr->tyeof) &&
(ch == typtr->tyeofch) ) {
return (devcall)EOF;
}
return (devcall)ch;
}

272
device/tty/ttyhandle_in.c

@ -0,0 +1,272 @@
/* ttyhandle_in.c - ttyhandle_in, erase1, eputc, echoch */
#include <xinu.h>
local void erase1(struct ttycblk *, struct uart_csreg *);
local void echoch(char, struct ttycblk *, struct uart_csreg *);
local void eputc(char, struct ttycblk *, struct uart_csreg *);
/*------------------------------------------------------------------------
* ttyhandle_in - Handle one arriving char (interrupts disabled)
*------------------------------------------------------------------------
*/
// void ttyhandle_in (
// struct ttycblk *typtr, /* Pointer to ttytab entry */
// struct uart_csreg *csrptr /* Address of UART's CSR */
// )
void ttyhandle_in (
struct ttycblk *typtr, /* Pointer to ttytab entry */
struct uart_csreg *csrptr, /* Address of UART's CSR */
char c /* AVR char received */
)
{
char ch; /* Next char from device */
int32 avail; /* Chars available in buffer */
ch = c;
/* Compute chars available */
avail = semcount(typtr->tyisem);
if (avail < 0) { /* One or more processes waiting*/
avail = 0;
}
/* Handle raw mode */
if (typtr->tyimode == TY_IMRAW) {
if (avail >= TY_IBUFLEN) { /* No space => ignore input */
return;
}
/* Place char in buffer with no editing */
*typtr->tyitail++ = ch;
/* Wrap buffer pointer */
if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyitail = typtr->tyibuff;
}
/* Signal input semaphore and return */
signal(typtr->tyisem);
return;
}
/* Handle cooked and cbreak modes (common part) */
if ( (ch == TY_RETURN) && typtr->tyicrlf ) {
ch = TY_NEWLINE;
}
/* If flow control is in effect, handle ^S and ^Q */
// STM32 specific: if (typtr->tyoflow) {
// STM32 specific: if (ch == typtr->tyostart) { /* ^Q starts output */
// STM32 specific: typtr->tyoheld = FALSE;
// STM32 specific: ttykickout(csrptr);
// STM32 specific: return;
// STM32 specific: } else if (ch == typtr->tyostop) { /* ^S stops output */
// STM32 specific: typtr->tyoheld = TRUE;
// STM32 specific: return;
// STM32 specific: }
// STM32 specific: }
typtr->tyoheld = FALSE; /* Any other char starts output */
if (typtr->tyimode == TY_IMCBREAK) { /* Just cbreak mode */
/* If input buffer is full, send bell to user */
if (avail >= TY_IBUFLEN) {
eputc(typtr->tyifullc, typtr, csrptr);
} else { /* Input buffer has space for this char */
*typtr->tyitail++ = ch;
/* Wrap around buffer */
if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyitail = typtr->tyibuff;
}
if (typtr->tyiecho) { /* Are we echoing chars?*/
echoch(ch, typtr, csrptr);
}
signal(typtr->tyisem);
}
return;
} else { /* Just cooked mode (see common code above) */
/* Line kill character arrives - kill entire line */
if (ch == typtr->tyikillc && typtr->tyikill) {
typtr->tyitail -= typtr->tyicursor;
if (typtr->tyitail < typtr->tyibuff) {
typtr->tyitail += TY_IBUFLEN;
}
typtr->tyicursor = 0;
eputc(TY_RETURN, typtr, csrptr);
eputc(TY_NEWLINE, typtr, csrptr);
return;
}
/* Erase (backspace) character */
if ( ((ch==typtr->tyierasec) || (ch==typtr->tyierasec2))
&& typtr->tyierase) {
if (typtr->tyicursor > 0) {
typtr->tyicursor--;
erase1(typtr, csrptr);
}
return;
}
/* End of line */
if ( (ch == TY_NEWLINE) || (ch == TY_RETURN) ) {
if (typtr->tyiecho) {
echoch(ch, typtr, csrptr);
}
*typtr->tyitail++ = ch;
if (typtr->tyitail>=&typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyitail = typtr->tyibuff;
}
/* Make entire line (plus \n or \r) available */
signaln(typtr->tyisem, typtr->tyicursor + 1);
typtr->tyicursor = 0; /* Reset for next line */
return;
}
/* Character to be placed in buffer - send bell if */
/* buffer has overflowed */
avail = semcount(typtr->tyisem);
if (avail < 0) {
avail = 0;
}
if ((avail + typtr->tyicursor) >= TY_IBUFLEN-1) {
eputc(typtr->tyifullc, typtr, csrptr);
return;
}
/* EOF character: recognize at beginning of line, but */
/* print and ignore otherwise. */
if (ch == typtr->tyeofch && typtr->tyeof) {
if (typtr->tyiecho) {
echoch(ch, typtr, csrptr);
}
if (typtr->tyicursor != 0) {
return;
}
*typtr->tyitail++ = ch;
signal(typtr->tyisem);
return;
}
/* Echo the character */
if (typtr->tyiecho) {
echoch(ch, typtr, csrptr);
}
/* Insert in the input buffer */
typtr->tyicursor++;
*typtr->tyitail++ = ch;
/* Wrap around if needed */
if (typtr->tyitail >= &typtr->tyibuff[TY_IBUFLEN]) {
typtr->tyitail = typtr->tyibuff;
}
return;
}
}
/*------------------------------------------------------------------------
* erase1 - Erase one character honoring erasing backspace
*------------------------------------------------------------------------
*/
local void erase1(
struct ttycblk *typtr, /* Ptr to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
char ch; /* Character to erase */
if ( (--typtr->tyitail) < typtr->tyibuff) {
typtr->tyitail += TY_IBUFLEN;
}
/* Pick up char to erase */
ch = *typtr->tyitail;
if (typtr->tyiecho) { /* Are we echoing? */
if (ch < TY_BLANK || ch == 0177) { /* Nonprintable */
if (typtr->tyevis) { /* Visual cntl chars */
eputc(TY_BACKSP, typtr, csrptr);
if (typtr->tyieback) { /* Erase char */
eputc(TY_BLANK, typtr, csrptr);
eputc(TY_BACKSP, typtr, csrptr);
}
}
eputc(TY_BACKSP, typtr, csrptr);/* Bypass up arr*/
if (typtr->tyieback) {
eputc(TY_BLANK, typtr, csrptr);
eputc(TY_BACKSP, typtr, csrptr);
}
} else { /* A normal character that is printable */
eputc(TY_BACKSP, typtr, csrptr);
if (typtr->tyieback) { /* erase the character */
eputc(TY_BLANK, typtr, csrptr);
eputc(TY_BACKSP, typtr, csrptr);
}
}
}
return;
}
/*------------------------------------------------------------------------
* echoch - Echo a character with visual and output crlf options
*------------------------------------------------------------------------
*/
local void echoch(
char ch, /* Character to echo */
struct ttycblk *typtr, /* Ptr to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
if ((ch==TY_NEWLINE || ch==TY_RETURN) && typtr->tyecrlf) {
eputc(TY_RETURN, typtr, csrptr);
eputc(TY_NEWLINE, typtr, csrptr);
} else if ( (ch<TY_BLANK||ch==0177) && typtr->tyevis) {
eputc(TY_UPARROW, typtr, csrptr);/* print ^x */
eputc(ch+0100, typtr, csrptr); /* Make it printable */
} else {
eputc(ch, typtr, csrptr);
}
}
/*------------------------------------------------------------------------
* eputc - Put one character in the echo queue
*------------------------------------------------------------------------
*/
local void eputc(
char ch, /* Character to echo */
struct ttycblk *typtr, /* Ptr to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
*typtr->tyetail++ = ch;
/* Wrap around buffer, if needed */
if (typtr->tyetail >= &typtr->tyebuff[TY_EBUFLEN]) {
typtr->tyetail = typtr->tyebuff;
}
ttykickout(csrptr);
return;
}

85
device/tty/ttyhandle_out.c

@ -0,0 +1,85 @@
/* ttyhandle_out.c - ttyhandle_out */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttyhandle_out - Handle an output on a tty device by sending more
* characters to the device FIFO (interrupts disabled)
*------------------------------------------------------------------------
*/
void ttyhandle_out(
struct ttycblk *typtr, /* Ptr to ttytab entry */
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
int32 ochars; /* Number of output chars sent */
/* to the UART */
int32 avail; /* Available chars in output buf*/
int32 uspace; /* Space left in onboard UART */
/* output FIFO */
//uint32 ier = 0;
/* If output is currently held, simply ignore the call */
if (typtr->tyoheld) {
return;
}
/* If echo and output queues empty, turn off interrupts */
if ( (typtr->tyehead == typtr->tyetail) &&
(semcount(typtr->tyosem) >= TY_OBUFLEN) ) {
// STM32 specific: csrptr->cr1 &= ~(1 << UART_INTR_TX); /* deshabilita interrupciones */
//ier = csrptr->ier;
//csrptr->ier = ier & ~UART_IER_ETBEI;
return;
}
/* Initialize uspace to the available space in the Tx FIFO */
//uspace = UART_FIFO_SIZE - csrptr->txfifo_lvl;
uspace = UART_FIFO_SIZE;
/* While onboard FIFO is not full and the echo queue is */
/* nonempty, xmit chars from the echo queue */
while ( (uspace>0) && typtr->tyehead != typtr->tyetail) {
// STM32 specific: csrptr->dr = *typtr->tyehead++; /* ENVIA CARACERES POR UART */
serial_put_char(*typtr->tyohead++); /* ENVIA CARACERES POR UART */
if (typtr->tyehead >= &typtr->tyebuff[TY_EBUFLEN]) {
typtr->tyehead = typtr->tyebuff;
}
uspace--;
}
/* While onboard FIFO is not full and the output queue is */
/* nonempty, transmit chars from the output queue */
ochars = 0;
avail = TY_OBUFLEN - semcount(typtr->tyosem);
while ( (uspace>0) && (avail > 0) ) {
//while(!(csrptr->sr & UART_TC));
//while(csrptr->sr &= ~(1 << UART_TEST));
// STM32 specific: csrptr->dr = *typtr->tyohead++; /* ENVIA CARACERES POR UART */
serial_put_char(*typtr->tyohead++); /* ENVIA CARACERES POR UART */
if (typtr->tyohead >= &typtr->tyobuff[TY_OBUFLEN]) {
typtr->tyohead = typtr->tyobuff;
}
avail--;
uspace--;
ochars++;
}
if (ochars > 0) {
signaln(typtr->tyosem, ochars);
}
if ( (typtr->tyehead == typtr->tyetail) &&
(semcount(typtr->tyosem) >= TY_OBUFLEN) ) {
// STM32 specific: csrptr->cr1 &= ~(1 << UART_INTR_TX); /* deshabilita interrupcines de transmición */
//ier = csrptr->ier;
//csrptr->ier = (ier & ~UART_IER_ETBEI);
}
return;
}

122
device/tty/ttyhandler.c

@ -0,0 +1,122 @@
/* ttyhandler.c - ttyhandler */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttyhandler - Handle an interrupt for a tty (serial) device
*------------------------------------------------------------------------
*/
void ttyhandler(uint32 xnum, char c, int flag) {
struct dentry *devptr; /* Address of device control blk*/
struct ttycblk *typtr; /* Pointer to ttytab entry */
struct uart_csreg *csrptr; /* Address of UART's CSR */
// uint32 iir = 0; /* Interrupt identification */
// uint32 lsr = 0; /* Line status */
//
//
/* Get CSR address of the device (assume console for now) */
devptr = (struct dentry *) &devtab[CONSOLE];
// STM32 specific: csrptr = (struct uart_csreg *) devptr->dvcsr;
/* Obtain a pointer to the tty control block */
typtr = &ttytab[devptr->dvminor];
/* Test type of UART interrupt */
// STM32 specific: uint8 flags = csrptr->sr & 0xFF;
//kprintf("%x", flags);
// STM32 specific: if (flags & UART_RXNE) {
// STM32 specific: ttyhandle_in(typtr, csrptr);
// STM32 specific: return;
// STM32 specific: }
// STM32 specific: else if (flags & UART_TC) {
// STM32 specific: ttyhandle_out(typtr, csrptr);
// STM32 specific: return;
// STM32 specific: }
/* AVR */
if (flag) /* TX */
ttyhandle_out(typtr, csrptr);
else /* RX */
ttyhandle_in(typtr, csrptr, c);
// switch(flags) {
//
// case UART_TC_TXE:
// case UART_TC:
// ttyhandle_out(typtr, csrptr);
// return;
// case UART_RXNE:
// ttyhandle_in(typtr, csrptr);
// return;
//
// default:
// kprintf("Unknown status\n");
// return;
// }
// /* Decode hardware interrupt request from UART device */
//
// /* Check interrupt identification register */
// iir = csrptr->iir;
// if (iir & UART_IIR_IRQ) {
// return;
// }
//
// /* Decode the interrupt cause based upon the value extracted */
// /* from the UART interrupt identification register. Clear */
// /* the interrupt source and perform the appropriate handling */
// /* to coordinate with the upper half of the driver */
//
// /* Decode the interrupt cause */
//
// iir &= UART_IIR_IDMASK; /* Mask off the interrupt ID */
// switch (iir) {
//
// /* Receiver line status interrupt (error) */
//
// case UART_IIR_RLSI:
// lsr = csrptr->lsr;
// if(lsr & UART_LSR_BI) { /* Break Interrupt */
//
// /* Read the RHR register to acknowledge */
//
// lsr = csrptr->buffer;
// }
// return;
//
// /* Receiver data available or timed out */
//
// case UART_IIR_RDA:
// case UART_IIR_RTO:
//
// resched_cntl(DEFER_START);
//
// /* While chars avail. in UART buffer, call ttyhandle_in */
//
// while ( (csrptr->lsr & UART_LSR_DR) != 0) {
// ttyhandle_in(typtr, csrptr);
// }
//
// resched_cntl(DEFER_STOP);
//
// return;
//
// /* Transmitter output FIFO is empty (i.e., ready for more) */
//
// case UART_IIR_THRE:
// ttyhandle_out(typtr, csrptr);
// return;
//
// /* Modem status change (simply ignore) */
//
// case UART_IIR_MSC:
// return;
// }
}

83
device/tty/ttyinit.c

@ -0,0 +1,83 @@
/* ttyinit.c - ttyinit */
#include <xinu.h>
struct ttycblk ttytab[Ntty];
/*------------------------------------------------------------------------
* ttyinit - Initialize buffers and modes for a tty line
*------------------------------------------------------------------------
*/
devcall ttyinit(
struct dentry *devptr /* Entry in device switch table */
)
{
struct ttycblk *typtr; /* Pointer to ttytab entry */
struct uart_csreg *uptr; /* Address of UART's CSRs */
typtr = &ttytab[ devptr->dvminor ];
/* Initialize values in the tty control block */
typtr->tyihead = typtr->tyitail = /* Set up input queue */
&typtr->tyibuff[0]; /* as empty */
typtr->tyisem = semcreate(0); /* Input semaphore */
typtr->tyohead = typtr->tyotail = /* Set up output queue */
&typtr->tyobuff[0]; /* as empty */
typtr->tyosem = semcreate(TY_OBUFLEN); /* Output semaphore */
typtr->tyehead = typtr->tyetail = /* Set up echo queue */
&typtr->tyebuff[0]; /* as empty */
typtr->tyimode = TY_IMCOOKED; /* Start in cooked mode */
typtr->tyiecho = TRUE; /* Echo console input */
typtr->tyieback = TRUE; /* Honor erasing bksp */
typtr->tyevis = TRUE; /* Visual control chars */
typtr->tyecrlf = TRUE; /* Echo CRLF for NEWLINE*/
typtr->tyicrlf = TRUE; /* Map CR to NEWLINE */
typtr->tyierase = TRUE; /* Do erasing backspace */
typtr->tyierasec = TY_BACKSP; /* Primary erase char */
typtr->tyierasec2= TY_BACKSP2; /* Alternate erase char */
typtr->tyeof = TRUE; /* Honor eof on input */
typtr->tyeofch = TY_EOFCH; /* End-of-file character*/
typtr->tyikill = TRUE; /* Allow line kill */
typtr->tyikillc = TY_KILLCH; /* Set line kill to ^U */
typtr->tyicursor = 0; /* Start of input line */
typtr->tyoflow = TRUE; /* Handle flow control */
typtr->tyoheld = FALSE; /* Output not held */
typtr->tyostop = TY_STOPCH; /* Stop char is ^S */
typtr->tyostart = TY_STRTCH; /* Start char is ^Q */
typtr->tyocrlf = TRUE; /* Send CRLF for NEWLINE*/
typtr->tyifullc = TY_FULLCH; /* Send ^G when buffer */
/* is full */
/* Initialize UART */
struct gpio_csreg *gptr;
struct clock_csreg *cptr;
/* Enable 'clock' on peripherals */
cptr = (struct clock_csreg *)CLOCK_BASE;
cptr->apb2enr |= (1 << IOPAEN) | (1 << USART1EN);
/* Set in and output mode */
gptr = (struct gpio_csreg *)(0x40010800);
gptr->crh = 0x44444894;
/* Enable peripheral */
uptr = (struct uart_csreg *)(0x40013800);
uptr->cr1 &= ~(1 << UART_EN);
/* Set baudrate 115200 */
uptr->brr = 0x00000045;
uptr->cr1 |= (1 << UART_TX_EN) | (1 << UART_RX_EN); /* Enable lines */
uptr->cr1 |= (1 << UART_INTR_RX) | (1 << UART_INTR_TX); /* Enable interrupts */
/* Set and enable interrupt vector */
set_evec(devptr->dvirq, (uint32)devptr->dvintr);
*NVIC_ISER1 |= (1 << 5);
/* Start the device */
uptr->cr1 |= (1 << UART_EN);
// ttykickout(uptr);
return OK;
}

25
device/tty/ttykickout.c

@ -0,0 +1,25 @@
/* ttykickout.c - ttykickout */
#include <xinu.h>
#include <avr/interrupt.h>
/*------------------------------------------------------------------------
* ttykickout - "Kick" the hardware for a tty device, causing it to
* generate an output interrupt (interrupts disabled)
*------------------------------------------------------------------------
*/
void ttykickout(
struct uart_csreg *csrptr /* Address of UART's CSRs */
)
{
/* Force the UART hardware generate an output interrupt */
// STM32 specific csrptr->cr1 |= (1 << UART_INTR_TX);
// STM32 specific *NVIC_STIR = 0x25; /* Generate general UART interrupt */
cli();
ttyhandler(1, 'X', 1); /* 1, 'X' arguments useless */
sei();
return;
}

44
device/tty/ttyputc.c

@ -0,0 +1,44 @@
/* ttyputc.c - ttyputc */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttyputc - Write one character to a tty device (interrupts disabled)
*------------------------------------------------------------------------
*/
devcall ttyputc(
struct dentry *devptr, /* Entry in device switch table */
char ch /* Character to write */
)
{
//struct uart_csreg * uptr;
struct ttycblk *typtr; /* Pointer to tty control block */
//uptr = (struct uart_csreg *)devptr->csreg;
typtr = &ttytab[devptr->dvminor];
/* Handle output CRLF by sending CR first */
if ( ch==TY_NEWLINE && typtr->tyocrlf ) {
ttyputc(devptr, TY_RETURN);
}
wait(typtr->tyosem); /* Wait for space in queue */
*typtr->tyotail++ = ch;
/* Wrap around to beginning of buffer, if needed */
if (typtr->tyotail >= &typtr->tyobuff[TY_OBUFLEN]) {
typtr->tyotail = typtr->tyobuff;
}
/* Start output in case device is idle */
//while () {
//
// uptr->dr =
//}
ttykickout((struct uart_csreg *)devptr->dvcsr);
return OK;
}

68
device/tty/ttyread.c

@ -0,0 +1,68 @@
/* ttyread.c - ttyread */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttyread - Read character(s) from a tty device (interrupts disabled)
*------------------------------------------------------------------------
*/
devcall ttyread(
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer of characters */
int32 count /* Count of character to read */
)
{
struct ttycblk *typtr; /* Pointer to tty control block */
int32 avail; /* Characters available in buff.*/
int32 nread; /* Number of characters read */
int32 firstch; /* First input character on line*/
char ch; /* Next input character */
if (count < 0) {
return SYSERR;
}
typtr= &ttytab[devptr->dvminor];
if (typtr->tyimode != TY_IMCOOKED) {
/* For count of zero, return all available characters */
if (count == 0) {
avail = semcount(typtr->tyisem);
if (avail == 0) {
return 0;
} else {
count = avail;
}
}
for (nread = 0; nread < count; nread++) {
*buff++ = (char) ttygetc(devptr);
}
return nread;
}
/* Block until input arrives */
firstch = ttygetc(devptr);
/* Check for End-Of-File */
if (firstch == EOF) {
return EOF;
}
/* Read up to a line */
ch = (char) firstch;
*buff++ = ch;
nread = 1;
while ( (nread < count) && (ch != TY_NEWLINE) &&
(ch != TY_RETURN) ) {
ch = ttygetc(devptr);
*buff++ = ch;
nread++;
}
return nread;
return OK;
}

29
device/tty/ttywrite.c

@ -0,0 +1,29 @@
/* ttywrite.c - ttywrite */
#include <xinu.h>
/*------------------------------------------------------------------------
* ttywrite - Write character(s) to a tty device (interrupts disabled)
*------------------------------------------------------------------------
*/
devcall ttywrite(
struct dentry *devptr, /* Entry in device switch table */
char *buff, /* Buffer of characters */
int32 count /* Count of character to write */
)
{
/* Handle negative and zero counts */
if (count < 0) {
return SYSERR;
} else if (count == 0){
return OK;
}
/* Write count characters one at a time */
for (; count>0 ; count--) {
ttyputc(devptr, *buff++);
}
return OK;
}

3
include/mark.h

@ -1,6 +1,7 @@
/* mark.h - notmarked */
#define MAXMARK 20 /* Maximum number of marked locations */
// RAFA #define MAXMARK 20 /* Maximum number of marked locations */
#define MAXMARK 10 /* Maximum number of marked locations */
extern int32 *(marks[]);
extern int32 nmarks;

1
include/messages.h

@ -9,6 +9,7 @@ extern const char m3[];
extern const char m4[];
extern const char m5[];
extern const char m6[];
extern const char m7[];

6
include/prototypes.h

@ -552,13 +552,15 @@ extern devcall ttycontrol(struct dentry *, int32, int32, int32);
extern devcall ttygetc(struct dentry *);
/* in file ttyhandle_in.c */
extern void ttyhandle_in(struct ttycblk *, struct uart_csreg *);
// RAFA extern void ttyhandle_in(struct ttycblk *, struct uart_csreg *);
extern void ttyhandle_in(struct ttycblk *, struct uart_csreg *, char c);
/* in file ttyhandle_out.c */
extern void ttyhandle_out(struct ttycblk *, struct uart_csreg *);
/* in file ttyhandler.c */
extern void ttyhandler(uint32);
// RAFA extern void ttyhandler(uint32);
extern void ttyhandler(uint32, char c, int tipo);
/* in file ttyinit.c */
extern devcall ttyinit(struct dentry *);

2
include/tty.h

@ -56,7 +56,7 @@ struct ttycblk { /* Tty line control block */
bool8 tyocrlf; /* Output CR/LF for LF ? */
char tyifullc; /* Char to send when input full */
};
// extern struct ttycblk ttytab[];
extern struct ttycblk ttytab[];
/* Characters with meaning to the tty driver */

1
lib/messages.c

@ -9,6 +9,7 @@ const char m3[] PROGMEM = "\n\nAll user processes have completed.\n\n";
const char m4[] PROGMEM = "namespace: cannot mount device %d\r\n";
const char m5[] PROGMEM = "namespace: device name %s too long\r\n";
const char m6[] PROGMEM = "Can't startup system";
const char m7[] PROGMEM = "ptinit - insufficient memory";

9
system/clkhandler.c

@ -23,11 +23,10 @@
void clkhandler()
{
struct timer_csreg *tptr;
tptr = (struct timer_csreg *)TIM2_BASE;
// STM32 specific tptr = (struct timer_csreg *)TIM2_BASE;
/* Clear interrupt flag */
tptr->sr &= ~(1 << TIM_UIF);
// STM32 specific /* Clear interrupt flag */
// STM32 specific tptr->sr &= ~(1 << TIM_UIF);
/* Increment 1000ms counter */
@ -58,6 +57,6 @@ void clkhandler()
if((--preempt) == 0) {
preempt = QUANTUM;
// PendSV call
*SCB_ICSR |= (1 << PENDSV_INTR);
// STM32 specific *SCB_ICSR |= (1 << PENDSV_INTR);
}
}

58
system/clkinit.c

@ -16,6 +16,9 @@
#include <xinu.h>
#include <avr/io.h>
#include <avr/interrupt.h>
uint32 clktime; /* Seconds since boot */
uint32 count1000; /* ms since last clock tick */
qid16 sleepq; /* Queue of sleeping processes */
@ -39,25 +42,62 @@ void clkinit(void)
clktime = 0; /* Start counting seconds */
count1000 = 0;
/* RAFA : LO QUE SIGUE ERA PARA el CLOCK STM32 */
/* Enable timer peripheral */
clockptr->apb1enr |= (1 << TIM2EN);
// RAFA clockptr->apb1enr |= (1 << TIM2EN);
/* Configuration for 1ms interrupt timer
Based on 8 MHz chip CLK / 2 */
tptr->cr1 |= (1 << TIM_URS);
tptr->psc = 0x7; /* Set to 0x3 for 1Mhz */
tptr->arr = 0x1000; /* Set to 1000 */
tptr->dier |= 0x1; /* Enable interrupts */
// RAFA tptr->cr1 |= (1 << TIM_URS);
// RAFA tptr->psc = 0x7; /* Set to 0x3 for 1Mhz */
// RAFA tptr->arr = 0x1000; /* Set to 1000 */
// RAFA tptr->dier |= 0x1; /* Enable interrupts */
/* Set interrupt vector for timer */
set_evec(TIM2_IRQ, (uint32)clkhandler);
*NVIC_ISER0 |= (1 << 28);
// RAFA set_evec(TIM2_IRQ, (uint32)clkhandler);
// RAFA *NVIC_ISER0 |= (1 << 28);
/* Set interrupt for PendSV: a pendsv call will execute the scheduler */
set_evec(PENDSV_ENTRY, (uint32)resched);
// RAFA set_evec(PENDSV_ENTRY, (uint32)resched);
/* Enable and start timer */
tptr->cr1 |= (1 << TIM_CEN);
// RAFA tptr->cr1 |= (1 << TIM_CEN);
/* AVR atmega328p timer/clock init: interrupt every 1ms */
// cli(); // We are here with interrupts disablled */
TCCR0B |= (1<<CS01) | (1<<CS00); //clock select is divided by 64.
TCCR0A |= (1<<WGM01); //sets mode to CTC
// OCR0A = 0x7C; //sets TOP to 124 so the timer will overflow every 1 ms.
OCR0A = 0xF9; //sets TOP to 124 so the timer will overflow every 1 ms.
TIMSK0 |= (1<<OCIE0A); //Output Compare Match A Interrupt Enable
// sei(); //enable global interrupts
return;
}
int avr_ticks;
ISR(TIMER0_COMPA_vect)
{
cli();
/* Every ms: What TO DO */
clkhandler();
avr_ticks ++;
if (avr_ticks == 1000) {
/* PORTB ^= ( 1 << PORTB5 ); */
/* every second */
avr_ticks=0;
}
sei();
}

12
system/evec.c

@ -7,7 +7,7 @@ typedef unsigned int size_t;
#include <stdio.h>
uint32 __attribute__((aligned(0x100))) intc_vector[92]; /* Interrupt vector */
// RAFA uint32 __attribute__((aligned(0x100))) intc_vector[92]; /* Interrupt vector */
/* Each message corresponds to an exception in the vector table. */
char * exception_message(uint8 intnr) {
@ -106,10 +106,10 @@ __attribute__ ((naked)) void * dummy_isr(void) {
int32 initintc()
{
/* System control block */
struct scb_csreg *csrptr = (struct scb_csreg *)0xE000ED00;
// STM32 specific: struct scb_csreg *csrptr = (struct scb_csreg *)0xE000ED00;
/* clear entire IVT location in memory */
memset(&intc_vector, 0, (sizeof(uint32) * 92));
// RAFA memset(&intc_vector, 0, (sizeof(uint32) * 92));
/* set dummy handlers */
for (int i = 1; i <= 64 ; i++) {
@ -119,12 +119,12 @@ int32 initintc()
/* Enable memory management, bus and usage fault exceptions handlers
* If these are not enabled, the processor treats them as a hard
* faults. Unpriviliged access will cause a busfault in case no MPU */
csrptr->shcsr |= (1 << MPUFAULT_EN) | (1 << BUSFAULT_EN) | (1 << USAGEFAULT_EN);
// STM32 specific: srptr->shcsr |= (1 << MPUFAULT_EN) | (1 << BUSFAULT_EN) | (1 << USAGEFAULT_EN);
/* The vector table is intially at 0x0. The vector table can be
* relocated to other memory locations. We can do this by setting
* a register in the NVIC called the vector table offset register */
csrptr->vtor = (uint32) &intc_vector;
// RAFA // STM32 specific: srptr->vtor = (uint32) &intc_vector;
return OK;
}
@ -143,7 +143,7 @@ int32 set_evec(uint32 xnum, uint32 handler)
/* Install the handler */
intc_vector[xnum] = handler;
// STM32 specific: intc_vector[xnum] = handler;
return OK;
}

10
system/init.c

@ -14,13 +14,23 @@ syscall init(
struct dentry *devptr; /* Entry in device switch table */
int32 retval; /* Value to return to caller */
kprintf("8\n");
mask = disable();
kprintf("8\n");
if (isbaddev(descrp)) {
kprintf("7\n");
restore(mask);
kprintf("6\n");
return SYSERR;
}
kprintf("5\n");
devptr = (struct dentry *) &devtab[descrp];
kprintf("4\n");
retval = (*devptr->dvinit) (devptr);
kprintf("3\n");
restore(mask);
kprintf("8\n");
return retval;
}

13
system/initialize.c

@ -122,7 +122,7 @@ void nulluser()
uint32 free_mem; /* Total amount of free memory */
//RAFA
cli();
cli(); /* AVR disable interrups */
blink_avr();
// RAFA uartinit();
@ -133,6 +133,9 @@ void nulluser()
int c = atoi(&f);
serial_put_char('X');
serial_put_char(frase[c]);
serial_put_str(frase);
blink_avr();
blink_avr();
/* Initialize the system */
@ -172,6 +175,9 @@ void nulluser()
/* Initialize the real time clock */
clkinit();
//RAFA
kprintf("\nstartup %s\n\n", VERSION);
/* Start of nullprocess */
startup(0, prptr);
@ -219,10 +225,12 @@ static void sysinit()
kprintf(CONSOLE_RESET);
kprintf("\n%s\n\n", VERSION);
/* Initialize free memory list */
meminit();
/* Initialize system variables */
/* Count the Null process as the first process in the system */
@ -253,6 +261,7 @@ static void sysinit()
semptr->squeue = newqueue();
}
/* Initialize buffer pools */
bufinit();
@ -265,6 +274,8 @@ static void sysinit()
for (i = 0; i < NDEVS; i++) {
init(i);
}
return;
}

49
system/intr.S → system/intr.c

@ -1,4 +1,4 @@
/* Xinu for STM32
/* Xinu for AVR
*
* Original license applies
* Modifications for STM32 by Robin Krens
@ -14,47 +14,50 @@
/* intr.S - enable, disable, restore, halt, pause, (ARM) */
#include <cortexm3.h>
#include <xinu.h>
#include <avr/interrupt.h>
.text
.globl disable
.globl restore
.globl enable
.globl pause
.globl halt
/* RAFA: the arguments and returns do not have any meaning. It were there
* for STM32.
*
* For AVR: remove them some day
*/
/*------------------------------------------------------------------------
* disable - Disable interrupts and return the previous state
*------------------------------------------------------------------------
*/
disable:
// mrs r0, psr /* Copy the CPSR into r0 */
// cpsid i /* Disable interrupts */
// bx lr /* Return the CPSR */
intmask disable() {
cli();
return 0;
}
/*------------------------------------------------------------------------
* restore - Restore interrupts to value given by mask argument
Cortex M3 hardware handles a lot, rewrite
*------------------------------------------------------------------------
*/
restore:
// msr psr_nzcvq, r0 /* Restore the CPSR */
// cpsie i
// bx lr /* Return to caller */
inline void restore(intmask c) {
sei();
}
/*------------------------------------------------------------------------
* enable - Enable interrupts
*------------------------------------------------------------------------
*/
enable:
// cpsie i /* Enable interrupts */
// bx lr /* Return */
inline void enable() {
sei();
}
/*------------------------------------------------------------------------
* pause or halt - Place the processor in a hard loop
*------------------------------------------------------------------------
*/
halt:
pause:
// cpsid i /* Disable interrupts */
//dloop: b dloop /* Dead loop */
inline void halt() {
for (;;);
}
inline void pause() {
for (;;);
}

9
system/kprintf.c

@ -7,6 +7,8 @@
#include <xinu.h>
#include <stdarg.h>
#include <serial_avr.h>
/*------------------------------------------------------------------------
* kputc - use polled I/O to write a character to the console serial line
*------------------------------------------------------------------------
@ -16,16 +18,21 @@ syscall kputc(
)
{
intmask mask;
volatile struct uart_csreg * uptr = 0x40013800;
// STM32 specific: volatile struct uart_csreg * uptr = 0x40013800;
mask = disable();
if (c == '\n')
serial_put_char('\r');
serial_put_char(c);
/*
if (c == '\n') {
while(!(uptr->sr & UART_TC));
uptr->dr = 0x0D; // return line
}
while(!(uptr->sr & UART_TC));
uptr->dr = c;
*/
restore(mask);
return OK;

10
system/meminit.c

@ -21,12 +21,14 @@ void meminit(void)
/* Initialize the minheap and maxheap variables */
//RAFA AGREGO ESTO
int end = __bss_end + 1;
minheap = (void *)&end;
minheap = (void *)__bss_end+1;
maxheap = (void *)__bss_end+1024; /* 1KB for AVR */
// STM32 specific: minheap = (void *)&end;
/* 1024 bytes is reserved for supervise mode handling */
maxheap = (void *)MAXADDR - HANDLERSTACK;
// STM32 specific: maxheap = (void *)MAXADDR - HANDLERSTACK;
/* Initialize the memory list as one big block */

2
system/ptinit.c

@ -21,7 +21,7 @@ syscall ptinit(
ptfree = (struct ptnode *)getmem(maxmsgs*sizeof(struct ptnode));
if (ptfree == (struct ptnode *)SYSERR) {
panic("ptinit - insufficient memory");
panic(&m7[0]);
}
/* Initialize all port table entries to free */

75
system/serial_avr.c

@ -1,8 +1,6 @@
#include <xinu.h>
/* Completar la estructura de datos para que se superponga a los registros
del periferico de hardware del USART del atmega328, segun sugerido
en el apunte */
#include <avr/interrupt.h>
typedef struct
{
@ -22,7 +20,7 @@ typedef struct
// volatile uart_t *puerto_serial = (uart_t *) (0xc0);
char letra_start = 'R';
char cadena[100];
// char cadena[100];
#define F_CPU 16000000UL
@ -30,78 +28,58 @@ char cadena[100];
#define BAUD_PRESCALE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
#define INIT 0x06
#define EN_RX_TX 0x18
#define UART_RXCIE0 7
#define EN_TX 0x20
#define EN_RX 0x80
volatile uart_t *puerto_serial = (uart_t *) (0xc0);
void serial_init() {
/* Configurar los registros High y Low con BAUD_PRESCALE */
blink_avr();
/* Load .data segment into SRAM */
// extern uint32 * etext, data, edata;
// extern uint32 * _rom_data_begin;
// int size = (&edata - &data);
// memcpy(&data, &_rom_data_begin, size);
extern uint32_t __data;
extern uint32_t __data_end;
extern uint32_t __data_load;
extern uint32_t __bss;
extern uint32_t __bss_end;
extern uint32_t __vectors;
uint32_t *from = &__data_load;
uint32_t *to = &__data;
unsigned char b;
// Relocate .data section
// for (uint32_t *from = &__data_load, *to = &__data; to < &__data_end; from++, to++) {
// b = *from;
// *to = b;
//}
// Clear .bss
//for (uint32_t *to = &__bss; to < &__bss_end; to++)
//{
// *to = 0;
//}
volatile uart_t *puerto_serial = (uart_t *) (0xc0);
puerto_serial->baud_rate_h = (unsigned char) (BAUD_PRESCALE>>8);
puerto_serial->baud_rate_l = (unsigned char) (BAUD_PRESCALE);
/* Configurar un frame de 8bits, con un bit de paridad y bit de stop */
puerto_serial->status_control_c = (unsigned char)(INIT);
/* Activar la recepcion y transmicion */
puerto_serial->status_control_b = (unsigned char)(EN_RX_TX);
/* Activar la recepcion y transmicion e interrupcion de recepcion */
puerto_serial->status_control_b = (unsigned char)(EN_RX_TX | UART_RXCIE0);
/* test */
while(!((puerto_serial->status_control_a) & (EN_TX)));
// puerto_serial->data_es = letra_start;
puerto_serial->data_es = 'R';
}
/* enviar un byte a traves del del dispositivo inicializado */
void serial_put_char (char outputChar)
{
volatile uart_t *puerto_serial = (uart_t *) (0xc0);
while(!((puerto_serial->status_control_a) & (EN_TX)));
puerto_serial->data_es = outputChar;
}
char value;
/*
* RX interrupt service rutine
*/
ISR(USART_RX_vect){
cli();
value = UDR0; //read UART register into value
ttyhandler (1, value, 0);
sei();
}
char serial_get_char(void)
{
volatile uart_t *puerto_serial = (uart_t *) (0xc0);
/* Wait for the next character to arrive. */
while(!((puerto_serial->status_control_a) & (EN_RX)));
return (puerto_serial->data_es);
@ -115,16 +93,3 @@ void serial_put_str (char * mensaje)
};
}
char* serial_get_str(void)
{
int i = 0;
char l = serial_get_char();
while((l != '\r') && (l != '\n') && (l != '\0')){
cadena[i]=l;
i++;
l = serial_get_char();
};
cadena[i]='\0';/*agrega el fin de cadena*/
return cadena;
}

Loading…
Cancel
Save