for rt-thread 1.1.0

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2372 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
nongli1031@gmail.com 2012-10-26 03:36:13 +00:00
parent 2cdbbf8b05
commit 6fe2afed8c
11 changed files with 683 additions and 649 deletions

View File

@ -20,7 +20,7 @@
int rt_application_init() int rt_application_init()
{ {
return 0; return 0;
} }
/*@}*/ /*@}*/

View File

@ -11,7 +11,7 @@
* Date Author Notes * Date Author Notes
* 2006-08-23 Bernard first implementation * 2006-08-23 Bernard first implementation
* *
* 2011-12-17 nl1031 for MicroBlaze * 2011-12-17 nl1031 for MacroBlaze
* *
*/ */
@ -43,11 +43,14 @@
#endif #endif
/* Global Variables: */ /* Global Variables: */
XTmrCtr timer; /* The instance of the timer */ XTmrCtr timer; /* The instance of the timer */
XGpio gpio_output; /* The driver instance for GPIO Device configured as O/P */ XGpio gpio_output; /* The driver instance for GPIO Device configured as O/P */
XUartLite uart_lite; /* Instance of the UartLite device */ XUartLite uart_lite; /* Instance of the UartLite device */
XIntc int_ctl; /* The instance of the Interrupt Controller */ XIntc int_ctl; /* The instance of the Interrupt Controller */
static rt_uint32_t led_data; static rt_uint32_t led_data;
static int cnt;
static void rt_hw_board_led_init(void); static void rt_hw_board_led_init(void);
@ -56,22 +59,23 @@ static void rt_hw_board_led_init(void);
*/ */
static void rt_hw_board_led_init() static void rt_hw_board_led_init()
{ {
rt_uint32_t status; rt_uint32_t status;
led_data = 0; led_data = 0;
status = XGpio_Initialize(&gpio_output, LEDS_DEVICE_ID); cnt = 0;
if (status != XST_SUCCESS) status = XGpio_Initialize(&gpio_output, LEDS_DEVICE_ID);
{ if (status != XST_SUCCESS)
return; {
} return;
}
/* /*
* Set the direction for all signals to be outputs * Set the direction for all signals to be outputs
*/ */
XGpio_SetDataDirection(&gpio_output, 1, 0x0); XGpio_SetDataDirection(&gpio_output, 1, 0x0);
/* /*
* Set the GPIO outputs to high * Set the GPIO outputs to high
*/ */
XGpio_DiscreteWrite(&gpio_output, 1, 3); XGpio_DiscreteWrite(&gpio_output, 1, 3);
} }
/** /**
@ -81,8 +85,8 @@ static void rt_hw_board_led_init()
*/ */
void rt_hw_board_led_on(rt_uint32_t led) void rt_hw_board_led_on(rt_uint32_t led)
{ {
led_data |= led; led_data |= led;
XGpio_DiscreteWrite(&gpio_output, 1, led_data); XGpio_DiscreteWrite(&gpio_output, 1, led_data);
} }
/** /**
@ -92,21 +96,23 @@ void rt_hw_board_led_on(rt_uint32_t led)
*/ */
void rt_hw_board_led_off(rt_uint32_t led) void rt_hw_board_led_off(rt_uint32_t led)
{ {
led_data &= ~led; led_data &= ~led;
XGpio_DiscreteWrite(&gpio_output, 1, led_data); XGpio_DiscreteWrite(&gpio_output, 1, led_data);
} }
void rt_hw_led_flash(void) void rt_hw_led_flash(void)
{ {
rt_uint32_t i; volatile rt_uint32_t i;
rt_hw_board_led_off(1); rt_hw_board_led_off(1);
for (i = 0; i < 20000; i++) ; for (i = 0; i < 20000; i ++);
rt_hw_board_led_on(1); rt_hw_board_led_on(1);
for (i = 0; i < 20000; i++) ; for (i = 0; i < 20000; i ++);
} }
#ifdef RT_USING_CONSOLE #ifdef RT_USING_CONSOLE
/* /*
@ -120,107 +126,112 @@ void rt_hw_led_flash(void)
*/ */
void rt_hw_console_output(const char* str) void rt_hw_console_output(const char* str)
{ {
while (*str) while (*str)
{ {
/* Transmit Character */ /* Transmit Character */
XUartLite_SendByte(STDOUT_BASEADDRESS, *str);
if (*str == '\n') XUartLite_SendByte(STDOUT_BASEADDRESS, *str);
XUartLite_SendByte(STDOUT_BASEADDRESS, '\r'); if (*str == '\n')
str++; XUartLite_SendByte(STDOUT_BASEADDRESS, '\r');
} str++;
}
} }
static void rt_hw_console_init() static void rt_hw_console_init()
{ {
rt_uint32_t status; rt_uint32_t status;
/* /*
* Initialize the UartLite driver so that it is ready to use. * Initialize the UartLite driver so that it is ready to use.
*/ */
status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID); status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID);
if (status != XST_SUCCESS) if (status != XST_SUCCESS)
{ {
return; return;
} }
} }
#endif #endif
void rt_hw_timer_handler(void) void rt_hw_timer_handler(void)
{ {
rt_uint32_t csr; rt_uint32_t csr;
csr = XTmrCtr_ReadReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET); csr = XTmrCtr_ReadReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET);
/* /*
* Check if timer expired and interrupt occured * Check if timer expired and interrupt occured
*/ */
if (csr & XTC_CSR_INT_OCCURED_MASK) if (csr & XTC_CSR_INT_OCCURED_MASK)
{ {
rt_tick_increase(); rt_tick_increase();
XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET, csr | XTC_CSR_INT_OCCURED_MASK);
XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET, csr | XTC_CSR_INT_OCCURED_MASK); }
}
} }
/*
*********************************************************************************************************
* rt_intc_init()
*
* Description: This function intializes the interrupt controller by registering the appropriate handler
* functions and enabling interrupts.
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void rt_intc_init(void) /*
*********************************************************************************************************
* rt_intc_init()
*
* Description: This function intializes the interrupt controller by registering the appropriate handler
* functions and enabling interrupts.
*
* Arguments : None
*
* Returns : None
*********************************************************************************************************
*/
void rt_intc_init (void)
{ {
XStatus status; XStatus status;
XIntc_MasterDisable(XPAR_INTC_0_BASEADDR); XIntc_MasterDisable(XPAR_INTC_0_BASEADDR);
status = XIntc_Initialize(&int_ctl, XPAR_INTC_0_DEVICE_ID); status = XIntc_Initialize(&int_ctl, XPAR_INTC_0_DEVICE_ID);
/* install interrupt handler */ /* install interrupt handler */
rt_hw_interrupt_install(XPAR_INTC_0_TMRCTR_0_VEC_ID, (rt_isr_handler_t) rt_hw_timer_handler, RT_NULL); rt_hw_interrupt_install(XPAR_INTC_0_TMRCTR_0_VEC_ID, (rt_isr_handler_t)rt_hw_timer_handler, RT_NULL);
rt_hw_interrupt_umask(XPAR_INTC_0_TMRCTR_0_VEC_ID);
rt_hw_interrupt_umask(XPAR_INTC_0_TMRCTR_0_VEC_ID); XIntc_Start(&int_ctl, XIN_REAL_MODE);
XIntc_Start(&int_ctl, XIN_REAL_MODE);
} }
void rt_tmr_init(void)
void rt_tmr_init (void)
{ {
rt_uint32_t ctl; rt_uint32_t ctl;
XStatus status; XStatus status;
status = XTmrCtr_Initialize(&timer, XPAR_AXI_TIMER_0_DEVICE_ID);
XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TLR_OFFSET, PIV);
status = XTmrCtr_Initialize(&timer,XPAR_AXI_TIMER_0_DEVICE_ID);
XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TLR_OFFSET, PIV);
ctl = XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK; ctl = XTC_CSR_ENABLE_TMR_MASK | XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | XTC_CSR_DOWN_COUNT_MASK;
XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET, ctl); XTmrCtr_WriteReg(timer.BaseAddress, TIMER_CNTR_0, XTC_TCSR_OFFSET, ctl);
} }
/** /**
* This function will initial SPARTAN 6 LX9 board. * This function will initial SPARTAN 6 LX9 board.
*/ */
void rt_hw_board_init() void rt_hw_board_init()
{ {
/* init hardware console */ microblaze_disable_icache();
rt_hw_console_init(); microblaze_disable_dcache();
/* init hardware console */
rt_hw_console_init();
/* init led */ /* init led */
rt_hw_board_led_init(); rt_hw_board_led_init();
/* init intc */ /* init intc */
rt_intc_init(); rt_intc_init();
/* timer init */ /* timer init */
rt_tmr_init(); rt_tmr_init();
} }

