First Interrupt Execution Flow:
C:\intelFPGA_pro\23.2\ip\altera\soft_processor\intel_niosv_common\HAL\src\machine_trap.S is copied to bsp generated in project folders:
C:\test\top_project\sw\bsp_freertos\HAL\src\machine_trap.S
C:\test\top_project\sw\bsp_ucosii\HAL\src\machine_trap.S
trap_vector:
:
save_registers:
/* Save caller-saved registers on the stack */
#if ALT_CPU_NUM_GPR == 32
addi sp, sp, -16 * 4
sw a6, 10 * 4(sp)
sw a7, 11 * 4(sp)
sw t3, 12 * 4(sp)
sw t4, 13 * 4(sp)
sw t5, 14 * 4(sp)
sw t6, 15 * 4(sp)
#else // 16 (RV32E)
addi sp, sp, -10 * 4
#endif
sw ra, 0 * 4(sp)
sw t0, 1 * 4(sp)
sw t1, 2 * 4(sp)
sw t2, 3 * 4(sp)
sw a0, 4 * 4(sp)
sw a1, 5 * 4(sp)
sw a2, 6 * 4(sp)
sw a3, 7 * 4(sp)
sw a4, 8 * 4(sp)
sw a5, 9 * 4(sp)
/* Call handle_trap to dispatch the correct handler, if available */
csrr a0, mcause
csrr a1, mepc
csrr a2, mtval
jal handle_trap
csrw mepc, a0
:
top_project\sw\bsp_ucosii\HAL\src\alt_irq_handler.c
top_project\sw\bsp_freertos\HAL\src\alt_irq_handler.c
alt_u32 handle_trap(alt_u32 cause, alt_u32 epc, alt_u32 tval)
{
alt_u32 is_irq, exception_code;
is_irq = (cause & NIOSV_MCAUSE_INTERRUPT_MASK);
exception_code = (cause & ~NIOSV_MCAUSE_INTERRUPT_MASK);
if (is_irq) {
switch (exception_code) {
case NIOSV_TIMER_IRQ:
{
if (alt_niosv_timer_interrupt_handler) {
ALT_OS_INT_ENTER();
alt_niosv_timer_interrupt_handler(cause, epc, tval);
ALT_OS_INT_EXIT();
}
break;
}
case NIOSV_SOFTWARE_IRQ:
{
if (alt_niosv_software_interrupt_handler) {
ALT_OS_INT_ENTER();
alt_niosv_software_interrupt_handler(cause, epc, tval);
ALT_OS_INT_EXIT();
}
break;
default:
{
if (exception_code >= 16) {
alt_irq_handler();
} else {
ALT_LOG_PRINTF("invalid exception code: %d, epc = %d, tval = %d\n", exception_code, epc, tval);
}
break;
}
:
/*
* A table describing each interrupt handler. The index into the array is the
* interrupt id associated with the handler.
*
* When an interrupt occurs, the associated handler is called with
* the argument stored in the context member.
*/
struct ALT_IRQ_HANDLER
{
void (*handler)(void*);
void *context;
} alt_irq[ALT_NIRQ];
/*
* alt_irq_handler() is called by the interrupt exception handler in order to
* process any outstanding interrupts.
*
* It is defined here since it is linked in using weak linkage.
* This means that if there is never a call to alt_irq_register() then
* this function will not get linked in to the executable. This is acceptable
* since if no handler is ever registered, then an interrupt can never occur.
*/
void alt_irq_handler (void)
{
alt_u32 active;
alt_u32 mask;
alt_u32 i;
/*
* Notify the operating system that we are at interrupt level.
*/
ALT_OS_INT_ENTER();
:
alt_irq[i].handler(alt_irq[i].context);
:
/*
* Notify the operating system that interrupt processing is complete.
*/
ALT_OS_INT_EXIT();
}
There seems to be a major difference between FreeRTOS and uCOS II in interrupt handling that FreeRTOS seems to be calling BSP's handle_trap() from its own trap_vector instead of you provide the ALT_OS_INT_ENTER/ALT_OS_INT_EXIT() for the BSP's trap_vector() and handle_trap(). Check that as it would be better for you.
top_project\sw\bsp_freertos\HAL\src\os_cpu_c.c
/* handle_trap() and alt_tick() are Intel HAL function. */
extern alt_u32 handle_trap( alt_u32 cause, alt_u32 epc, alt_u32 tval );
extern void alt_tick( void );
#define HAL_HANDLE_TRAP(); alt_u32 ulMCAUSE = 0, ulMEPC = 0, ulMTVAL = 0; \
__asm volatile( "csrr %0, mcause" : "=r"( ulMCAUSE ) ); \
__asm volatile( "csrr %0, mepc" : "=r"( ulMEPC ) ); \
__asm volatile( "csrr %0, mtval" : "=r"( ulMTVAL ) ); \
ulHalNestedInterruptCounter++; \
handle_trap(ulMCAUSE, ulMEPC, ulMTVAL); \
ulHalNestedInterruptCounter--; \
/* Hook for tick. To use this, configUSE_TICK_HOOK must set to 1 */
void vApplicationTickHook( void )
{
/* ALT_LOG - see altera_hal/HAL/inc/sys/alt_log_printf.h */
ALT_LOG_SYS_CLK_HEARTBEAT();
ulHalNestedInterruptCounter++;
alt_tick();
ulHalNestedInterruptCounter--;
}
:
/* Override weak function defined in portASM.S */
void freertos_risc_v_application_interrupt_handler( void )
{
HAL_HANDLE_TRAP();
}
/* Override weak function defined in portASM.S */
void freertos_risc_v_application_exception_handler( void )
{
HAL_HANDLE_TRAP();
}
freertos_risc_v_trap_handler is assigned as Vector Base Address in mtvec register.
│Installing the FreeRTOS trap handler
│The FreeRTOS trap handler is called freertos_risc_v_trap_handler() and is the central│entry point for all interrupts and exceptions.
top_project\sw\bsp_freertos\FREERTOS\inc\os\alt_hooks.h
#define ALT_OS_INIT() alt_envsem = xSemaphoreCreateCounting(1, 1); \
alt_heapsem = xSemaphoreCreateCounting(1, 1); \
extern void freertos_risc_v_trap_handler( void ); \
__asm__ volatile( "csrw mtvec, %0" :: "r"( freertos_risc_v_trap_handler ) )