提交 b032dff1 编写于 作者: z13955633063's avatar z13955633063

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)
上级 2d56a27c
......@@ -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()
{
......
......@@ -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;
}
......
......@@ -75,87 +75,82 @@ 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
// first line is
PRCI_REG(PRCI_PLLCFG) = (PLL_REFSEL(1) | PLL_BYPASS(1));
PRCI_REG(PRCI_PLLCFG) |= (PLL_SEL(1));
// Turn off HFROSC to save power
PRCI_REG(PRCI_HFROSCCFG) &= ~(ROSC_EN(1));
*/
// Wait a bit to avoid corruption on the UART.
// (In some cases, switching to the IOF can lead
// to output glitches, so need to let the UART
// reciever time out and resynchronize to the real
// start of the stream.
volatile int i=0;
while(i < 10000){i++;}
_puts(sifive_msg);
//_puts("Config String:\n\r");
//_puts(*((const char **) 0x100C));
//_puts("\n\r");
_puts(led_msg);
uint16_t r=0xFF;
uint16_t g=0;
uint16_t b=0;
char c = 0;
// 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);
PWM1_REG(PWM_COUNT) = 0;
// Period is approximately 244 Hz
// the LEDs are intentionally left somewhat dim,
// as the full brightness can be painful to look at.
PWM1_REG(PWM_CMP0) = 0;
*/
while(1){
if(r > 0 && b == 0){
r--;
g++;
}
if(g > 0 && r == 0){
g--;
b++;
}
if(b > 0 && g == 0){
r++;
b--;
}
uint32_t G = g;
uint32_t R = r;
uint32_t B = b;
PWM1_REG(PWM_CMP1) = G << 4; // PWM is low on the left, GPIO is low on the left side, LED is ON on the left.
PWM1_REG(PWM_CMP2) = (B << 1) << 4; // PWM is high on the middle, GPIO is low in the middle, LED is ON in the middle.
PWM1_REG(PWM_CMP3) = 0xFFFF - (R << 4); // PWM is low on the left, GPIO is low on the right, LED is on on the right.
// Check for user input
if (c == 0){
if (_getc(&c) != 0){
_putc(c);
_puts("\n\r");
if ((c == 'y') || (c == 'Y')){
_puts("PASS\n\r");
} else{
_puts("FAIL\n\r");
}
}
}
}
// 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
// first line is
PRCI_REG(PRCI_PLLCFG) = (PLL_REFSEL(1) | PLL_BYPASS(1));
PRCI_REG(PRCI_PLLCFG) |= (PLL_SEL(1));
// Turn off HFROSC to save power
PRCI_REG(PRCI_HFROSCCFG) &= ~(ROSC_EN(1));
*/
// Wait a bit to avoid corruption on the UART.
// (In some cases, switching to the IOF can lead
// to output glitches, so need to let the UART
// reciever time out and resynchronize to the real
// start of the stream.
volatile int i=0;
while(i < 10000){i++;}
_puts(sifive_msg);
//_puts("Config String:\n\r");
//_puts(*((const char **) 0x100C));
//_puts("\n\r");
_puts(led_msg);
uint16_t r=0xFF;
uint16_t g=0;
uint16_t b=0;
char c = 0;
// 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);
PWM1_REG(PWM_COUNT) = 0;
// Period is approximately 244 Hz
// the LEDs are intentionally left somewhat dim,
// as the full brightness can be painful to look at.
PWM1_REG(PWM_CMP0) = 0;
*/
if(r > 0 && b == 0){
r--;
g++;
}
if(g > 0 && r == 0){
g--;
b++;
}
if(b > 0 && g == 0){
r++;
b--;
}
uint32_t G = g;
uint32_t R = r;
uint32_t B = b;
PWM1_REG(PWM_CMP1) = G << 4; // PWM is low on the left, GPIO is low on the left side, LED is ON on the left.
PWM1_REG(PWM_CMP2) = (B << 1) << 4; // PWM is high on the middle, GPIO is low in the middle, LED is ON in the middle.
PWM1_REG(PWM_CMP3) = 0xFFFF - (R << 4); // PWM is low on the left, GPIO is low on the right, LED is on on the right.
// Check for user input
if (c == 0){
if (_getc(&c) != 0){
_putc(c);
_puts("\n\r");
if ((c == 'y') || (c == 'Y')){
_puts("PASS\n\r");
} else{
_puts("FAIL\n\r");
}
}
}
return;
}
void rt_hw_led_off(int led)
......
......@@ -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)
......
......@@ -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()
{
......
......@@ -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
la a0, rt_thread_switch_interrupt_flag
lw a1, (a0)
# 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)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册