View File

@ -13,6 +13,7 @@
#define __BOARD_H__ #define __BOARD_H__
#define MCK 50000000
void rt_hw_board_led_on(rt_uint32_t); void rt_hw_board_led_on(rt_uint32_t);
void rt_hw_board_led_off(rt_uint32_t); void rt_hw_board_led_off(rt_uint32_t);

View File

@ -16,6 +16,7 @@
/* Tick per Second*/ /* Tick per Second*/
#define RT_TICK_PER_SECOND 100 #define RT_TICK_PER_SECOND 100
/* SECTION: RT_DEBUG */ /* SECTION: RT_DEBUG */
/* Thread Debug*/ /* Thread Debug*/
/* #define RT_THREAD_DEBUG */ /* #define RT_THREAD_DEBUG */
@ -88,6 +89,7 @@
#define FINSH_THREAD_STACK_SIZE 8192 #define FINSH_THREAD_STACK_SIZE 8192
#define RT_USING_TC #define RT_USING_TC
/* SECTION: a runtime libc library */ /* SECTION: a runtime libc library */
/* a runtime libc library*/ /* a runtime libc library*/
/* #define RT_USING_NEWLIB */ /* #define RT_USING_NEWLIB */

View File

@ -25,6 +25,7 @@ extern void finsh_system_init(void);
extern void rt_hw_led_flash(void); extern void rt_hw_led_flash(void);
/*@{*/ /*@{*/
#ifdef __CC_ARM #ifdef __CC_ARM
extern int Image$$RW_IRAM1$$ZI$$Limit; extern int Image$$RW_IRAM1$$ZI$$Limit;
@ -36,7 +37,7 @@ extern unsigned char __bss_end;
#endif #endif
extern void rt_hw_interrupt_init(void); extern void rt_hw_interrupt_init(void);
extern int rt_application_init(void); extern int rt_application_init(void);
#ifdef RT_USING_DEVICE #ifdef RT_USING_DEVICE
extern rt_err_t rt_hw_serial_init(void); extern rt_err_t rt_hw_serial_init(void);
#endif #endif
@ -46,73 +47,74 @@ extern rt_err_t rt_hw_serial_init(void);
*/ */
void rtthread_startup(void) void rtthread_startup(void)
{ {
/* init hardware interrupt */ /* init hardware interrupt */
rt_hw_interrupt_init(); rt_hw_interrupt_init();
/* init board */ /* init board */
rt_hw_board_init(); rt_hw_board_init();
rt_show_version(); rt_show_version();
/* init tick */ /* init tick */
rt_system_tick_init(); rt_system_tick_init();
/* init kernel object */ /* init kernel object */
rt_system_object_init(); rt_system_object_init();
/* init timer system */ /* init timer system */
rt_system_timer_init(); rt_system_timer_init();
#ifdef RT_USING_HEAP #ifdef RT_USING_HEAP
#ifdef __CC_ARM #ifdef __CC_ARM
rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)0x204000); rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)0x204000);
#elif __ICCARM__ #elif __ICCARM__
rt_system_heap_init(__segment_end("HEAP"), (void*)0x204000); rt_system_heap_init(__segment_end("HEAP"), (void*)0x204000);
#else #else
rt_system_heap_init((void*) &__bss_end, (void*) (&__bss_end + 0x4000)); rt_system_heap_init((void*)&__bss_end, (void*)(&__bss_end+0x4000));
#endif #endif
#endif #endif
/* init scheduler system */ /* init scheduler system */
rt_system_scheduler_init(); rt_system_scheduler_init();
#ifdef RT_USING_HOOK /* if the hook is used */ #ifdef RT_USING_HOOK /* if the hook is used */
/* set idle thread hook */ /* set idle thread hook */
rt_thread_idle_sethook(rt_hw_led_flash); rt_thread_idle_sethook(rt_hw_led_flash);
#endif #endif
#ifdef RT_USING_DEVICE #ifdef RT_USING_DEVICE
/* init hardware serial device */ /* init hardware serial device */
rt_hw_serial_init(); rt_hw_serial_init();
/* init all device */ /* init all device */
rt_device_init_all(); rt_device_init_all();
#endif #endif
/* init application */ /* init application */
rt_application_init(); rt_application_init();
#ifdef RT_USING_FINSH #ifdef RT_USING_FINSH
/* init finsh */ /* init finsh */
finsh_system_init(); finsh_system_init();
finsh_set_device("uart1"); finsh_set_device("uart1");
#endif #endif
/* init idle thread */ /* init idle thread */
rt_thread_idle_init(); rt_thread_idle_init();
/* start scheduler */ /* start scheduler */
rt_system_scheduler_start(); rt_system_scheduler_start();
/* never reach here */ /* never reach here */
return; return ;
} }
int main(void) int main (void)
{ {
/* invoke rtthread_startup */ /* invoke rtthread_startup */
rtthread_startup(); rtthread_startup();
return 0; return 0;
} }
/*@}*/ /*@}*/

View File

