diff --git a/bsp/risc-v/applications/applications.c b/bsp/risc-v/applications/applications.c index b8adfe53eb..c26b4903d8 100644 --- a/bsp/risc-v/applications/applications.c +++ b/bsp/risc-v/applications/applications.c @@ -15,13 +15,7 @@ static void led_thread_entry(void* parameter) unsigned int count=0; rt_hw_led_init(); - - rt_hw_interrupt_enable(0x888); - set_csr(mstatus, MSTATUS_MIE); - asm( - "csrr a5, mie" - ); - rt_kprintf("core freq at %d Hz\n", get_cpu_freq()); + rt_kprintf("core freq at %d Hz\n", get_cpu_freq()); while (1) { /* led1 on */ @@ -29,7 +23,8 @@ static void led_thread_entry(void* parameter) /* rt_kprintf("led on, count : %d\r\n",count);*/ #endif count++; - rt_thread_delay( RT_TIMER_TICK_PER_SECOND*2 ); /* sleep 0.5 second and switch to other thread */ + rt_thread_delay( RT_TIMER_TICK_PER_SECOND/2 ); /* sleep 0.5 second and switch to other thread */ + while(1); rt_hw_led_on(0); /* led1 off */ @@ -41,7 +36,7 @@ static void led_thread_entry(void* parameter) rt_thread_delay( RT_TIMER_TICK_PER_SECOND*2); } } -static rt_uint8_t led_stack[ 512 ]; +static rt_uint8_t led_stack[ 2048 ]; static struct rt_thread led_thread; void rt_application_init() { diff --git a/bsp/risc-v/applications/startup.c b/bsp/risc-v/applications/startup.c index 59bf44c83b..efd344f5ad 100644 --- a/bsp/risc-v/applications/startup.c +++ b/bsp/risc-v/applications/startup.c @@ -30,7 +30,6 @@ static void rtthread_startup(void) rt_thread_idle_init(); /* start scheduler */ - while(1); rt_system_scheduler_start(); /* never reach here */ diff --git a/bsp/risc-v/drivers/board.c b/bsp/risc-v/drivers/board.c index 60a4de3baa..da324a83b1 100644 --- a/bsp/risc-v/drivers/board.c +++ b/bsp/risc-v/drivers/board.c @@ -31,7 +31,6 @@ static void rt_hw_timer_init(void) CLINT_REG(CLINT_MTIME) = 0x0; CLINT_REG(CLINT_MTIMECMP) = 0x10000; volatile uint64_t * mtimecmp = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP); - set_csr(mstatus, MSTATUS_MIE); *mtimecmp = 0x20000; return; } diff --git a/bsp/risc-v/drivers/led.c b/bsp/risc-v/drivers/led.c index eb2a9bfe09..900bb40f7d 100644 --- a/bsp/risc-v/drivers/led.c +++ b/bsp/risc-v/drivers/led.c @@ -74,6 +74,7 @@ static void _puts(const char * s) { void rt_hw_led_on(int led) { + /* // Make sure the HFROSC is on before the next line: PRCI_REG(PRCI_HFROSCCFG) |= ROSC_EN(1); // Run off 16 MHz Crystal for accuracy. Note that the @@ -82,17 +83,8 @@ void rt_hw_led_on(int led) PRCI_REG(PRCI_PLLCFG) |= (PLL_SEL(1)); // Turn off HFROSC to save power PRCI_REG(PRCI_HFROSCCFG) &= ~(ROSC_EN(1)); + */ - // Configure UART to print - GPIO_REG(GPIO_OUTPUT_VAL) |= IOF0_UART0_MASK; - GPIO_REG(GPIO_OUTPUT_EN) |= IOF0_UART0_MASK; - GPIO_REG(GPIO_IOF_SEL) &= ~IOF0_UART0_MASK; - GPIO_REG(GPIO_IOF_EN) |= IOF0_UART0_MASK; - - // 115200 Baud Rate - UART0_REG(UART_REG_DIV) = 138; - UART0_REG(UART_REG_TXCTRL) = UART_TXEN; - UART0_REG(UART_REG_RXCTRL) = UART_RXEN; // Wait a bit to avoid corruption on the UART. // (In some cases, switching to the IOF can lead @@ -107,7 +99,6 @@ void rt_hw_led_on(int led) //_puts(*((const char **) 0x100C)); //_puts("\n\r"); _puts(led_msg); - uint16_t r=0xFF; uint16_t g=0; uint16_t b=0; @@ -115,6 +106,7 @@ void rt_hw_led_on(int led) // Set up RGB PWM + /* PWM1_REG(PWM_CFG) = 0; // To balance the power consumption, make one left, one right, and one center aligned. PWM1_REG(PWM_CFG) = (PWM_CFG_ENALWAYS) | (PWM_CFG_CMP2CENTER); @@ -124,16 +116,10 @@ void rt_hw_led_on(int led) // the LEDs are intentionally left somewhat dim, // as the full brightness can be painful to look at. PWM1_REG(PWM_CMP0) = 0; + */ - GPIO_REG(GPIO_IOF_SEL) |= ( (1 << GREEN_LED_OFFSET) | (1 << BLUE_LED_OFFSET) | (1 << RED_LED_OFFSET)); - GPIO_REG(GPIO_IOF_EN ) |= ( (1 << GREEN_LED_OFFSET) | (1 << BLUE_LED_OFFSET) | (1 << RED_LED_OFFSET)); - GPIO_REG(GPIO_OUTPUT_XOR) &= ~( (1 << GREEN_LED_OFFSET) | (1 << BLUE_LED_OFFSET)); - GPIO_REG(GPIO_OUTPUT_XOR) |= (1 << RED_LED_OFFSET); while(1){ - volatile uint64_t * now = (volatile uint64_t*)(CLINT_CTRL_ADDR + CLINT_MTIME); - volatile uint64_t then = *now + 100; - while (*now < then) { } if(r > 0 && b == 0){ r--; diff --git a/bsp/risc-v/platform/interrupt.c b/bsp/risc-v/platform/interrupt.c index 7c980f23ae..b0ac8927b0 100644 --- a/bsp/risc-v/platform/interrupt.c +++ b/bsp/risc-v/platform/interrupt.c @@ -63,7 +63,7 @@ rt_uint32_t rt_hw_interrupt_get_active(rt_uint32_t fiq_irq) { //volatile rt_uint32_t irqstat; rt_uint32_t id; - return id; + return 0; } void rt_hw_interrupt_ack(rt_uint32_t fiq_irq, rt_uint32_t id) { diff --git a/bsp/risc-v/rtconfig.h b/bsp/risc-v/rtconfig.h index aa5669f736..46ac2ddf5d 100644 --- a/bsp/risc-v/rtconfig.h +++ b/bsp/risc-v/rtconfig.h @@ -17,9 +17,10 @@ /* SECTION: RT_DEBUG */ /* Thread Debug */ #define RT_DEBUG +#define RT_DEBUG_TIMER 1 /*#define RT_DEBUG_IRQ 1*/ -//#define SCHEDULER_DEBUG -/* #define RT_THREAD_DEBUG */ +#define RT_DEBUG_SCHEDULER 1 +#define RT_DEBUG_THREAD 1 #define RT_USING_OVERFLOW_CHECK @@ -31,7 +32,7 @@ /* Using Software Timer */ #define RT_USING_TIMER_SOFT #define RT_TIMER_THREAD_PRIO 8 -#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_TIMER_THREAD_STACK_SIZE 1024 #define RT_TIMER_TICK_PER_SECOND 10 /* SECTION: IPC */ @@ -91,7 +92,7 @@ /* Using symbol table */ #define FINSH_USING_SYMTAB #define FINSH_USING_DESCRIPTION -#define FINSH_THREAD_STACK_SIZE 4096 +#define FINSH_THREAD_STACK_SIZE 1024 #define FINSH_USING_MSH #define FINSH_USING_MSH_ONLY @@ -259,5 +260,5 @@ //#define RT_USING_CPU_FFS #define RT_USING_COMPONENTS_INIT -#define IDLE_THREAD_STACK_SIZE 512 +#define IDLE_THREAD_STACK_SIZE 1024 #endif diff --git a/libcpu/risc-v/e310/context_gcc.S b/libcpu/risc-v/e310/context_gcc.S index f92c80748d..ea2e205e4b 100644 --- a/libcpu/risc-v/e310/context_gcc.S +++ b/libcpu/risc-v/e310/context_gcc.S @@ -1,5 +1,5 @@ ;/* -; * File : context_iar.S +; * File : context_gcc.S ; * This file is part of RT-Thread RTOS ; * COPYRIGHT (C) 2006, RT-Thread Development Team ; * @@ -34,7 +34,6 @@ rt_hw_interrupt_disable: sw a5, (sp) csrr a0, mie li a5, MIP_MEIP|MIP_MTIP|MIP_MSIP - csrrc a5, mie, a5 /* csrrc a5, mstatus, MSTATUS_MIE*/ lw a5, (sp) addi sp, sp, 12 @@ -95,9 +94,11 @@ rt_hw_context_switch: STORE x1, 31*REGBYTES(sp) STORE x10, 29*REGBYTES(sp) STORE x1, 30*REGBYTES(sp) - - # Remain in M-mode after mret - li t0, MSTATUS_MPP +/* + *Remain in M-mode after mret + *enable interrupt in M-mode + */ + li t0, MSTATUS_MPIE|MSTATUS_MPP csrs mstatus, t0 LOAD sp, (a1) @@ -130,7 +131,7 @@ rt_hw_context_switch: LOAD x27, 27*REGBYTES(sp) LOAD x28, 28*REGBYTES(sp) LOAD x10, 31*REGBYTES(sp) - csrw mepc,a0 + csrw mepc,x10 LOAD x10, 29*REGBYTES(sp) LOAD x1, 30*REGBYTES(sp) @@ -194,16 +195,21 @@ rt_hw_context_switch_interrupt: sw s0, 12(sp) sw a0, 8(sp) sw a5, 4(sp) + la a0, rt_thread_switch_interrupt_flag - beqz a5, _reswitch + lw a5, (a0) + bnez a5, _reswitch li a5, 1 sw a5, (a0) + la a5, rt_interrupt_from_thread lw a0, 8(sp) sw a0, (a5) + _reswitch: la a5, rt_interrupt_to_thread sw a1, (a5) + lw a5, 4(sp) lw a0, 8(sp) lw s0, 12(sp) diff --git a/libcpu/risc-v/e310/start_gcc.S b/libcpu/risc-v/e310/start_gcc.S index d05ef7b8b2..b986f3f5e8 100644 --- a/libcpu/risc-v/e310/start_gcc.S +++ b/libcpu/risc-v/e310/start_gcc.S @@ -1,13 +1,32 @@ -// See LICENSE for license details. +;/* +; * File : start_gcc.S +; * This file is part of RT-Thread RTOS +; * COPYRIGHT (C) 2006, RT-Thread Development Team +; * +; * This program is free software; you can redistribute it and/or modify +; * it under the terms of the GNU General Public License as published by +; * the Free Software Foundation; either version 2 of the License, or +; * (at your option) any later version. +; * +; * This program is distributed in the hope that it will be useful, +; * but WITHOUT ANY WARRANTY; without even the implied warranty of +; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +; * GNU General Public License for more details. +; * +; * You should have received a copy of the GNU General Public License along +; * with this program; if not, write to the Free Software Foundation, Inc., +; * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +; * +; * Change Logs: +; * Date Author Notes +; * 2017-07-16 zhangjun for hifive1 +; */ #include - -/* This is defined in sifive/platform.h, but that can't be included from - * assembly. */ #define CLINT_CTRL_ADDR 0x02000000 - .section .init - .globl _start - .type _start,@function +.section .init +.globl _start +.type _start,@function _start: .cfi_startproc @@ -119,7 +138,7 @@ _start: .align 2 .global trap_entry trap_entry: - addi sp, sp, -32*REGBYTES + addi sp, sp, -32*REGBYTES STORE x30, 1*REGBYTES(sp) STORE x31, 2*REGBYTES(sp) @@ -151,8 +170,8 @@ trap_entry: STORE x28, 28*REGBYTES(sp) STORE x10, 29*REGBYTES(sp) STORE x1, 30*REGBYTES(sp) - csrr x1, mepc - STORE x1, 31*REGBYTES(sp) + csrr x10, mepc + STORE x10, 31*REGBYTES(sp) call rt_interrupt_enter @@ -162,7 +181,7 @@ trap_entry: la a0, rt_thread_switch_interrupt_flag lw a1, (a0) - beqz a1, rt_hw_context_switch_interrupt_do + bnez a1, rt_hw_context_switch_interrupt_do # Remain in M-mode after mret li t0, MSTATUS_MPP @@ -197,17 +216,23 @@ trap_entry: LOAD x27, 27*REGBYTES(sp) LOAD x28, 28*REGBYTES(sp) LOAD x10, 31*REGBYTES(sp) - csrw mepc, a0 + csrw mepc,x10 LOAD x10, 29*REGBYTES(sp) LOAD x1, 30*REGBYTES(sp) - addi sp, sp, 32*REGBYTES + addi sp, sp, 32*REGBYTES mret rt_hw_context_switch_interrupt_do: - LOAD a0, rt_interrupt_to_thread - LOAD sp, (a0) + + la a0, rt_thread_switch_interrupt_flag + lw a5, (a0) + li a5, 0 + sw a5, (a0) + + LOAD a0, rt_interrupt_to_thread + LOAD sp, (a0) LOAD x30, 1*REGBYTES(sp) LOAD x31, 2*REGBYTES(sp) LOAD x3, 3*REGBYTES(sp) @@ -237,10 +262,9 @@ rt_hw_context_switch_interrupt_do: LOAD x27, 27*REGBYTES(sp) LOAD x28, 28*REGBYTES(sp) LOAD x10, 31*REGBYTES(sp) - csrw mepc, a0 + csrw mepc,x10 LOAD x10, 29*REGBYTES(sp) LOAD x1, 30*REGBYTES(sp) - addi sp, sp, 32*REGBYTES mret diff --git a/src/idle.c b/src/idle.c deleted file mode 100644 index db87baa484..0000000000 --- a/src/idle.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * File : idle.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2012, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2006-03-23 Bernard the first version - * 2010-11-10 Bernard add cleanup callback function in thread exit. - * 2012-12-29 Bernard fix compiling warning. - * 2013-12-21 Grissiom let rt_thread_idle_excute loop until there is no - * dead thread. - * 2016-08-09 ArdaFu add method to get the handler of the idle thread. - */ - -#include -#include - -#if defined (RT_USING_HOOK) -#ifndef RT_USING_IDLE_HOOK -#define RT_USING_IDLE_HOOK -#endif -#endif - -#ifndef IDLE_THREAD_STACK_SIZE -#if defined (RT_USING_IDLE_HOOK) || defined(RT_USING_HEAP) -#define IDLE_THREAD_STACK_SIZE 256 -#else -#define IDLE_THREAD_STACK_SIZE 128 -#endif -#endif - -static struct rt_thread idle; -ALIGN(RT_ALIGN_SIZE) -static rt_uint8_t rt_thread_stack[IDLE_THREAD_STACK_SIZE]; - -extern rt_list_t rt_thread_defunct; - -#ifdef RT_USING_IDLE_HOOK -static void (*rt_thread_idle_hook)(); - -/** - * @ingroup Hook - * This function sets a hook function to idle thread loop. When the system performs - * idle loop, this hook function should be invoked. - * - * @param hook the specified hook function - * - * @note the hook function must be simple and never be blocked or suspend. - */ -void rt_thread_idle_sethook(void (*hook)(void)) -{ - rt_thread_idle_hook = hook; -} -#endif - -/* Return whether there is defunctional thread to be deleted. */ -rt_inline int _has_defunct_thread(void) -{ - /* The rt_list_isempty has prototype of "int rt_list_isempty(const rt_list_t *l)". - * So the compiler has a good reason that the rt_thread_defunct list does - * not change within rt_thread_idle_excute thus optimize the "while" loop - * into a "if". - * - * So add the volatile qualifier here. */ - const volatile rt_list_t *l = (const volatile rt_list_t*)&rt_thread_defunct; - - return l->next != l; -} - -/** - * @ingroup Thread - * - * This function will perform system background job when system idle. - */ -void rt_thread_idle_excute(void) -{ - /* Loop until there is no dead thread. So one call to rt_thread_idle_excute - * will do all the cleanups. */ - while (_has_defunct_thread()) - { - rt_base_t lock; - rt_thread_t thread; -#ifdef RT_USING_MODULE - rt_module_t module = RT_NULL; -#endif - RT_DEBUG_NOT_IN_INTERRUPT; - - /* disable interrupt */ - lock = rt_hw_interrupt_disable(); - - /* re-check whether list is empty */ - if (_has_defunct_thread()) - { - /* get defunct thread */ - thread = rt_list_entry(rt_thread_defunct.next, - struct rt_thread, - tlist); -#ifdef RT_USING_MODULE - /* get thread's parent module */ - module = (rt_module_t)thread->module_id; - - /* if the thread is module's main thread */ - if (module != RT_NULL && module->module_thread == thread) - { - /* detach module's main thread */ - module->module_thread = RT_NULL; - } -#endif - /* remove defunct thread */ - rt_list_remove(&(thread->tlist)); - /* invoke thread cleanup */ - if (thread->cleanup != RT_NULL) - thread->cleanup(thread); - - /* if it's a system object, not delete it */ - if (rt_object_is_systemobject((rt_object_t)thread) == RT_TRUE) - { - /* enable interrupt */ - rt_hw_interrupt_enable(lock); - - return; - } - } - else - { - /* enable interrupt */ - rt_hw_interrupt_enable(lock); - - /* may the defunct thread list is removed by others, just return */ - return; - } - - /* enable interrupt */ - rt_hw_interrupt_enable(lock); - -#ifdef RT_USING_HEAP -#if defined(RT_USING_MODULE) && defined(RT_USING_SLAB) - /* the thread belongs to an application module */ - if (thread->flags & RT_OBJECT_FLAG_MODULE) - rt_module_free((rt_module_t)thread->module_id, thread->stack_addr); - else -#endif - /* release thread's stack */ - RT_KERNEL_FREE(thread->stack_addr); - /* delete thread object */ - rt_object_delete((rt_object_t)thread); -#endif - -#ifdef RT_USING_MODULE - if (module != RT_NULL) - { - extern rt_err_t rt_module_destroy(rt_module_t module); - - /* if sub thread list and main thread are all empty */ - if ((module->module_thread == RT_NULL) && - rt_list_isempty(&module->module_object[RT_Object_Class_Thread].object_list)) - { - module->nref --; - } - - /* destroy module */ - if (module->nref == 0) - rt_module_destroy(module); - } -#endif - } -} - -static void rt_thread_idle_entry(void *parameter) -{ - while (1) - { - #ifdef RT_USING_IDLE_HOOK - if (rt_thread_idle_hook != RT_NULL) - { - rt_thread_idle_hook(); - } - #endif - - rt_thread_idle_excute(); - } -} - -/** - * @ingroup SystemInit - * - * This function will initialize idle thread, then start it. - * - * @note this function must be invoked when system init. - */ -void rt_thread_idle_init(void) -{ - /* initialize thread */ - rt_thread_init(&idle, - "tidle", - rt_thread_idle_entry, - RT_NULL, - &rt_thread_stack[0], - sizeof(rt_thread_stack), - RT_THREAD_PRIORITY_MAX - 1, - 32); - - /* startup */ - rt_thread_startup(&idle); -} - -/** - * @ingroup Thread - * - * This function will get the handler of the idle thread. - * - */ -rt_thread_t rt_thread_idle_gethandler(void) -{ - return (rt_thread_t)(&idle); -}