Hi,
I encounter an issue while trying to updating my application using RTX5 CMSIS OS to RTX5 CMSIS OS2.
While using RTX5 CMSIS OS everything works fine (I can upload and download files to my FTP server with a constant rate).
I updated the files to the last version (and nothing needed to be changed in my source files to be able to compile the whole project).
With the new RTX5 CMSIS OS2 , my FTP server starts to download/upload files like before but after a certain amount of data/time it stucks and the rate decrease by a lot (from 2Mbits/s to less than 100bits/s).
I tried a lot of thing to be able to resolve the issue but the only way to have the FTP server working is by using the old EMAC_LPC43XX.C file, v2.8, which does not support RTX5 CMSIS OS2 (I am using a LPC4337)
The only differences between the 2 versions of the file (v2.8 and v2.9) are this code lines
#if defined(RTE_CMSIS_RTOS2) tick = osKernelGetTickCount(); #elif defined(RTE_CMSIS_RTOS) tick = osKernelSysTick(); #endif
#if defined(RTE_CMSIS_RTOS2) } while ((osKernelGetTickCount() - tick) < (((osKernelGetTickFreq() * PHY_TIMEOUT) + 999999U) / 1000000U)); #elif defined(RTE_CMSIS_RTOS) } while ((osKernelSysTick() - tick) < osKernelSysTickMicroSec(PHY_TIMEOUT)); #endif
So it seems that I may encounter an issue with osKernelGetTickCount and osKernelGetTickFreq
I am using an alternative clock (RIT from LPC4337 @1000 Hz) for the kernel and here is the code
/**************************************************************************//** * @file os_systick.c * @brief CMSIS OS Tick SysTick implementation * @version V1.0.1 * @date 24. November 2017 ******************************************************************************/ /* * Copyright (c) 2017-2017 ARM Limited. All rights reserved. * * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. * You may obtain a copy of the License at * * www.apache.org/.../LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "os_tick.h" #include "RTE_Components.h" #include CMSIS_device_header #ifndef SYSTICK_IRQ_PRIORITY #define SYSTICK_IRQ_PRIORITY 0xFFU #endif IRQHandler_t _tickHandler; #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 } void M0_RITIMER_OR_WWDT_IRQHandler( void ){ _tickHandler(); } // Setup OS Tick. int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { uint32_t load; _tickHandler = handler; if (freq == 0U) { return (-1); } load = (SystemCoreClock / freq) - 1U; if (load > 0x00FFFFFFU) { return (-1); } LPC_CCU1->CLK_M4_RITIMER_CFG = CCU1_CLK_M4_RITIMER_CFG_RUN_Msk ; LPC_RITIMER->COUNTER = 0x00000000 ; LPC_RITIMER->MASK = 0x00000000 ; LPC_RITIMER->COMPVAL = load ; NVIC_SetPriority(M0_RITIMER_OR_WWDT_IRQn, 0xFF); NVIC_EnableIRQ(M0_RITIMER_OR_WWDT_IRQn); return (0); } /// Enable OS Tick. void OS_Tick_Enable (void) { LPC_RITIMER->CTRL = RITIMER_CTRL_RITENBR_Msk | RITIMER_CTRL_RITENCLR_Msk | RITIMER_CTRL_RITEN_Msk ; //return (0); } /// Disable OS Tick. void OS_Tick_Disable (void) { LPC_RITIMER->CTRL = 0 ; //return (0); } // Acknowledge OS Tick IRQ. void OS_Tick_AcknowledgeIRQ (void) { /* Acknowledge timer interrupt. */ LPC_RITIMER->CTRL |= ( RITIMER_CTRL_RITINT_Msk ) ; //return (0); } // Get OS Tick IRQ number. int32_t OS_Tick_GetIRQn (void) { return ((int32_t)M0_RITIMER_OR_WWDT_IRQn); } // Get OS Tick clock. uint32_t OS_Tick_GetClock (void) { return (SystemCoreClock); } // Get OS Tick interval. uint32_t OS_Tick_GetInterval (void) { return (LPC_RITIMER->COMPVAL + 1U); } // Get OS Tick count value. uint32_t OS_Tick_GetCount (void) { return( LPC_RITIMER->COUNTER ) ; } // Get OS Tick overflow status. uint32_t OS_Tick_GetOverflow (void) { return (LPC_RITIMER->CTRL & 1); }
Does anyone already encountered such an issue and have any idea on how to fix it (I would like to update my application to the latest version and I don't wont to be stuck with CMSIS OS1 even if it works fine) ?
Regards.
Incorrect Flash Accelerator timings might cause such an issue. What is the core clock you are using?
Default setting for the FLASHCFGA and FLASHCFGB is 4, which is fine for core clocks up to 107 MHz. If your core clock is higher, you might see sporadic undefined behaviour of your application.
/*---------------------------------------------------------------------------- * Configure Flash Accelerator *---------------------------------------------------------------------------- * Flash acces time: * | CPU clock | FLASHTIM | * | up to 21MHz | 0 | * | up to 43MHz | 1 | * | up to 64MHz | 2 | * | up to 86MHz | 3 | * | up to 107MHz | 4 | * | up to 129MHz | 5 | * | up to 150MHz | 6 | * | up to 172MHz | 7 | * | up to 193MHz | 8 | * | up to 204MHz | 9 | *----------------------------------------------------------------------------*/ #define FLASHCFG_FLASHTIM 8
Incorrect flash timing setting might cause decoding and executing an invalid instruction. If an invalid instruction is a jump to uninitialized/undefined memory, this ends in a hardfault. But usually, execution of an invalid instruction is not trapped in a hardfault.
Thank you for your reply. Indeed, FlashTim was still configured at 4 while I am running at 204MHz (still don't understand how my device could working for years with such a mistake !). But, unfortunatly, it does not solve my first issue.
My FTP download still stuck after few minutes/data (depending on the SD cache drive, if I increase the cache, I could download way more data but FTP stucks faster, if I remove the cache, I can have my download running for few more minutes but FTP will stuck after downloading less data).
For the issue to show up, many conditions must be met. Flash Accelerator fetches 16 bytes in parallel (128-bits). If the last 2 bytes of a fetch are from a 4-byte THUMB-2 instruction, the flash accelerator must do a second fetch to complete the last instruction. If the address of the fetch is at a specific boundary, and the flash accelerator timings are incorrect, this might fail. That is why this problem is rarely seen.
The code difference in the EMAC driver is actually a correction of the timeout in PHY management interface. If this fails, the Network core might incorrectly detect link-up or link-down status. This has no influence on the transfer speed.
I think the issue is coming from the PHY_TIMEOUT combined with my kernel frequency.
My kernel frequency is @1000Hz so it can't do a proper while loop with a 200us delay (PHY_TIMEOUT). Timeout value for 200us is equal to 1 tick so it might happens that new tick minus previous tick reach directly the timeout condition and result in a single loop and I think this may cause Ethernet issues.
As you said, the timeout with the previous version was not correct and this is why it worked for me.
I just added a "<=" in the timeout condition to avoid this unexpected behavior and it fixed my issue.
Thanks again for your help.