@ -131,7 +131,7 @@ int _tc_thread_delete()
tc_cleanup(_tc_cleanup); tc_cleanup(_tc_cleanup);
thread_delete_init(); thread_delete_init();
return 25; return 27;
} }
FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example); FINSH_FUNCTION_EXPORT(_tc_thread_delete, a thread delete example);
#else #else

View File

@ -6,8 +6,8 @@ static struct rt_thread thread2;
static char thread1_stack[THREAD_STACK_SIZE]; static char thread1_stack[THREAD_STACK_SIZE];
static char thread2_stack[THREAD_STACK_SIZE]; static char thread2_stack[THREAD_STACK_SIZE];
static rt_uint32_t t1_count = 0; volatile static rt_uint32_t t1_count = 0;
static rt_uint32_t t2_count = 0; volatile static rt_uint32_t t2_count = 0;
static void thread1_entry(void* parameter) static void thread1_entry(void* parameter)
{ {
while (1) while (1)
@ -65,8 +65,12 @@ static void _tc_cleanup()
/* unlock scheduler */ /* unlock scheduler */
rt_exit_critical(); rt_exit_critical();
rt_kprintf("t1_count=%d t2_count=%d\n",t1_count,t2_count);
if (t1_count / t2_count != 2) if (t1_count / t2_count != 2)
tc_stat(TC_STAT_END | TC_STAT_FAILED); tc_stat(TC_STAT_END | TC_STAT_FAILED);
else
tc_done(TC_STAT_PASSED);
} }
int _tc_thread_same_priority() int _tc_thread_same_priority()

View File

