From d1e84fb788b78d818eee9b5af904470bab510336 Mon Sep 17 00:00:00 2001 From: Ramtin Amin Date: Tue, 22 Nov 2016 12:10:11 -0600 Subject: [PATCH] Misoc: Add timer driver --- arch/misoc/src/common/misoc_serial.c | 32 +--- arch/misoc/src/common/misoc_timerisr.c | 140 ++++++++++++++ arch/misoc/src/lm32/Make.defs | 3 +- arch/misoc/src/lm32/lm32_reprioritizertr.c | 203 +++++++++++++++++++++ configs/misoc/hello/defconfig | 119 +++++++++++- 5 files changed, 464 insertions(+), 33 deletions(-) create mode 100644 arch/misoc/src/common/misoc_timerisr.c create mode 100644 arch/misoc/src/lm32/lm32_reprioritizertr.c diff --git a/arch/misoc/src/common/misoc_serial.c b/arch/misoc/src/common/misoc_serial.c index 9b15ba8e12..de914c8f61 100644 --- a/arch/misoc/src/common/misoc_serial.c +++ b/arch/misoc/src/common/misoc_serial.c @@ -205,13 +205,13 @@ static char g_uart1txbuffer[CONFIG_UART1_TXBUFSIZE]; static struct misoc_dev_s g_uart1priv = { - .uartbase = CSR_UART_BASE, - .irq = UART_INTERRUPT, - .rxtx_addr = CSR_UART_RXTX_ADDR, - .rxempty_addr = CSR_UART_RXEMPTY_ADDR, - .txfull_addr = CSR_UART_TXFULL_ADDR, - .ev_status_addr = CSR_UART_EV_STATUS_ADDR, - .ev_pending_addr = CSR_UART_EV_PENDING_ADDR, + .uartbase = CSR_UART_BASE, + .irq = UART_INTERRUPT, + .rxtx_addr = CSR_UART_RXTX_ADDR, + .rxempty_addr = CSR_UART_RXEMPTY_ADDR, + .txfull_addr = CSR_UART_TXFULL_ADDR, + .ev_status_addr = CSR_UART_EV_STATUS_ADDR, + .ev_pending_addr = CSR_UART_EV_PENDING_ADDR, .ev_enable_addr = CSR_UART_EV_ENABLE_ADDR, }; @@ -312,16 +312,9 @@ static void misoc_shutdown(struct uart_dev_s *dev) static int misoc_attach(struct uart_dev_s *dev) { struct misoc_dev_s *priv = (struct misoc_dev_s *)dev->priv; - uint32_t im; - irq_attach(priv->irq, misoc_uart_interrupt); - - /* enable interrupt */ - /* TODO: move that somewhere proper ! */ - - im = irq_getmask(); - im |= (1 << UART_INTERRUPT); - irq_setmask(im); + (void)irq_attach(priv->irq, misoc_uart_interrupt); + up_enable_irq(priv->irq); return OK; } @@ -339,13 +332,8 @@ static int misoc_attach(struct uart_dev_s *dev) static void misoc_detach(struct uart_dev_s *dev) { struct misoc_dev_s *priv = (struct misoc_dev_s *)dev->priv; - uint32_t im; - /* TODO: move that somewhere proper */ - - im = irq_getmask(); - im &= ~(1 << UART_INTERRUPT); - irq_setmask(im); + up_disable_irq(priv->irq); irq_detach(priv->irq); } diff --git a/arch/misoc/src/common/misoc_timerisr.c b/arch/misoc/src/common/misoc_timerisr.c new file mode 100644 index 0000000000..3ad75dccf7 --- /dev/null +++ b/arch/misoc/src/common/misoc_timerisr.c @@ -0,0 +1,140 @@ +/**************************************************************************** + * arch/risc-v/src/nr5m100/nr5_timerisr.c + * + * Copyright (C) 2009 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Modified for MISOC: + * + * Copyright (C) 2016 Ramtin Amin. All rights reserved. + * Author: Ramtin Amin + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "chip.h" +#include "misoc.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* The desired timer interrupt frequency is provided by the definition + * CLK_TCK (see include/time.h). CLK_TCK defines the desired number of + * system clock ticks per second. That value is a user configurable setting + * that defaults to 100 (100 ticks per second = 10 MS interval). + * + * The RCC feeds the Cortex System Timer (SysTick) with the AHB clock (HCLK) + * divided by 8. The SysTick can work either with this clock or with the + * Cortex clock (HCLK), configurable in the SysTick Control and Status + * register. + */ + +#define SYSTICK_RELOAD ((MISOC_CLK_FREQUENCY / CLOCKS_PER_SEC) - 1) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: up_timerisr + * + * Description: + * The timer ISR will perform a variety of services for various portions + * of the systems. + * + ****************************************************************************/ + +int up_timerisr(int irq, void *context) +{ + /* Clear event pending */ + + timer0_ev_pending_write(timer0_ev_pending_read()); + + /* Process timer interrupt */ + + sched_process_timer(); + return 0; +} + +/**************************************************************************** + * Function: up_timer_initialize + * + * Description: + * This function is called during start-up to initialize + * the timer interrupt. + * + ****************************************************************************/ + +void misoc_timer_initialize(void) +{ + uint32_t im; + + /* Clear event pending */ + + timer0_ev_pending_write(timer0_ev_pending_read()); + + /* Disable timer*/ + + timer0_en_write(0); + + /* FIX ME, PUT PROPER VALUE */ + + timer0_reload_write(80000); + timer0_load_write(80000); + + /* Enable timer */ + + timer0_en_write(1); + + /* Attach the timer interrupt vector */ + + (void)irq_attach(TIMER0_INTERRUPT, up_timerisr); + + /* And enable the timer interrupt */ + + up_enable_irq(TIMER0_INTERRUPT); + + /* Enable IRQ of the timer core */ + + timer0_ev_enable_write(1); +} diff --git a/arch/misoc/src/lm32/Make.defs b/arch/misoc/src/lm32/Make.defs index 9c0768b2a4..01a6702dcb 100644 --- a/arch/misoc/src/lm32/Make.defs +++ b/arch/misoc/src/lm32/Make.defs @@ -39,7 +39,7 @@ HEAD_ASRC = lm32_vectors.S CMN_ASRCS = CMN_CSRCS = misoc_lowputs.c misoc_serial.c misoc_mdelay.c CMN_CSRCS += misoc_modifyreg8.c misoc_modifyreg16.c misoc_modifyreg32.c -CMN_CSRCS += misoc_puts.c misoc_udelay.c +CMN_CSRCS += misoc_puts.c misoc_udelay.c misoc_timerisr.c CHIP_ASRCS = lm32_syscall.S @@ -49,3 +49,4 @@ CHIP_CSRCS += lm32_doirq.c lm32_dumpstate.c lm32_exit.c lm32_idle.c CHIP_CSRCS += lm32_initialize.c lm32_initialstate.c lm32_interruptcontext.c CHIP_CSRCS += lm32_irq.c lm32_releasepending.c lm32_releasestack.c CHIP_CSRCS += lm32_stackframe.c lm32_swint.c lm32_unblocktask.c +CHIP_CSRCS += lm32_reprioritizertr.c diff --git a/arch/misoc/src/lm32/lm32_reprioritizertr.c b/arch/misoc/src/lm32/lm32_reprioritizertr.c new file mode 100644 index 0000000000..e6b4261101 --- /dev/null +++ b/arch/misoc/src/lm32/lm32_reprioritizertr.c @@ -0,0 +1,203 @@ +/**************************************************************************** + * arch/misoc/src/lm32/lm32_reprioritizertr.c + * + * Copyright (C) 2016 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" +#include "lm32.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_reprioritize_rtr + * + * Description: + * Called when the priority of a running or + * ready-to-run task changes and the reprioritization will + * cause a context switch. Two cases: + * + * 1) The priority of the currently running task drops and the next + * task in the ready to run list has priority. + * 2) An idle, ready to run task's priority has been raised above the + * the priority of the current, running task and it now has the + * priority. + * + * Inputs: + * tcb: The TCB of the task that has been reprioritized + * priority: The new task priority + * + ****************************************************************************/ + +void up_reprioritize_rtr(struct tcb_s *tcb, uint8_t priority) +{ + /* Verify that the caller is sane */ + + if (tcb->task_state < FIRST_READY_TO_RUN_STATE || + tcb->task_state > LAST_READY_TO_RUN_STATE +#if SCHED_PRIORITY_MIN > 0 + || priority < SCHED_PRIORITY_MIN +#endif +#if SCHED_PRIORITY_MAX < UINT8_MAX + || priority > SCHED_PRIORITY_MAX +#endif + ) + { + PANIC(); + } + else + { + struct tcb_s *rtcb = this_task(); + bool switch_needed; + + sinfo("TCB=%p PRI=%d\n", tcb, priority); + + /* Remove the tcb task from the ready-to-run list. + * sched_removereadytorun will return true if we just + * remove the head of the ready to run list. + */ + + switch_needed = sched_removereadytorun(tcb); + + /* Setup up the new task priority */ + + tcb->sched_priority = (uint8_t)priority; + + /* Return the task to the specified blocked task list. + * sched_addreadytorun will return true if the task was + * added to the new list. We will need to perform a context + * switch only if the EXCLUSIVE or of the two calls is non-zero + * (i.e., one and only one the calls changes the head of the + * ready-to-run list). + */ + + switch_needed ^= sched_addreadytorun(tcb); + + /* Now, perform the context switch if one is needed */ + + if (switch_needed) + { + /* If we are going to do a context switch, then now is the right + * time to add any pending tasks back into the ready-to-run list. + * task list now + */ + + if (g_pendingtasks.head) + { + sched_mergepending(); + } + + /* Update scheduler parameters */ + + sched_suspend_scheduler(rtcb); + + /* Are we in an interrupt handler? */ + + if (g_current_regs) + { + /* Yes, then we have to do things differently. + * Just copy the g_current_regs into the OLD rtcb. + */ + + up_savestate(rtcb->xcp.regs); + + /* Restore the exception context of the rtcb at the (new) head + * of the ready-to-run task list. + */ + + rtcb = this_task(); + + /* Update scheduler parameters */ + + sched_resume_scheduler(rtcb); + + /* Then switch contexts. Any necessary address environment + * changes will be made when the interrupt returns. + */ + + up_restorestate(rtcb->xcp.regs); + } + + /* No, then we will need to perform the user context switch */ + + else + { + /* Switch context to the context of the task at the head of the + * ready to run list. + */ + + struct tcb_s *nexttcb = this_task(); + +#ifdef CONFIG_ARCH_ADDRENV + /* Make sure that the address environment for the previously + * running task is closed down gracefully (data caches dump, + * MMU flushed) and set up the address environment for the new + * thread at the head of the ready-to-run list. + */ + + (void)group_addrenv(nexttcb); +#endif + /* Update scheduler parameters */ + + sched_resume_scheduler(nexttcb); + + /* Then switch contexts */ + + up_switchcontext(rtcb->xcp.regs, nexttcb->xcp.regs); + + /* up_switchcontext forces a context switch to the task at the + * head of the ready-to-run list. It does not 'return' in the + * normal sense. When it does return, it is because the blocked + * task is again ready to run and has execution priority. + */ + } + } + } +} diff --git a/configs/misoc/hello/defconfig b/configs/misoc/hello/defconfig index dddddfd3ee..71aea364a7 100644 --- a/configs/misoc/hello/defconfig +++ b/configs/misoc/hello/defconfig @@ -221,7 +221,7 @@ CONFIG_PREALLOC_TIMERS=0 # CONFIG_INIT_NONE is not set CONFIG_INIT_ENTRYPOINT=y # CONFIG_INIT_FILEPATH is not set -CONFIG_USER_ENTRYPOINT="hello_main" +CONFIG_USER_ENTRYPOINT="nsh_main" CONFIG_RR_INTERVAL=0 # CONFIG_SCHED_SPORADIC is not set CONFIG_TASK_NAME_SIZE=0 @@ -263,9 +263,9 @@ CONFIG_NAME_MAX=32 # # Stack and heap information # -CONFIG_IDLETHREAD_STACKSIZE=512 -CONFIG_USERMAIN_STACKSIZE=512 -CONFIG_PTHREAD_STACK_MIN=256 +CONFIG_IDLETHREAD_STACKSIZE=1024 +CONFIG_USERMAIN_STACKSIZE=1024 +CONFIG_PTHREAD_STACK_MIN=512 CONFIG_PTHREAD_STACK_DEFAULT=1024 # CONFIG_LIB_SYSCALL is not set @@ -546,7 +546,7 @@ CONFIG_EXAMPLES_HELLO_STACKSIZE=2048 # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set # CONFIG_EXAMPLES_NRF24L01TERM is not set -# CONFIG_EXAMPLES_NSH is not set +CONFIG_EXAMPLES_NSH=y # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set @@ -555,7 +555,12 @@ CONFIG_EXAMPLES_HELLO_STACKSIZE=2048 # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set -# CONFIG_EXAMPLES_OSTEST is not set +CONFIG_EXAMPLES_OSTEST=y +CONFIG_EXAMPLES_OSTEST_LOOPS=1 +CONFIG_EXAMPLES_OSTEST_STACKSIZE=8192 +CONFIG_EXAMPLES_OSTEST_NBARRIER_THREADS=8 +CONFIG_EXAMPLES_OSTEST_RR_RANGE=10000 +CONFIG_EXAMPLES_OSTEST_RR_RUNS=10 # CONFIG_EXAMPLES_PCA9635 is not set # CONFIG_EXAMPLES_POSIXSPAWN is not set # CONFIG_EXAMPLES_PPPD is not set @@ -618,7 +623,97 @@ CONFIG_EXAMPLES_HELLO_STACKSIZE=2048 # # NSH Library # -# CONFIG_NSH_LIBRARY is not set +CONFIG_NSH_LIBRARY=y +# CONFIG_NSH_MOTD is not set + +# +# Command Line Configuration +# +# CONFIG_NSH_READLINE is not set +CONFIG_NSH_CLE=y +CONFIG_NSH_LINELEN=80 +# CONFIG_NSH_DISABLE_SEMICOLON is not set +CONFIG_NSH_MAXARGUMENTS=6 +CONFIG_NSH_ARGCAT=y +CONFIG_NSH_NESTDEPTH=3 +# CONFIG_NSH_DISABLEBG is not set + +# +# Disable Individual commands +# +# CONFIG_NSH_DISABLE_ADDROUTE is not set +# CONFIG_NSH_DISABLE_BASENAME is not set +# CONFIG_NSH_DISABLE_CAT is not set +# CONFIG_NSH_DISABLE_CD is not set +# CONFIG_NSH_DISABLE_CP is not set +# CONFIG_NSH_DISABLE_CMP is not set +CONFIG_NSH_DISABLE_DATE=y +# CONFIG_NSH_DISABLE_DD is not set +# CONFIG_NSH_DISABLE_DF is not set +# CONFIG_NSH_DISABLE_DELROUTE is not set +# CONFIG_NSH_DISABLE_DIRNAME is not set +# CONFIG_NSH_DISABLE_ECHO is not set +# CONFIG_NSH_DISABLE_EXEC is not set +# CONFIG_NSH_DISABLE_EXIT is not set +# CONFIG_NSH_DISABLE_FREE is not set +# CONFIG_NSH_DISABLE_GET is not set +# CONFIG_NSH_DISABLE_HELP is not set +# CONFIG_NSH_DISABLE_HEXDUMP is not set +CONFIG_NSH_DISABLE_IFCONFIG=y +CONFIG_NSH_DISABLE_IFUPDOWN=y +# CONFIG_NSH_DISABLE_KILL is not set +# CONFIG_NSH_DISABLE_LOSETUP is not set +CONFIG_NSH_DISABLE_LOSMART=y +# CONFIG_NSH_DISABLE_LS is not set +# CONFIG_NSH_DISABLE_MB is not set +# CONFIG_NSH_DISABLE_MKDIR is not set +# CONFIG_NSH_DISABLE_MKRD is not set +# CONFIG_NSH_DISABLE_MH is not set +# CONFIG_NSH_DISABLE_MOUNT is not set +# CONFIG_NSH_DISABLE_MV is not set +# CONFIG_NSH_DISABLE_MW is not set +CONFIG_NSH_DISABLE_PRINTF=y +CONFIG_NSH_DISABLE_PS=y +# CONFIG_NSH_DISABLE_PUT is not set +# CONFIG_NSH_DISABLE_PWD is not set +# CONFIG_NSH_DISABLE_RM is not set +# CONFIG_NSH_DISABLE_RMDIR is not set +# CONFIG_NSH_DISABLE_SET is not set +# CONFIG_NSH_DISABLE_SH is not set +# CONFIG_NSH_DISABLE_SLEEP is not set +# CONFIG_NSH_DISABLE_TIME is not set +# CONFIG_NSH_DISABLE_TEST is not set +# CONFIG_NSH_DISABLE_UMOUNT is not set +# CONFIG_NSH_DISABLE_UNAME is not set +# CONFIG_NSH_DISABLE_UNSET is not set +# CONFIG_NSH_DISABLE_USLEEP is not set +# CONFIG_NSH_DISABLE_WGET is not set +# CONFIG_NSH_DISABLE_XD is not set +CONFIG_NSH_MMCSDMINOR=0 + +# +# Configure Command Options +# +CONFIG_NSH_CMDOPT_DF_H=y +CONFIG_NSH_CODECS_BUFSIZE=128 +CONFIG_NSH_CMDOPT_HEXDUMP=y +CONFIG_NSH_FILEIOSIZE=1024 + +# +# Scripting Support +# +# CONFIG_NSH_DISABLESCRIPT is not set +# CONFIG_NSH_DISABLE_ITEF is not set +# CONFIG_NSH_DISABLE_LOOPS is not set + +# +# Console Configuration +# +CONFIG_NSH_CONSOLE=y +# CONFIG_NSH_ALTCONDEV is not set +# CONFIG_NSH_ARCHINIT is not set +# CONFIG_NSH_LOGIN is not set +# CONFIG_NSH_CONSOLE_LOGIN is not set # # NxWidgets/NxWM @@ -632,15 +727,19 @@ CONFIG_EXAMPLES_HELLO_STACKSIZE=2048 # # System Libraries and NSH Add-Ons # -# CONFIG_SYSTEM_CLE is not set +CONFIG_SYSTEM_CLE=y +CONFIG_SYSTEM_CLE_DEBUGLEVEL=0 # CONFIG_SYSTEM_CUTERM is not set # CONFIG_SYSTEM_FREE is not set # CONFIG_SYSTEM_HEX2BIN is not set # CONFIG_SYSTEM_HEXED is not set # CONFIG_SYSTEM_INSTALL is not set # CONFIG_SYSTEM_RAMTEST is not set -# CONFIG_READLINE_HAVE_EXTMATCH is not set -# CONFIG_SYSTEM_READLINE is not set +CONFIG_READLINE_HAVE_EXTMATCH=y +CONFIG_SYSTEM_READLINE=y +CONFIG_READLINE_ECHO=y +# CONFIG_READLINE_TABCOMPLETION is not set +# CONFIG_READLINE_CMD_HISTORY is not set # CONFIG_SYSTEM_SUDOKU is not set # CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set