Fix IRQ-related bugs, fix serial read logic, add fgets
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@51 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
43f4608432
commit
89b91918d9
@ -95,8 +95,6 @@ void up_block_task(_TCB *tcb, tstate_t task_state)
|
||||
_TCB *rtcb = (_TCB*)g_readytorun.head;
|
||||
boolean switch_needed;
|
||||
|
||||
dbg("Blocking TCB=%p\n", tcb);
|
||||
|
||||
/* Remove the tcb task from the ready-to-run list. If we
|
||||
* are blocking the task at the head of the task list (the
|
||||
* most likely case), then a context switch to the next
|
||||
|
@ -74,6 +74,13 @@ void up_doirq(int irq, uint32* regs)
|
||||
#else
|
||||
if ((unsigned)irq < NR_IRQS)
|
||||
{
|
||||
/* Current regs non-zero indicates that we are processing
|
||||
* an interrupt; current_regs is also used to manage
|
||||
* interrupt level context switches.
|
||||
*/
|
||||
|
||||
current_regs = regs;
|
||||
|
||||
/* Mask and acknowledge the interrupt */
|
||||
|
||||
up_maskack_irq(irq);
|
||||
@ -82,8 +89,15 @@ void up_doirq(int irq, uint32* regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
/* Then unmask it */
|
||||
/* Indicate that we are no long in an interrupt handler */
|
||||
|
||||
current_regs = NULL;
|
||||
|
||||
/* Unmask the last interrupt (global interrupts are still
|
||||
* disabled.
|
||||
*/
|
||||
|
||||
current_regs = NULL;
|
||||
up_enable_irq(irq);
|
||||
}
|
||||
up_ledoff(LED_INIRQ);
|
||||
|
@ -521,7 +521,7 @@ static inline void up_givesem(sem_t *sem)
|
||||
* characters from the tail of the buffer.
|
||||
*/
|
||||
|
||||
static inline void up_recvchars(up_dev_t *dev)
|
||||
static void up_recvchars(up_dev_t *dev)
|
||||
{
|
||||
uint16 status;
|
||||
int nexthead = dev->recv.head + 1;
|
||||
@ -800,6 +800,32 @@ static void shutdown(up_dev_t * dev)
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* Name: up_irqwrite
|
||||
************************************************************/
|
||||
|
||||
static ssize_t up_irqwrite(up_dev_t *dev, const char *buffer, size_t buflen)
|
||||
{
|
||||
ssize_t ret = buflen;
|
||||
|
||||
/* Force each character through the low level interface */
|
||||
|
||||
for (; buflen; buflen--)
|
||||
{
|
||||
int ch = *buffer++;
|
||||
up_lowputc(ch);
|
||||
|
||||
/* If this is the console, then we should replace LF with LF-CR */
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
up_lowputc('\r');
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/************************************************************
|
||||
* Name: up_write
|
||||
************************************************************/
|
||||
@ -810,6 +836,23 @@ static ssize_t up_write(struct file *filep, const char *buffer, size_t buflen)
|
||||
up_dev_t *dev = inode->i_private;
|
||||
ssize_t ret = buflen;
|
||||
|
||||
/* We may receive console writes through this path from
|
||||
* interrupt handlers! In this case, we will need to do
|
||||
* things a little differently.
|
||||
*/
|
||||
|
||||
if (up_interrupt_context())
|
||||
{
|
||||
if (dev->isconsole)
|
||||
{
|
||||
return up_irqwrite(dev, buffer, buflen);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/* Only one user can be accessing dev->xmit.head at once */
|
||||
|
||||
up_takesem(&dev->xmit.sem);
|
||||
@ -827,10 +870,10 @@ static ssize_t up_write(struct file *filep, const char *buffer, size_t buflen)
|
||||
/* Put the character into the transmit buffer */
|
||||
|
||||
up_putxmitchar(dev, ch);
|
||||
|
||||
|
||||
/* If this is the console, then we should replace LF with LF-CR */
|
||||
|
||||
if (ch == '\n')
|
||||
if (dev->isconsole && ch == '\n')
|
||||
{
|
||||
up_putxmitchar(dev, '\r');
|
||||
}
|
||||
@ -895,7 +938,7 @@ static ssize_t up_read(struct file *filep, char *buffer, size_t buflen)
|
||||
}
|
||||
|
||||
up_enablerxint(dev);
|
||||
up_takesem(&dev->recv.sem);
|
||||
up_givesem(&dev->recv.sem);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user