@ -15,50 +15,48 @@
#include "microblaze.inc" #include "microblaze.inc"
.text .text
.globl rt_interrupt_enter .globl rt_interrupt_enter
.globl rt_interrupt_leave .globl rt_interrupt_leave
/* /*
* rt_base_t rt_hw_interrupt_disable() * rt_base_t rt_hw_interrupt_disable()
* copy from ucos-ii * copy from ucos-ii
*/ */
.globl rt_hw_interrupt_disable .globl rt_hw_interrupt_disable
.ent rt_hw_interrupt_disable .ent rt_hw_interrupt_disable
.align 2 .align 2
rt_hw_interrupt_disable: rt_hw_interrupt_disable:
ADDIK r1, r1, -4 ADDIK r1, r1, -4
SW r4, r1, r0 SW r4, r1, r0
MFS r3, RMSR MFS r3, RMSR
ANDNI r4, r3, IE_BIT ANDNI r4, r3, IE_BIT
MTS RMSR, r4 MTS RMSR, r4
LW r4, r1, r0 LW r4, r1, r0
ADDIK r1, r1, 4 ADDIK r1, r1, 4
AND r0, r0, r0 /* NO-OP - pipeline flush */ AND r0, r0, r0 /* NO-OP - pipeline flush */
AND r0, r0, r0 /* NO-OP - pipeline flush */ AND r0, r0, r0 /* NO-OP - pipeline flush */
AND r0, r0, r0 /* NO-OP - pipeline flush */ AND r0, r0, r0 /* NO-OP - pipeline flush */
RTSD r15, 8 RTSD r15, 8
AND r0, r0, r0 AND r0, r0, r0
.end rt_hw_interrupt_disable
.end rt_hw_interrupt_disable
/* /*
* void rt_hw_interrupt_enable(rt_base_t level) * void rt_hw_interrupt_enable(rt_base_t level)
* copy from ucos-ii * copy from ucos-ii
*/ */
.globl rt_hw_interrupt_enable .globl rt_hw_interrupt_enable
.ent rt_hw_interrupt_enable .ent rt_hw_interrupt_enable
.align 2 .align 2
rt_hw_interrupt_enable: rt_hw_interrupt_enable:
RTSD r15, 8 RTSD r15, 8
MTS rMSR, r5 /* Move the saved status from r5 into rMSR */ MTS rMSR, r5 /* Move the saved status from r5 into rMSR */
.end rt_hw_interrupt_enable
.end rt_hw_interrupt_enable
/* /*
* void rt_hw_context_switch(rt_uint32 from, rt_uint32 to) * void rt_hw_context_switch(rt_uint32 from, rt_uint32 to)
@ -66,163 +64,162 @@ rt_hw_interrupt_enable:
* r6 --> to * r6 --> to
*/ */
.globl rt_interrupt_from_thread .globl rt_interrupt_from_thread
.globl rt_interrupt_to_thread .globl rt_interrupt_to_thread
.globl rt_hw_context_switch .globl rt_hw_context_switch
.ent rt_hw_context_switch .ent rt_hw_context_switch
.align 2 .align 2
rt_hw_context_switch: rt_hw_context_switch:
PUSH_ALL PUSH_ALL
MFS r3, RMSR /* save the MSR */ MFS r3, RMSR /* save the MSR */
SWI r3, r1, STACK_RMSR SWI r3, r1, STACK_RMSR
SWI r1, r5, 0 /* store sp in preempted tasks TCB */ SWI r1, r5, 0 /* store sp in preempted tasks TCB */
LWI r1, r6, 0 /* get new task stack pointer */ LWI r1, r6, 0 /* get new task stack pointer */
LWI r3, r1, STACK_RMSR LWI r3, r1, STACK_RMSR
ANDI r3, r3, IE_BIT ANDI r3, r3, IE_BIT
BNEI r3, rt_hw_context_switch_ie /*if IE bit set,should be use RTID (return from interrupt). */ BNEI r3, rt_hw_context_switch_ie /*if IE bit set,should be use RTID (return from interrupt). */
LWI r3, r1, STACK_RMSR LWI r3, r1, STACK_RMSR
MTS RMSR, r3 MTS RMSR,r3
POP_ALL POP_ALL
ADDIK r1, r1, STACK_SIZE ADDIK r1, r1, STACK_SIZE
RTSD r15, 8 RTSD r15, 8
AND r0, r0, r0 AND r0, r0, r0
rt_hw_context_switch_ie: rt_hw_context_switch_ie:
LWI r3, r1, STACK_RMSR LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/ ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR, r3 MTS RMSR,r3
LWI r3, r1, STACK_R03 LWI r3, r1, STACK_R03
POP_ALL POP_ALL
ADDIK r1, r1, STACK_SIZE ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */ RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0 AND r0, r0, r0
.end rt_hw_context_switch
.end rt_hw_context_switch
/* /*
* void rt_hw_context_switch_to(rt_uint32 to) * void rt_hw_context_switch_to(rt_uint32 to)
* r5 --> to * r5 --> to
*/ */
.globl rt_hw_context_switch_to .globl rt_hw_context_switch_to
.ent rt_hw_context_switch_to .ent rt_hw_context_switch_to
.align 2 .align 2
rt_hw_context_switch_to: rt_hw_context_switch_to:
LWI r1, r5, 0 /* get new task stack pointer */ LWI r1, r5, 0 /* get new task stack pointer */
LWI r3, r1, STACK_RMSR LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/ ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR, r3 MTS RMSR,r3
POP_ALL POP_ALL
ADDIK r1, r1, STACK_SIZE ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */ RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0 AND r0, r0, r0
.end rt_hw_context_switch_to .end rt_hw_context_switch_to
/* /*
* void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to) * void rt_hw_context_switch_interrupt(rt_uint32 from, rt_uint32 to)
*/ */
.globl rt_thread_switch_interrupt_flag .globl rt_thread_switch_interrupt_flag
.globl rt_hw_context_switch_interrupt .globl rt_hw_context_switch_interrupt
.ent rt_hw_context_switch_interrupt .ent rt_hw_context_switch_interrupt
.align 2 .align 2
rt_hw_context_switch_interrupt: rt_hw_context_switch_interrupt:
LA r3, r0, rt_thread_switch_interrupt_flag LA r3, r0, rt_thread_switch_interrupt_flag
LWI r4, r3, 0 /* load rt_thread_switch_interrupt_flag into r4 */ LWI r4, r3, 0 /* load rt_thread_switch_interrupt_flag into r4 */
ANDI r4, r4, 1 ANDI r4, r4, 1
BNEI r4, _reswitch /* if rt_thread_switch_interrupt_flag = 1 */ BNEI r4, _reswitch /* if rt_thread_switch_interrupt_flag = 1 */
ADDIK r4, r0, 1 /* set rt_thread_switch_interrupt_flag to 1 */ ADDIK r4, r0, 1 /* set rt_thread_switch_interrupt_flag to 1 */
SWI r4, r3, 0 SWI r4, r3, 0
LA r3, r0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */ LA r3, r0, rt_interrupt_from_thread /* set rt_interrupt_from_thread */
SWI r5, r3, 0 /* rt_interrupt_from_thread = from */ SWI r5, r3, 0 /* rt_interrupt_from_thread = from */
_reswitch: _reswitch:
LA r3, r0, rt_interrupt_to_thread/* set rt_interrupt_to_thread */ LA r3, r0, rt_interrupt_to_thread /* set rt_interrupt_to_thread */
SWI r6, r3, 0 /* rt_interrupt_to_thread = to */ SWI r6, r3, 0 /* rt_interrupt_to_thread = to */
RTSD r15, 8 RTSD r15, 8
AND r0, r0, r0 AND r0, r0, r0
.end rt_hw_context_switch_interrupt
.end rt_hw_context_switch_interrupt
.globl _interrupt_handler .globl _interrupt_handler
.align 2 .section .text
.ent _interrupt_handler .align 2
.type _interrupt_handler, @function .ent _interrupt_handler
.type _interrupt_handler, @function
_interrupt_handler: _interrupt_handler:
PUSH_ALL PUSH_ALL
MFS r3, RMSR MFS r3, RMSR
ORI r3, r3, IE_BIT ORI r3, r3, IE_BIT
SWI r3, r1, STACK_RMSR /* push MSR */ SWI r3, r1, STACK_RMSR /* push MSR */
BRLID r15, rt_interrupt_enter BRLID r15, rt_interrupt_enter
AND r0, r0, r0 AND r0, r0, r0
BRLID r15, rt_hw_trap_irq BRLID r15, rt_hw_trap_irq
AND r0, r0, r0 AND r0, r0, r0
BRLID r15, rt_interrupt_leave BRLID r15, rt_interrupt_leave
AND r0, r0, r0 AND r0, r0, r0
/* /*
* if rt_thread_switch_interrupt_flag set, jump to * if rt_thread_switch_interrupt_flag set, jump to
* rt_hw_context_switch_interrupt_do and don't return * rt_hw_context_switch_interrupt_do and don't return
*/ */
LA r3, r0, rt_thread_switch_interrupt_flag LA r3, r0, rt_thread_switch_interrupt_flag
LWI r4, r3, 0 LWI r4, r3, 0
ANDI r4, r4, 1 ANDI r4, r4, 1
BNEI r4, rt_hw_context_switch_interrupt_do BNEI r4, rt_hw_context_switch_interrupt_do
LWI r3, r1, STACK_RMSR LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT ANDNI r3, r3, IE_BIT
MTS RMSR, r3 MTS RMSR,r3
POP_ALL POP_ALL
ADDIK r1, r1, STACK_SIZE ADDIK r1, r1, STACK_SIZE
RTID r14, 0 RTID r14, 0
AND r0, r0, r0 AND r0, r0, r0
/* /*
* void rt_hw_context_switch_interrupt_do(rt_base_t flag) * void rt_hw_context_switch_interrupt_do(rt_base_t flag)
*/ */
rt_hw_context_switch_interrupt_do: rt_hw_context_switch_interrupt_do:
SWI r0, r3, 0 /* clear rt_thread_switch_interrupt_flag */ SWI r0, r3, 0 /* clear rt_thread_switch_interrupt_flag */
LA r3, r0, rt_interrupt_from_thread LA r3, r0, rt_interrupt_from_thread
LW r4, r0, r3 LW r4, r0, r3
SWI r1, r4, 0 /* store sp in preempted tasks's TCB */ SWI r1, r4, 0 /* store sp in preempted tasks's TCB */
LA r3, r0, rt_interrupt_to_thread LA r3, r0, rt_interrupt_to_thread
LW r4, r0, r3 LW r4, r0, r3
LWI r1, r4, 0 /* get new task's stack pointer */ LWI r1, r4, 0 /* get new task's stack pointer */
LWI r3, r1, STACK_RMSR LWI r3, r1, STACK_RMSR
ANDI r3, r3, IE_BIT ANDI r3, r3, IE_BIT
BNEI r3, return_with_ie /*if IE bit set,should be use RTID (return from interrupt). */ BNEI r3, return_with_ie /*if IE bit set,should be use RTID (return from interrupt). */
LWI r3, r1, STACK_RMSR LWI r3, r1, STACK_RMSR
MTS RMSR, r3 MTS RMSR,r3
POP_ALL POP_ALL
ADDIK r1, r1, STACK_SIZE ADDIK r1, r1, STACK_SIZE
RTSD r15, 8 RTSD r15, 8
AND r0, r0, r0 AND r0, r0, r0
return_with_ie: return_with_ie:
LWI r3, r1, STACK_RMSR LWI r3, r1, STACK_RMSR
ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/ ANDNI r3, r3, IE_BIT /* clear IE bit, prevent interrupt occur immediately*/
MTS RMSR, r3 MTS RMSR,r3
LWI r3, r1, STACK_R03 LWI r3, r1, STACK_R03
POP_ALL POP_ALL
ADDIK r1, r1, STACK_SIZE ADDIK r1, r1, STACK_SIZE
RTID r14, 0 /* IE bit will be set automatically */ RTID r14, 0 /* IE bit will be set automatically */
AND r0, r0, r0 AND r0, r0, r0
.end _interrupt_handler .end _interrupt_handler

