This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software:
Hi Ti,
SDK version: mcu_plus_sdk_am64x_08_06_00_45
Test environment description:
I run a program based on the FreeRTOS version on the r5fss1_0 kernel. In the program, I enabled the external GPIO pin (GPIO0_37 -> GPMC0_WAIT0 (W19)) interrupt configuration. I input a square wave with a period of 100us to the pin externally, and then I use the ClockP_getTimeUsec function in the GPIO interrupt service function to measure the interrupt interval. Normally, the measured interrupt interval should be stable at around 100, but I recorded the measured values through some software methods (wave recording), and I found that there would be abnormal values of up to about 1100. For this reason, I did a lot of debugging work. I found that by modifying the priority of the tick interrupt, as long as the tick interrupt priority is higher than the GPIO interrupt priority, the abnormal value will not appear. So I would like to ask TI experts, what level is recommended for the tick interrupt priority? In addition, can my problem be explained as related to the tick interrupt priority? Is my handling correct?
Here are my key parts of the code for your reference:
volatile uint32_t ISR_TimeValues[4]; void getCtrlCycleTime(void) { volatile static uint64_t preTime = 0; volatile uint64_t dTime = ClockP_getTimeUsec(); if (dTime > preTime) { ISR_TimeValues[0] = dTime - preTime; } preTime = dTime; } /* GPIO Pin interrupt function with a period of 100us */ static void GPIO_BankIsrFxn(void *args) { volatile uint32_t pinNum = (uint32_t)args; volatile uint32_t intrStatus; intrStatus = GPIO_getIntrStatus(gGpioBaseAddr, pinNum); GPIO_clearIntrStatus(gGpioBaseAddr, pinNum); if(intrStatus) { /* Measuring GPIO interrupt intervals */ getCtrlCycleTime(); /* Waveform recording function call */ TFR_Sample(&ISR_TimeValues); } } #define INTR_PIN_NUM (37) #define INTR_NUM CSLR_R5FSS1_CORE0_INTR_MAIN_GPIOMUX_INTROUTER0_OUTP_12 //12~13 #define INTR_DEV_ID TISCI_DEV_R5FSS1_CORE0 #define GPMC_WAIT0_BASE_ADDR (CSL_GPIO0_BASE) #define GPMC_WAIT0_PIN (37) #define GPMC_WAIT0_DIR (GPIO_DIRECTION_INPUT) #define GPMC_WAIT0_TRIG_TYPE (GPIO_TRIG_TYPE_RISE_EDGE) static Pinmux_PerCfg_t gPinMuxGpioCfg[] = { /* GPIO0_37 -> GPMC0_WAIT0 (W19) */ { PIN_GPMC0_WAIT0, ( PIN_MODE(7) | PIN_INPUT_ENABLE | PIN_PULL_DISABLE ) }, {PINMUX_END, PINMUX_END} }; static void FpgaIrq_GPIO_init() { uint32_t baseAddr; baseAddr = (uint32_t) AddrTranslateP_getLocalAddr(GPMC_WAIT0_BASE_ADDR); GPIO_setDirMode(baseAddr, GPMC_WAIT0_PIN, GPMC_WAIT0_DIR); GPIO_setTrigType(baseAddr, GPMC_WAIT0_PIN, GPMC_WAIT0_TRIG_TYPE); } void Sciclient_gpioIrqSet(void) { int32_t retVal; struct tisci_msg_rm_irq_set_req rmIrqReq; struct tisci_msg_rm_irq_set_resp rmIrqResp; rmIrqReq.valid_params = 0U; rmIrqReq.valid_params |= TISCI_MSG_VALUE_RM_DST_ID_VALID; rmIrqReq.valid_params |= TISCI_MSG_VALUE_RM_DST_HOST_IRQ_VALID; rmIrqReq.global_event = 0U; rmIrqReq.src_id = TISCI_DEV_GPIO0; rmIrqReq.src_index = INTR_PIN_NUM; rmIrqReq.dst_id = INTR_DEV_ID; rmIrqReq.dst_host_irq = INTR_NUM; rmIrqReq.ia_id = 0U; rmIrqReq.vint = 0U; rmIrqReq.vint_status_bit_index = 0U; rmIrqReq.secondary_host = TISCI_MSG_VALUE_RM_UNUSED_SECONDARY_HOST; retVal = Sciclient_rmIrqSet(&rmIrqReq, &rmIrqResp, SystemP_WAIT_FOREVER); if (0 != retVal) { DebugP_log("[R%d][Error] Sciclient event config failed!!!\r\n" ,getCoreNr()); // DebugP_assert(FALSE); } } void GPIO_IntrSetup() { int32_t retVal; uint32_t pinNum; uint32_t intrNum; HwiP_Params hwiPrms; Pinmux_config(gPinMuxGpioCfg, PINMUX_DOMAIN_ID_MAIN); FpgaIrq_GPIO_init(); Sciclient_gpioIrqSet(); pinNum = INTR_PIN_NUM; intrNum = INTR_NUM; /* Address translate */ gGpioBaseAddr = (uint32_t)AddrTranslateP_getLocalAddr(gGpioBaseAddr); GPIO_bankIntrEnable(gGpioBaseAddr, GPIO_GET_BANK_INDEX(INTR_PIN_NUM)); /* Register pin interrupt */ HwiP_Params_init(&hwiPrms); hwiPrms.intNum = intrNum; hwiPrms.callback = &GPIO_BankIsrFxn; hwiPrms.args = (void *)pinNum; /* GPIO interrupt is a pulse type interrupt */ hwiPrms.isPulse = TRUE; hwiPrms.priority = 10; retVal = HwiP_construct(&gGpioHwiObject, &hwiPrms); DebugP_assert(retVal == SystemP_SUCCESS); }
Regards,
wen
Hello Wen,
Thanks for reaching out to Texas Instruments E2E support forum.
I have taken your inputs and working on it. Please allow some time to revert back.
Regards,
Tushar
Hello Wen,
Thanks for your patience.
I found that there would be abnormal values of up to about 1100.
Can you please try once running the example after following the below mentioned steps.
cd source/kernel/freertos/ gmake -s -f makefile.am64x.r5f.ti-arm-clang gmake -s -f makefile.am64x.r5f.gcc-armv7
Please let us know the results.
Regards,
Tushar
Hi Tushar,
I have completed the test, and this change did not improve the problem. There is still an error period data of about 1ms.
Regards,
Wen
Hello Wen,
There is still an error period data of about 1ms.
Can you please also confirm have you build the kernel for debug mode also?
I assume that you are building the example for debug mode, so you will need to rebuild the kernel for debug mode also.
Please run below command from MCU+SDK root directory to build kernel for debug mode.
cd source/kernel/freertos/ gmake -s -f makefile.am64x.r5f.ti-arm-clang PROFILE=debug clean gmake -s -f makefile.am64x.r5f.gcc-armv7 PROFILE=debug clean gmake -s -f makefile.am64x.r5f.ti-arm-clang PROFILE=debug gmake -s -f makefile.am64x.r5f.gcc-armv7 PROFILE=debug
After rebuilding kernel, please rebuild the example project.
Regards,
Tushar
Hi Tushar,
I have confirmed that the kernel has been built, because I have added the kernel source code to the project for compilation, but the error data still appears.
Regards,
Wen
Hello Wen,
I am not sure if the above Tushar proposal is done correctly or not in your workspace .
To confirm above changes are there in your workspace , put the break point in vApplicationIdleHook API and the se whether wfi instruction is executing or not. If it is not executing, then recompile debug kernel libraries and after that rebuild your application too in debug mode
Otherwise with the above proposal , Please confirm with any GPIO pin toggling rather than cycleP_counter API in ISR routines and share the results.
Reagrds,
Anil.
Hi Anil,
I confirmed the modification of this part of the code again, and confirmed through break point debugging that this change has no effect on my measured results. I can still get abnormal values of more than 1000us.
Regards,
Wen
I confirmed the modification of this part of the code again, and confirmed through break point debugging that this change has no effect on my measured results. I can still get abnormal values of more than 1000us.
Hello Wen,
We have not seen these issues on our EVM.
This is the only problem with the measurement of GPIO timing.
We suggested that instead of checking with the clock_timerP, please check with GPIO toggling and share the test results.
As already, we have confirmed that the PMU timer does not give proper results in freeRTOS applications.
Can you please confirm how you measured the above test results ? Is it with GPIO or ClockP timer ?
If you measure with a clockP timer, then there is a problem with the GPIO measurement .
Regards,
Anil.
Hi Anil,
Test code reference:
volatile uint32_t ISR_TimeValues[4]; void getCtrlCycleTime(void) { volatile static uint64_t preTime = 0; volatile uint64_t dTime = ClockP_getTimeUsec(); if (dTime > preTime) { ISR_TimeValues[0] = dTime - preTime; } preTime = dTime; } /* GPIO Pin interrupt function with a period of 100us */ static void GPIO_BankIsrFxn(void *args) { volatile uint32_t pinNum = (uint32_t)args; volatile uint32_t intrStatus; intrStatus = GPIO_getIntrStatus(gGpioBaseAddr, pinNum); GPIO_clearIntrStatus(gGpioBaseAddr, pinNum); if(intrStatus) { /* Measuring GPIO interrupt intervals */ getCtrlCycleTime(); /* Waveform recording function call */ TFR_Sample(&ISR_TimeValues); } }
Regards,
Wen
Hello Wen,
Please check with GTC timer or GPIO toggling and share the test results.
Here, why I am suggesting many times rather than with the above PMU or ClockP_getTimeUsec since these belong to the PMU timer and FreeRTOS timer.
So, the PMU timer does not give proper results when an application is running in freetops.
ClockP_getTimeUsec Timer is not a continuous timer, which means that every time it is loaded with the freeRTOs schedule expired time as start of the counter, and it will never start from 0x00.
In this case, we may get issues while measuring these latencies .
Please confirm this testing with toggling GPIO or GTC timer and share test results.
This testing will be confirmed either this issue with the measurement method or GPIO interrupt.
Regards,
Anil.