Monday, February 19, 2024

NIOS V OS porting

 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 ) )































Friday, September 15, 2023

Intel NIOS V Resources


Nios V/m software development


-- 39 ----
8. Jumps to alt_main()—The processor jumps to the alt_main() function, which begins initializing the HAL BSP run-time library.

Note: If you use a third-party RTOS or environment for your BSP library file, the alt_main() function can be different than the one provided by Intel.

---- 40 ----
The HAL alt_main() function performs the following steps:
 1. Initializes interrupts—Sets up interrupt support for the Nios V processor with the alt_irq_init() function.
 2. Starts MicroC/OS-II—Starts the MicroC/OS-II, if this OS is configured to run (with the ALT_OS_INIT and ALT_SEM_CREATE functions). For additional information about MicroC/OS-II use and initialization, refer to Selecting the Operating System.

 ----
3.4.3.1. Timer Devices The HAL provides two types of timer services, a system clock timer, and a timestamp timer. • The system clock timer is used to control, monitor, and schedule system events. • The timestamp variant is used to make high performance timing measurements. You can assign each of these timer services to the Nios V processor internal timer or an Intel Avalon Timer peripheral. Note: Nios V processor core includes a timer that provides both the system clock timer and timestamp services.

----
The HAL system initialization process calls the MicroC/OS-II function OSInit() before
alt_sys_init(), which instantiates and initializes each device in the system.
Therefore, the complete MicroC/OS-II API is available to device drivers, although the
system is still running in single-threaded mode until the program calls OSStart()
from within main().
----

C:\intelFPGA_pro\23.2\nios2eds\components\micrium_uc_osii\UCOSII\inc\os


9.3.5. Interrupt Service Routines for MicroC/OS-II
Implementing ISRs for MicroC/OS-II normally involves some housekeeping details, as
described in MicroC/OS-II: The Real-Time Kernel. However, because the Nios V
implementation of MicroC/OS-II is based on the HAL, several of these details are
taken care of for you. The HAL performs the following housekeeping tasks for your
interrupt service routine (ISR):
• Saves and restores processor registers
• Calls OSIntEnter() and OSIntExit()
The HAL also allows you to write your ISR in C, rather than assembly language.


 

Tuesday, July 25, 2023

Math olympiad

 “In terms of Olympiad Math, I am mostly self-taught. Ever since grade 10, I have been doing Olympiad Math, through the Art of Problem Solving website, classes on the Online Math Club and handouts by Evan Chen, a past Olympiad medallist. I won a gold medal and placed 12th overall in this year’s event,” said Atul.

He got a perfect score of 1600 on the SAT last year and he will be continuing my future studies, doing Mathematics and Computer Science at the Massachusetts Institute of Technology, USA. “I am also the director of the Sophie Fellowship, an initiative to prepare Indian students for Math Olympiads by showing them its beauty. With this, I also hope to reach out to more students in India, most of who are unaware of the prospects mathematics holds as a career,” he added.“In terms of Olympiad Math, I am mostly self-taught. Ever since grade 10, I have been doing Olympiad Math, through the Art of Problem Solving website, classes on the Online Math Club and handouts by Evan Chen, a past Olympiad medallist. I won a gold medal and placed 12th overall in this year’s event,” said Atul.

He got a perfect score of 1600 on the SAT last year and he will be continuing my future studies, doing Mathematics and Computer Science at the Massachusetts Institute of Technology, USA. “I am also the director of the Sophie Fellowship, an initiative to prepare Indian students for Math Olympiads by showing them its beauty. With this, I also hope to reach out to more students in India, most of who are unaware of the prospects mathematics holds as a career,” he added.