View File

@ -22,23 +22,23 @@
typedef volatile rt_uint32_t REG32; typedef volatile rt_uint32_t REG32;
struct rt_mb_uart_lite_hw struct rt_mb_uart_lite_hw
{ {
REG32 Rx_FIFO; // Receiver Holding Register REG32 Rx_FIFO; // Receiver Holding Register
REG32 Tx_FIFO; // Transmitter Holding Register REG32 Tx_FIFO; // Transmitter Holding Register
REG32 STAT_REG; // Channel Status Register REG32 STAT_REG; // Channel Status Register
REG32 CTRL_REG; // Control Register REG32 CTRL_REG; // Control Register
}; };
struct rt_mb_uart_lite struct rt_mb_uart_lite
{ {
struct rt_device parent; struct rt_device parent;
struct rt_mb_uart_lite_hw* hw_base; struct rt_mb_uart_lite_hw* hw_base;
rt_uint16_t peripheral_id; rt_uint16_t peripheral_id;
rt_uint32_t baudrate; rt_uint32_t baudrate;
/* reception field */ /* reception field */
rt_uint16_t save_index, read_index; rt_uint16_t save_index, read_index;
rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE]; rt_uint8_t rx_buffer[RT_UART_RX_BUFFER_SIZE];
}; };
#ifdef RT_USING_UART1 #ifdef RT_USING_UART1
struct rt_mb_uart_lite serial1; struct rt_mb_uart_lite serial1;
@ -46,263 +46,271 @@ struct rt_mb_uart_lite serial1;
static void rt_hw_serial_isr(void) static void rt_hw_serial_isr(void)
{ {
unsigned int status; unsigned int status;
rt_base_t level; rt_base_t level;
struct rt_device* device; struct rt_device* device;
struct rt_mb_uart_lite* serial = RT_NULL; struct rt_mb_uart_lite* serial = RT_NULL;
#ifdef RT_USING_UART1 #ifdef RT_USING_UART1
/* serial 1 */ /* serial 1 */
serial = &serial1; serial = &serial1;
#endif #endif
RT_ASSERT(serial != RT_NULL); RT_ASSERT(serial != RT_NULL);
/* get generic device object */ /* get generic device object */
device = (rt_device_t) serial; device = (rt_device_t)serial;
/* disable interrupt */ /* disable interrupt */
level = rt_hw_interrupt_disable(); level = rt_hw_interrupt_disable();
/* get uart status register */ /* get uart status register */
status = serial->hw_base->STAT_REG; status = serial->hw_base->STAT_REG;
while (status & XUL_SR_RX_FIFO_VALID_DATA) while (status & XUL_SR_RX_FIFO_VALID_DATA)
{ {
/* get received character */ /* get received character */
serial->rx_buffer[serial->save_index] = serial->hw_base->Rx_FIFO; serial->rx_buffer[serial->save_index] = serial->hw_base->Rx_FIFO;
/* move to next position */ /* move to next position */
serial->save_index++; serial->save_index ++;
if (serial->save_index >= RT_UART_RX_BUFFER_SIZE) if (serial->save_index >= RT_UART_RX_BUFFER_SIZE)
serial->save_index = 0; serial->save_index = 0;
/* if the next position is read index, discard this 'read char' */ /* if the next position is read index, discard this 'read char' */
if (serial->save_index == serial->read_index) if (serial->save_index == serial->read_index)
{ {
serial->read_index++; serial->read_index ++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE) if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0; serial->read_index = 0;
} }
status = serial->hw_base->STAT_REG; status = serial->hw_base->STAT_REG;
} }
/* enable interrupt */ /* enable interrupt */
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
/* indicate to upper layer application */ /* indicate to upper layer application */
if (device->rx_indicate != RT_NULL) if (device->rx_indicate != RT_NULL)
device->rx_indicate(device, 1); device->rx_indicate(device, 1);
} }
static rt_err_t rt_serial_init(rt_device_t dev) static rt_err_t rt_serial_init (rt_device_t dev)
{ {
struct rt_mb_uart_lite* serial = (struct rt_mb_uart_lite*) dev; struct rt_mb_uart_lite* serial = (struct rt_mb_uart_lite*) dev;
RT_ASSERT(serial != RT_NULL); RT_ASSERT(serial != RT_NULL);
RT_ASSERT(serial->peripheral_id != XPAR_INTC_0_UARTLITE_1_VEC_ID); RT_ASSERT(serial->peripheral_id != XPAR_UARTLITE_1_DEVICE_ID);
/* reset rx index */
serial->save_index = 0;
serial->read_index = 0;
/* reset rx buffer */ /* reset rx index */
rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE); serial->save_index = 0;
serial->read_index = 0;
return RT_EOK; /* reset rx buffer */
rt_memset(serial->rx_buffer, 0, RT_UART_RX_BUFFER_SIZE);
return RT_EOK;
} }
static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag) static rt_err_t rt_serial_open(rt_device_t dev, rt_uint16_t oflag)
{ {
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*) dev; struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
RT_ASSERT(serial != RT_NULL); RT_ASSERT(serial != RT_NULL);
if (dev->flag & RT_DEVICE_FLAG_INT_RX) if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{ {
/* enable UART rx interrupt */ /* enable UART rx interrupt */
serial->hw_base->CTRL_REG = XUL_CR_ENABLE_INTR; /* enable interrupt */ serial->hw_base->CTRL_REG = XUL_CR_ENABLE_INTR; /* enable interrupt */
/* install UART handler */ /* install UART handler */
rt_hw_interrupt_install(serial->peripheral_id, (rt_isr_handler_t) rt_hw_serial_isr, RT_NULL); rt_hw_interrupt_install(serial->peripheral_id, (rt_isr_handler_t)rt_hw_serial_isr, RT_NULL);
rt_hw_interrupt_umask(serial->peripheral_id); rt_hw_interrupt_umask(serial->peripheral_id);
} }
return RT_EOK; return RT_EOK;
} }
static rt_err_t rt_serial_close(rt_device_t dev) static rt_err_t rt_serial_close(rt_device_t dev)
{ {
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*) dev; struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
RT_ASSERT(serial != RT_NULL); RT_ASSERT(serial != RT_NULL);
if (dev->flag & RT_DEVICE_FLAG_INT_RX) if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{ {
/* disable interrupt */ /* disable interrupt */
serial->hw_base->CTRL_REG = 0; /* RxReady interrupt */ serial->hw_base->CTRL_REG = 0; /* RxReady interrupt */
} }
return RT_EOK; return RT_EOK;
} }
static rt_size_t rt_serial_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) static rt_size_t rt_serial_read (rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{ {
rt_uint8_t* ptr; rt_uint8_t* ptr;
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*) dev; struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
RT_ASSERT(serial != RT_NULL); RT_ASSERT(serial != RT_NULL);
/* point to buffer */ /* point to buffer */
ptr = (rt_uint8_t*) buffer; ptr = (rt_uint8_t*) buffer;
if (dev->flag & RT_DEVICE_FLAG_INT_RX) if (dev->flag & RT_DEVICE_FLAG_INT_RX)
{ {
while (size) while (size)
{ {
/* interrupt receive */ /* interrupt receive */
rt_base_t level; rt_base_t level;
/* disable interrupt */ /* disable interrupt */
level = rt_hw_interrupt_disable(); level = rt_hw_interrupt_disable();
if (serial->read_index != serial->save_index) if (serial->read_index != serial->save_index)
{ {
*ptr = serial->rx_buffer[serial->read_index]; *ptr = serial->rx_buffer[serial->read_index];
serial->read_index++; serial->read_index ++;
if (serial->read_index >= RT_UART_RX_BUFFER_SIZE) if (serial->read_index >= RT_UART_RX_BUFFER_SIZE)
serial->read_index = 0; serial->read_index = 0;
} else }
{ else
/* no data in rx buffer */ {
/* no data in rx buffer */
/* enable interrupt */ /* enable interrupt */
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
break; break;
} }
/* enable interrupt */ /* enable interrupt */
rt_hw_interrupt_enable(level); rt_hw_interrupt_enable(level);
ptr++; ptr ++; size --;
size--; }
}
return (rt_uint32_t) ptr - (rt_uint32_t) buffer; return (rt_uint32_t)ptr - (rt_uint32_t)buffer;
} else if (dev->flag & RT_DEVICE_FLAG_DMA_RX) }
{ else if (dev->flag & RT_DEVICE_FLAG_DMA_RX)
/* not support right now */ {
RT_ASSERT(0); /* not support right now */
} else RT_ASSERT(0);
{ }
/* poll mode */ else
while (size) {
{ /* poll mode */
/* Wait for Full Rx Buffer */ while (size)
while (!(serial->hw_base->STAT_REG & XUL_SR_RX_FIFO_VALID_DATA)) {
; /* Wait for Full Rx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_RX_FIFO_VALID_DATA));
/* Read Character */ /* Read Character */
*ptr = serial->hw_base->Rx_FIFO; *ptr = serial->hw_base->Rx_FIFO;
ptr++; ptr ++;
size--; size --;
} }
return (rt_size_t) ptr - (rt_size_t) buffer; return (rt_size_t)ptr - (rt_size_t)buffer;
} }
return 0; return 0;
} }
static rt_size_t rt_serial_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) static rt_size_t rt_serial_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
{ {
rt_uint8_t* ptr; rt_uint8_t* ptr;
struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*) dev; struct rt_mb_uart_lite *serial = (struct rt_mb_uart_lite*)dev;
RT_ASSERT(serial != RT_NULL); RT_ASSERT(serial != RT_NULL);
ptr = (rt_uint8_t*) buffer; ptr = (rt_uint8_t*) buffer;
if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY) if (dev->open_flag & RT_DEVICE_OFLAG_WRONLY)
{ {
if (dev->flag & RT_DEVICE_FLAG_STREAM) if (dev->flag & RT_DEVICE_FLAG_STREAM)
{ {
/* it's a stream mode device */ /* it's a stream mode device */
while (size) while (size)
{ {
/* stream mode */ /* stream mode */
if (*ptr == '\n') if (*ptr == '\n')
{ {
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY)) while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
; serial->hw_base->Tx_FIFO = '\r';
serial->hw_base->Tx_FIFO = '\r'; }
}
/* Wait for Empty Tx Buffer */ /* Wait for Empty Tx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY)) ; while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
/* Transmit Character */ /* Transmit Character */
serial->hw_base->Tx_FIFO = *ptr; serial->hw_base->Tx_FIFO = *ptr;
ptr++; if (*ptr & 1)
size--; rt_hw_board_led_on(2);
} else
} rt_hw_board_led_off(2);
else ptr ++; size --;
{ }
while (size) }
{ else
/* Wait for Empty Tx Buffer */ {
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY)) while (size)
; {
/* Wait for Empty Tx Buffer */
while (!(serial->hw_base->STAT_REG & XUL_SR_TX_FIFO_EMPTY));
/* Transmit Character */ /* Transmit Character */
serial->hw_base->Tx_FIFO = *ptr; serial->hw_base->Tx_FIFO = *ptr;
ptr++; if (*ptr & 1)
size--; rt_hw_board_led_on(2);
} else
} rt_hw_board_led_off(2);
} ptr ++; size --;
}
}
}
return (rt_size_t) ptr - (rt_size_t) buffer; return (rt_size_t)ptr - (rt_size_t)buffer;
} }
static rt_err_t rt_serial_control(rt_device_t dev, rt_uint8_t cmd, void *args) static rt_err_t rt_serial_control (rt_device_t dev, rt_uint8_t cmd, void *args)
{ {
return RT_EOK; return RT_EOK;
} }
rt_err_t rt_hw_serial_init() rt_err_t rt_hw_serial_init()
{ {
rt_device_t device; rt_device_t device;
#ifndef RT_USING_CONSOLE #ifndef RT_USING_CONSOLE
int Status; int Status;
/* /*
* Initialize the UartLite driver so that it is ready to use. * Initialize the UartLite driver so that it is ready to use.
*/ */
Status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID); Status = XUartLite_Initialize(&uart_lite, RS232_DEVICE_ID);
if (Status != XST_SUCCESS) if (Status != XST_SUCCESS)
{ {
return; return;
} }
#endif #endif
#ifdef RT_USING_UART1 #ifdef RT_USING_UART1
device = (rt_device_t) &serial1; device = (rt_device_t) &serial1;
/* init serial device private data */ /* init serial device private data */
serial1.hw_base = (struct rt_mb_uart_lite_hw*) XPAR_USB_UART_BASEADDR; serial1.hw_base = (struct rt_mb_uart_lite_hw*)XPAR_USB_UART_BASEADDR;
serial1.peripheral_id = XPAR_INTC_0_UARTLITE_1_VEC_ID; serial1.peripheral_id = XPAR_UARTLITE_1_DEVICE_ID;
serial1.baudrate = 9600; serial1.baudrate = 115200;
/* set device virtual interface */ /* set device virtual interface */
device->init = rt_serial_init; device->init = rt_serial_init;
device->open = rt_serial_open; device->open = rt_serial_open;
device->close = rt_serial_close; device->close = rt_serial_close;
device->read = rt_serial_read; device->read = rt_serial_read;
device->write = rt_serial_write; device->write = rt_serial_write;
device->control = rt_serial_control; device->control = rt_serial_control;
/* register uart1 on device subsystem */ /* register uart1 on device subsystem */
rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX); rt_device_register(device, "uart1", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
#endif #endif
return RT_EOK;
return RT_EOK;
} }

