Forum Discussion

FabianL's avatar
FabianL
Icon for Occasional Contributor rankOccasional Contributor
15 hours ago

NIOS V: Systick based timeouts not available when using internal timer

Hello,

 

We are using Quartus 25.1 Standard. I came across something, which I would consider a but in the BSP generated HAL files, or at least a major limitation in the usage of NIOS V.

System Setup:

  • NIOS V + JTAG UART
  • NIOS V in internal Timer as Sys_clk_timer
  • BSP Setting:  

     

Problems:

  • The JTAG UART drivers have a timeout functionality based on the systick interrupt to avoid getting stuck, in case there is not JTAG UART connected, so the internal buffer fills up. --> see altera_avalon_jtag_uart_timeout()
  • This used to work fine with:
    • NIOS II Setup (using external Timer)
    • NIOS V Setup with external Timer block as sys_clk_timer
  • But when using the NIOS V internal as sys_clk_timer the JTAG UART timeout does not trigger and when calling alt_printf it gets stuck in altera_avalon_jtag_uart_write
      /*
       * No OS present: Always wait for data to be removed from buffer.  Once
       * the interrupt routine has removed some data then we will be able to
       * insert some more.
       */
      while (out == sp->tx_out && sp->host_inactive < sp->timeout)

 

Analysis

  • When I check the initialization routine of the JTAG UART altera_avalon_jtag_uart_init  by stepping through with the debugger, I realize, the alarm is not setup: 
      /*
       * No OS present: Always wait for data to be removed from buffer.  Once
       * the interrupt routine has removed some data then we will be able to
       * insert some more.
       */
      while (out == sp->tx_out && sp->host_inactive < sp->timeout)

 

    • This is because the alt_ticks_per_second() returns 0
  • During the main() function alt_ticks_per_second() is correctly set to 10 (which is my setting from the BSP)
  • The root cause, is the initialization order in alt_sys_init() within the generated alt_sys_init.c file:
void alt_sys_init( void )
{
    ALTERA_AVALON_TIMER_INIT ( NIOS_SUBSYSTEM_TIMER_0, nios_subsystem_timer_0);
    ALTERA_AVALON_JTAG_UART_INIT ( NIOS_SUBSYSTEM_JTAG_UART_0, nios_subsystem_jtag_uart_0);
    ALTERA_AVALON_SPI_INIT ( NSC3_SUBSYSTEM_0_ADC_SPI, nsc3_subsystem_0_adc_spi);
    ALTERA_AVALON_SYSID_QSYS_INIT ( NIOS_SUBSYSTEM_SYSID_NIOS, nios_subsystem_sysid_nios);
    ALTERA_AVALON_UART_INIT ( NIOS_SUBSYSTEM_UART_IP, nios_subsystem_uart_ip);
    INTEL_NIOSV_M_INIT ( NIOS_SUBSYSTEM_INTEL_NIOSV_M_0, nios_subsystem_intel_niosv_m_0);
}

 

    • _alt_tick_rate is initalized to 0 per default and gets set duing alt_sysclk_init(), called from the INTEL_NIOSV_M_INIT Macro
    • As seen above. The INTEL_NIOSV_M_INIT Macro is called last within alt_sys_init. Hence all other modules do see _alt_tick_rate = 0. Hence assume there is no sys tick timer present. Hence all sys tick based alarms are disabled.
    • NOTE: The ALTERA_AVALON_TIMER_INIT Macro is called first. Which appears to be correct IMHO, so the Timer module works as sys tick timer
    •  

 

@ Altera: Please advise on this issue. Is there any possibility to change the alt_sys_init initialization order?

 

best regards

Fabian

1 Reply

  • tehjingy_Altera's avatar
    tehjingy_Altera
    Icon for Regular Contributor rankRegular Contributor

    Hi FabianL 

     

    That issue that you are facing is valid and we are currently looking into it.

    As a workaround currently could you try modify the generated alt_sys_init function to have the INTEL_NIOSV_M_INIT before the rest as shown below:

     

     

            void alt_sys_init( void ) {                    

                    INTEL_NIOSV_M_INIT ( NIOS_SUBSYSTEM_INTEL_NIOSV_M_0, nios_subsystem_intel_niosv_m_0);

                    ALTERA_AVALON_TIMER_INIT ( NIOS_SUBSYSTEM_TIMER_0, nios_subsystem_timer_0);    

                    ALTERA_AVALON_JTAG_UART_INIT ( NIOS_SUBSYSTEM_JTAG_UART_0, nios_subsystem_jtag_uart_0);   

                    ALTERA_AVALON_SPI_INIT ( NSC3_SUBSYSTEM_0_ADC_SPI, nsc3_subsystem_0_adc_spi);    

                    ALTERA_AVALON_SYSID_QSYS_INIT ( NIOS_SUBSYSTEM_SYSID_NIOS, nios_subsystem_sysid_nios);    

                    ALTERA_AVALON_UART_INIT ( NIOS_SUBSYSTEM_UART_IP, nios_subsystem_uart_ip);    

            }

     

     

    For further details refer to the KDB :

    https://community.altera.com/kb/knowledge-base/why-does-the-nios%C2%AE-v-processor-that-applies-fast-jtag-uart-driver-stop-stuck-in-/349481