fix bug in rt_hw_context_switch_interrupt_do

save sp to old thread
	clear rt_thread_switch_interrupt_flag
always enable interrupt after rt_hw_context_switch
judeg the type of interrupt in trap_entry, then call handler(Machine timer interrupt of Machine external interrupt)
This commit is contained in:
zhangjun 2017-07-30 19:46:28 +08:00
parent 2d56a27c20
commit b032dff161
6 changed files with 132 additions and 128 deletions

View File

@ -15,17 +15,16 @@ static void led_thread_entry(void* parameter)
unsigned int count=0;
rt_hw_led_init();
rt_kprintf("core freq at %d Hz\n", get_cpu_freq());
while (1)
{
/* led1 on */
#ifndef RT_USING_FINSH
/* rt_kprintf("led on, count : %d\r\n",count);*/
#endif
rt_kprintf("core freq at %d Hz\n", get_cpu_freq());
count++;
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);
/* rt_hw_led_on(0);*/
/* led1 off */
#ifndef RT_USING_FINSH
@ -33,10 +32,10 @@ static void led_thread_entry(void* parameter)
#endif
rt_hw_led_off(0);
rt_thread_delay( RT_TIMER_TICK_PER_SECOND*2);
/* rt_thread_delay( RT_TIMER_TICK_PER_SECOND*2);*/
}
}
static rt_uint8_t led_stack[ 2048 ];
static rt_uint8_t led_stack[ 1024];
static struct rt_thread led_thread;
void rt_application_init()
{

View File

@ -14,11 +14,6 @@ static struct mem_desc hw_mem_desc[] =
};
#endif
static void rt_systick_handler(int vector, void *param)
{
rt_tick_increase();
return;
}
#include <encoding.h>
static void rt_hw_timer_init(void)
{
@ -26,11 +21,12 @@ static void rt_hw_timer_init(void)
GPIO_REG(GPIO_OUTPUT_EN) |= ((0x1<< RED_LED_OFFSET)| (0x1<< GREEN_LED_OFFSET) | (0x1 << BLUE_LED_OFFSET)) ;
GPIO_REG(GPIO_OUTPUT_VAL) |= (0x1 << BLUE_LED_OFFSET) ;
GPIO_REG(GPIO_OUTPUT_VAL) &= ~((0x1<< RED_LED_OFFSET) | (0x1<< GREEN_LED_OFFSET)) ;
rt_hw_interrupt_enable(1);
CLINT_REG(CLINT_MTIME) = 0x0;
CLINT_REG(CLINT_MTIMECMP) = 0x10000;
/* enable timer interrupt*/
set_csr(mie, MIP_MTIP);
volatile uint64_t * mtimecmp = (uint64_t*) (CLINT_CTRL_ADDR + CLINT_MTIMECMP);
CLINT_REG(CLINT_MTIME) = 0x0;
/* CLINT_REG(CLINT_MTIMECMP) = 0x10000;*/
*mtimecmp = 0x20000;
return;
}

View File

@ -117,10 +117,6 @@ void rt_hw_led_on(int led)
// as the full brightness can be painful to look at.
PWM1_REG(PWM_CMP0) = 0;
*/
while(1){
if(r > 0 && b == 0){
r--;
g++;
@ -154,7 +150,6 @@ void rt_hw_led_on(int led)
_puts("FAIL\n\r");
}
}
}
}
return;
}

View File

@ -32,9 +32,21 @@
rt_hw_interrupt_disable:
addi sp, sp, -12
sw a5, (sp)
li a5, 0x800
csrr a0, mie
li a5, MIP_MEIP|MIP_MTIP|MIP_MSIP
/* csrrc a5, mstatus, MSTATUS_MIE*/
blt a0, a5, 1f
/* interrupt is enable before disable it*/
addi a0, a0, 1
li a5, 0x1
addi a5, a5, -2048
csrrc a5, mie, a5
/* csrrc a5, mie, 128*/
j 2f
/* interrupt is disabled before disable it*/
1:
li a0, 0
2:
lw a5, (sp)
addi sp, sp, 12
ret
@ -46,9 +58,12 @@ rt_hw_interrupt_disable:
rt_hw_interrupt_enable:
addi sp, sp, -12
sw a5, (sp)
li a5, MIP_MEIP|MIP_MTIP|MIP_MSIP
beqz a0, 1f
li a5, 0x1
addi a5, a5, -2048
csrrs a5, mie, a5
/* csrrsi a5, mstatus, MSTATUS_MIE*/
/* csrrs a5, mie, 128*/
1:
lw a5, (sp)
addi sp, sp, 12
ret
@ -98,8 +113,8 @@ rt_hw_context_switch:
*Remain in M-mode after mret
*enable interrupt in M-mode
*/
li t0, MSTATUS_MPIE|MSTATUS_MPP
csrs mstatus, t0
li t0, 136
csrrs t0, mstatus, t0
LOAD sp, (a1)
LOAD x30, 1*REGBYTES(sp)

View File

@ -187,26 +187,6 @@ extern void handle_m_ext_interrupt();
extern void handle_m_time_interrupt();
#endif
uintptr_t handle_trap(uintptr_t mcause, uintptr_t epc)
{
if (0){
#ifdef USE_PLIC
// External Machine-Level interrupt from PLIC
} else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_EXT)) {
handle_m_ext_interrupt();
#endif
#ifdef USE_M_TIME
// External Machine-Level interrupt from PLIC
} else if ((mcause & MCAUSE_INT) && ((mcause & MCAUSE_CAUSE) == IRQ_M_TIMER)){
handle_m_time_interrupt();
#endif
}
else {
write(1, "trap\n", 5);
_exit(1 + mcause);
}
return epc;
}
void _init()
{

View File

@ -36,7 +36,10 @@ _start:
la gp, __global_pointer$
.option pop
la sp, _sp
csrrsi a5, mstatus, 0
/*
*disable all interrupt at startup
*/
csrrc a5, mstatus, 0xb
#if defined(ENABLE_SMP)
smp_pause(t0, t1)
@ -69,6 +72,7 @@ _start:
la a0, __libc_fini_array
call atexit
call __libc_init_array
/*call _init directly in rt-thread*/
call _init
#ifndef __riscv_float_abi_soft
@ -175,17 +179,31 @@ trap_entry:
call rt_interrupt_enter
csrr a0, mcause
lui a5, 0x80000
not a5, a5
and a5, a5, a0
li a4, 11
mv s1, a1
/*Machine external interrupt*/
bne a5, a4, 1f
call rt_hw_trap_irq
call handle_m_time_interrupt
1:
/*Machine software interrupt*/
li a4, 7
bne a5, a4, 2f
call rt_systick_handler
2:
call rt_interrupt_leave
# Remain in M-mode after mret
li t0, 136
csrrs t0, mstatus, t0
la a0, rt_thread_switch_interrupt_flag
lw a1, (a0)
bnez a1, rt_hw_context_switch_interrupt_do
# Remain in M-mode after mret
li t0, MSTATUS_MPP
csrs mstatus, t0
LOAD x30, 1*REGBYTES(sp)
LOAD x31, 2*REGBYTES(sp)
@ -225,12 +243,13 @@ trap_entry:
mret
rt_hw_context_switch_interrupt_do:
/*clear rt_thread_switch_interrupt_flag*/
la a0, rt_thread_switch_interrupt_flag
lw a5, (a0)
li a5, 0
sw a5, (a0)
LOAD a0, rt_interrupt_from_thread
STORE sp, (a0)
LOAD a0, rt_interrupt_to_thread
LOAD sp, (a0)
LOAD x30, 1*REGBYTES(sp)