View File

@ -13,8 +13,10 @@
* *
*/ */
#include <rtthread.h> #include <rtthread.h>
extern void *_SDA_BASE_; extern void *_SDA_BASE_;
extern void *_SDA2_BASE_; extern void *_SDA2_BASE_;
/** /**
* This function will initialize thread stack * This function will initialize thread stack
@ -26,43 +28,44 @@ extern void *_SDA2_BASE_;
* *
* @return stack address * @return stack address
*/ */
rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter, rt_uint8_t *stack_addr, void *texit) rt_uint8_t *rt_hw_stack_init(void *tentry, void *parameter,
rt_uint8_t *stack_addr, void *texit)
{ {
unsigned long *stk; unsigned long *stk;
stk = (unsigned long *) stack_addr; stk = (unsigned long *)stack_addr;
stk--; stk--;
stk--; stk--;
*stk-- = 0; /* r31 */ *stk-- = 0; /* r31 */
*stk-- = 0; /* r30 */ *stk-- = 0; /* r30 */
*stk-- = 0; /* r29 */ *stk-- = 0; /* r29 */
*stk-- = 0; /* r28 */ *stk-- = 0; /* r28 */
*stk-- = 0; /* r27 */ *stk-- = 0; /* r27 */
*stk-- = 0; /* r26 */ *stk-- = 0; /* r26 */
*stk-- = 0; /* r25 */ *stk-- = 0; /* r25 */
*stk-- = 0; /* r24 */ *stk-- = 0; /* r24 */
*stk-- = 0; /* r23 */ *stk-- = 0; /* r23 */
*stk-- = 0; /* r22 */ *stk-- = 0; /* r22 */
*stk-- = 0; /* r21 */ *stk-- = 0; /* r21 */
*stk-- = 0; /* r20 */ *stk-- = 0; /* r20 */
*stk-- = 0; /* r19 */ *stk-- = 0; /* r19 */
*stk-- = 0; /* r18 */ *stk-- = 0; /* r18 */
*stk-- = 0; /* r17 */ *stk-- = 0; /* r17 */
*stk-- = (unsigned long) texit - 8; /* r15 = task return address*/ *stk-- = (unsigned long)texit - 8; /* r15 = task return address*/
*stk-- = (unsigned long) tentry; /* r14 = entry address*/ *stk-- = (unsigned long)tentry; /* r14 = entry address*/
*stk-- = (unsigned long) &_SDA_BASE_; /* r13 */ *stk-- = (unsigned long)&_SDA_BASE_; /* r13 */
*stk-- = 0; /* r12 */ *stk-- = 0; /* r12 */
*stk-- = 0; /* r11 */ *stk-- = 0; /* r11 */
*stk-- = 0; /* r10 */ *stk-- = 0; /* r10 */
*stk-- = 0; /* r09 */ *stk-- = 0; /* r09 */
*stk-- = 0; /* r08 */ *stk-- = 0; /* r08 */
*stk-- = 0; /* r07 */ *stk-- = 0; /* r07 */
*stk-- = 0; /* r06 */ *stk-- = 0; /* r06 */
*stk-- = (unsigned long) parameter; /* r05 */ *stk-- = (unsigned long) parameter; /* r05 */
*stk-- = 0; /* r04 */ *stk-- = 0; /* r04 */
*stk-- = 0; /* r03 */ *stk-- = 0; /* r03 */
*stk-- = (unsigned long) &_SDA2_BASE_; /* r02 */ *stk-- = (unsigned long)&_SDA2_BASE_; /* r02 */
*stk = 2; /* enable interrupt */ *stk = 2; /* enable interrupt */
return (rt_uint8_t *) stk; return (rt_uint8_t *)stk;
} }

