Hi,
I am trying to migrate my application from RTOS to RTOS2 on a LPC4337. I did not have any issue yet to migrate M4 application which uses the SysTick timer for the kernel tick.
But I am not able to configure the M0 OS tick using an alternate timer (M0 do not have acces to the SysTick Timer).
With the RTOS I use the RITIMER (freq. = 1000Hz) as an alternate timer In the file "RTX_Conf_CM.c" my functions are :
int os_tick_init (void) { (...) //RITIMER configuration return(M0_RITIMER_OR_WWDT_IRQn); } uint32_t os_tick_val (void) { return (0); } uint32_t os_tick_ovf (void) { return (0); } void os_tick_irqack (void) { RIT_GetIntStatus(LPC_RITIMER); }
And I call the "OS_Tick_Handler" function in the assembly file instead of the RIT handler (I have no issue with RTOS, everything works fine).
With the RTOS2 I was stuck using the RITIMER (the interrupt and acknowledge did not work correctly) so I switched with the TIMER3 (freq. = 1MHz) Here are my functions :
int32_t osRtxSysTimerSetup (void){ (...) //TIMER3 Init code NVIC_SetPriority(M0_TIMER3_IRQn,(1UL << __NVIC_PRIO_BITS) - 1UL); //? NVIC_EnableIRQ(M0_TIMER3_IRQn); return(M0_TIMER3_IRQn); } /// Enable System Timer. void osRtxSysTimerEnable (void){ TIM_Cmd(LPC_TIMER3,ENABLE); } void osRtxSysTimerDisable (void){ TIM_Cmd(LPC_TIMER3,DISABLE); } void osRtxSysTimerAckIRQ (void){ TIM_ClearIntPending(LPC_TIMER3,TIM_MR0_INT); NVIC_ClearPendingIRQ(M0_TIMER3_IRQn); } uint32_t osRtxSysTimerGetCount (void){ return (_tick); //? } uint32_t osRtxSysTimerGetFreq (void){ return 1000000; } void M0_TIMER3_IRQHandler (void){ _tick++; //? osRtxTick_Handler(); }
I have no idea of what I need to implement in these functions for an alternate timer (Keil doc. and examples are very light on this topic). My TIMER3 interrupt works and is called at the desired frequency (1MHz), all other functions are called by the system but I am not sure about the return values. I tried a lot of differents frequencies, differents return values, etc.
I have only one thread running at the moment with a simple loop that sends a message after a short delay (I tried with "osDelayUntil" and "osDelay"). Depending on the delay, the loop can work twice or three times then the system "gets stuck" and loops forever in the "osRtxIdleThread" function.
int32_t main(void) { SystemInit(); //init system osKernelInitialize(); osThreadNew(Init_Thread, NULL, NULL); // start init task osKernelStart(); for (;;); } void Init_Thread(void *argument){ while(1){ (...)//send message through UART //osDelay(10); osDelayUntil(osKernelGetTickCount() + 10); } }
Could someone help me implementing an alternate timer or would have more documentations on this topic to guide me ?
Thank you.
Hi Robert,
Thank you for your answers. Here is a working code from ARM support based on your comments (hope this may help other users with the same issue)
#include "rtx_os.h" // ARM::CMSIS:RTOS2:Keil RTX5 #include "LPC43xx.h" // Device header /* ** forward the M0_SVC_Handler to the RTX SVC_Handler */ __asm __declspec( noreturn ) void M0_SVC_Handler( void ) { EXTERN SVC_Handler LDR R0, =SVC_Handler BX R0 } /* ** forward the M0_PendSV_Handler to the RTX PendSV_Handler */ __asm __declspec( noreturn ) void M0_PendSV_Handler( void ) { EXTERN PendSV_Handler LDR R0, =PendSV_Handler BX R0 } /* ** forward the M0_RIT_OR_WWDT_IRQHandler to the RTX SysTick_Handler */ __asm __declspec( noreturn ) void M0_RITIMER_OR_WWDT_IRQHandler( void ) { EXTERN SysTick_Handler LDR R0, =SysTick_Handler BX R0 } int32_t osRtxSysTimerSetup( void ) { LPC_CCU1->CLK_M4_RITIMER_CFG = CCU1_CLK_M4_RITIMER_CFG_RUN_Msk ; LPC_RITIMER->COUNTER = 0x00000000 ; LPC_RITIMER->MASK = 0x00000000 ; LPC_RITIMER->COMPVAL = osRtxInfo.kernel.sys_freq / osRtxConfig.tick_freq - 1 ; return( M0_RITIMER_OR_WWDT_IRQn ) ; /* Return IRQ number of SysTick timer */ } void osRtxSysTimerEnable( void ) { LPC_RITIMER->CTRL = RITIMER_CTRL_RITENBR_Msk | RITIMER_CTRL_RITENCLR_Msk | RITIMER_CTRL_RITEN_Msk ; } void osRtxSysTimerDisable( void ) { LPC_RITIMER->CTRL = 0 ; } void osRtxSysTimerAckIRQ( void ) { /* Acknowledge timer interrupt. */ LPC_RITIMER->CTRL |= ( RITIMER_CTRL_RITINT_Msk ) ; } uint32_t osRtxSysTimerGetCount( void ) { uint32_t tick; uint32_t val; tick = ( uint32_t )osRtxInfo.kernel.tick ; val = LPC_RITIMER->COUNTER ; if( LPC_RITIMER->CTRL & ( RITIMER_CTRL_RITINT_Msk ) ) { val = LPC_RITIMER->COUNTER ; tick++ ; } val += tick * ( LPC_RITIMER->COMPVAL + 1 ) ; return( val ) ; } uint32_t osRtxSysTimerGetFreq( void ) { return( osRtxInfo.kernel.sys_freq ) ; }