View File

@ -20,17 +20,20 @@
#include "xintc_i.h" #include "xintc_i.h"
#include "xintc_l.h" #include "xintc_l.h"
#define MAX_HANDLERS XPAR_INTC_MAX_NUM_INTR_INPUTS #define MAX_HANDLERS XPAR_INTC_MAX_NUM_INTR_INPUTS
extern XIntc int_ctl; /* The instance of the Interrupt Controller */ extern XIntc int_ctl; /* The instance of the Interrupt Controller */
extern rt_uint32_t rt_interrupt_nest; extern rt_uint32_t rt_interrupt_nest;
rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread; rt_uint32_t rt_interrupt_from_thread, rt_interrupt_to_thread;
rt_uint32_t rt_thread_switch_interrupt_flag; rt_uint32_t rt_thread_switch_interrupt_flag;
void rt_hw_interrupt_handler(int vector) void rt_hw_interrupt_handler(int vector)
{ {
rt_kprintf("Unhandled interrupt %d occured!!!\n", vector); rt_kprintf("Unhandled interrupt %d occured!!!\n", vector);
} }
/** /**
@ -38,22 +41,24 @@ void rt_hw_interrupt_handler(int vector)
*/ */
void rt_hw_interrupt_init() void rt_hw_interrupt_init()
{ {
rt_base_t index; rt_base_t index;
XIntc_Config *CfgPtr;
XIntc_Config *CfgPtr;
CfgPtr = &XIntc_ConfigTable[0]; CfgPtr = &XIntc_ConfigTable[0];
for (index = 0; index < MAX_HANDLERS; index++)
{
CfgPtr->HandlerTable[index].Handler = (XInterruptHandler) rt_hw_interrupt_handler;
}
/* init interrupt nest, and context in thread sp */ for (index = 0; index < MAX_HANDLERS; index ++)
rt_interrupt_nest = 0; {
rt_interrupt_from_thread = 0; CfgPtr->HandlerTable[index].Handler = (XInterruptHandler)rt_hw_interrupt_handler;
rt_interrupt_to_thread = 0; }
rt_thread_switch_interrupt_flag = 0;
/* init interrupt nest, and context in thread sp */
rt_interrupt_nest = 0;
rt_interrupt_from_thread = 0;
rt_interrupt_to_thread = 0;
rt_thread_switch_interrupt_flag = 0;
} }
/** /**
@ -62,8 +67,8 @@ void rt_hw_interrupt_init()
*/ */
void rt_hw_interrupt_mask(int vector) void rt_hw_interrupt_mask(int vector)
{ {
/* disable interrupt */ /* disable interrupt */
XIntc_Disable(&int_ctl, vector); XIntc_Disable(&int_ctl,vector);
} }
/** /**
@ -72,7 +77,7 @@ void rt_hw_interrupt_mask(int vector)
*/ */
void rt_hw_interrupt_umask(int vector) void rt_hw_interrupt_umask(int vector)
{ {
XIntc_Enable(&int_ctl, vector); XIntc_Enable(&int_ctl,vector);
} }
/** /**
@ -83,123 +88,124 @@ void rt_hw_interrupt_umask(int vector)
*/ */
void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler) void rt_hw_interrupt_install(int vector, rt_isr_handler_t new_handler, rt_isr_handler_t *old_handler)
{ {
XIntc_Config *CfgPtr; XIntc_Config *CfgPtr;
CfgPtr = &XIntc_ConfigTable[0]; CfgPtr = &XIntc_ConfigTable[0];
if (vector >= 0 && vector < MAX_HANDLERS) if(vector >= 0 && vector < MAX_HANDLERS)
{ {
if (*old_handler != RT_NULL) if (*old_handler != RT_NULL) *old_handler = (rt_isr_handler_t)CfgPtr->HandlerTable[vector].Handler;
*old_handler = (rt_isr_handler_t) CfgPtr->HandlerTable[vector].Handler; if (new_handler != RT_NULL) CfgPtr->HandlerTable[vector].Handler = (XInterruptHandler)new_handler;
if (new_handler != RT_NULL) }
CfgPtr->HandlerTable[vector].Handler = (XInterruptHandler) new_handler;
}
} }
/*****************************************************************************/ /*****************************************************************************/
/** copy from XIntc_DeviceInterruptHandler in xintc_l.c nl1031 /** copy from XIntc_DeviceInterruptHandler in xintc_l.c nl1031
* *
* This function is the primary interrupt handler for the driver. It must be * This function is the primary interrupt handler for the driver. It must be
* connected to the interrupt source such that is called when an interrupt of * connected to the interrupt source such that is called when an interrupt of
* the interrupt controller is active. It will resolve which interrupts are * the interrupt controller is active. It will resolve which interrupts are
* active and enabled and call the appropriate interrupt handler. It uses * active and enabled and call the appropriate interrupt handler. It uses
* the AckBeforeService flag in the configuration data to determine when to * the AckBeforeService flag in the configuration data to determine when to
* acknowledge the interrupt. Highest priority interrupts are serviced first. * acknowledge the interrupt. Highest priority interrupts are serviced first.
* The driver can be configured to service only the highest priority interrupt * The driver can be configured to service only the highest priority interrupt
* or all pending interrupts using the {XIntc_SetOptions()} function or * or all pending interrupts using the {XIntc_SetOptions()} function or
* the {XIntc_SetIntrSrvOption()} function. * the {XIntc_SetIntrSrvOption()} function.
* *
* This function assumes that an interrupt vector table has been previously * This function assumes that an interrupt vector table has been previously
* initialized. It does not verify that entries in the table are valid before * initialized. It does not verify that entries in the table are valid before
* calling an interrupt handler. * calling an interrupt handler.
* *
* *
* @return None. * @return None.
* *
* @note * @note
* *
* The constant XPAR_INTC_MAX_NUM_INTR_INPUTS must be setup for this to compile. * The constant XPAR_INTC_MAX_NUM_INTR_INPUTS must be setup for this to compile.
* Interrupt IDs range from 0 - 31 and correspond to the interrupt input signals * Interrupt IDs range from 0 - 31 and correspond to the interrupt input signals
* for the interrupt controller. XPAR_INTC_MAX_NUM_INTR_INPUTS specifies the * for the interrupt controller. XPAR_INTC_MAX_NUM_INTR_INPUTS specifies the
* highest numbered interrupt input signal that is used. * highest numbered interrupt input signal that is used.
* *
******************************************************************************/ ******************************************************************************/
void rt_hw_trap_irq(void)
void rt_hw_trap_irq(void )
{ {
u32 intr_status; u32 intr_status;
u32 intr_mask = 1; u32 intr_mask = 1;
int intr_number; int intr_number;
volatile u32 reg; /* used as bit bucket */ volatile u32 reg; /* used as bit bucket */
XIntc_Config *cfg_ptr; XIntc_Config *cfg_ptr;
/* Get the configuration data using the device ID */
cfg_ptr = &XIntc_ConfigTable[0];
/* Get the interrupts that are waiting to be serviced */ /* Get the configuration data using the device ID */
intr_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); cfg_ptr = &XIntc_ConfigTable[0];
/* Service each interrupt that is active and enabled by checking each /* Get the interrupts that are waiting to be serviced */
* bit in the register from LSB to MSB which corresponds to an interrupt intr_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR);
* intput signal
*/
for (intr_number = 0; intr_number < XPAR_INTC_MAX_NUM_INTR_INPUTS; intr_number++)
{
if (intr_status & 1)
{
XIntc_VectorTableEntry *table_ptr;
/* If the interrupt has been setup to acknowledge it /* Service each interrupt that is active and enabled by checking each
* before servicing the interrupt, then ack it * bit in the register from LSB to MSB which corresponds to an interrupt
*/ * intput signal
if (cfg_ptr->AckBeforeService & intr_mask) */
{ for (intr_number = 0; intr_number < XPAR_INTC_MAX_NUM_INTR_INPUTS; intr_number++)
XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask); {
} if (intr_status & 1)
{
XIntc_VectorTableEntry *table_ptr;
/* The interrupt is active and enabled, call the /* If the interrupt has been setup to acknowledge it
* interrupt handler that was setup with the specified * before servicing the interrupt, then ack it
* parameter */
*/ if (cfg_ptr->AckBeforeService & intr_mask)
table_ptr = &(cfg_ptr->HandlerTable[intr_number]); {
table_ptr->Handler(table_ptr->CallBackRef); XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask);
}
/* If the interrupt has been setup to acknowledge it /* The interrupt is active and enabled, call the
* after it has been serviced then ack it * interrupt handler that was setup with the specified
*/ * parameter
if ((cfg_ptr->AckBeforeService & intr_mask) == 0) */
{ table_ptr = &(cfg_ptr->HandlerTable[intr_number]);
XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask); table_ptr->Handler(table_ptr->CallBackRef);
}
/* /* If the interrupt has been setup to acknowledge it
* Read the ISR again to handle architectures with posted write * after it has been serviced then ack it
* bus access issues. */
*/ if ((cfg_ptr->AckBeforeService & intr_mask) == 0)
reg = XIntc_GetIntrStatus(cfg_ptr->BaseAddress); {
XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask);
}
/* /*
* If only the highest priority interrupt is to be * Read the ISR again to handle architectures with posted write
* serviced, exit loop and return after servicing * bus access issues.
* the interrupt */
*/ reg = XIntc_GetIntrStatus(cfg_ptr->BaseAddress);
if (cfg_ptr->Options == XIN_SVC_SGL_ISR_OPTION)
{
return;
}
}
/* Move to the next interrupt to check */ /*
intr_mask <<= 1; * If only the highest priority interrupt is to be
intr_status >>= 1; * serviced, exit loop and return after servicing
* the interrupt
*/
if (cfg_ptr->Options == XIN_SVC_SGL_ISR_OPTION)
{
return;
}
}
/* If there are no other bits set indicating that all interrupts /* Move to the next interrupt to check */
* have been serviced, then exit the loop intr_mask <<= 1;
*/ intr_status >>= 1;
if (intr_status == 0)
{ /* If there are no other bits set indicating that all interrupts
break; * have been serviced, then exit the loop
} */
} if (intr_status == 0)
{
break;
}
}
} }