使用STM32WL V1.3.0的LoRaWAN_End_Node_FreeRTOS,stm32wle5cc芯片,发现运行几天后大概率出现systick周期由1ms变为4us的问题,导致freertos任务无法正常运行。 从debug信息中发现STK_LOAD寄存器被修改为很小的值,每次出问题的位置都是在lorawan发送一帧数据的过程中,MAC txDone到MAC rxTimeOut之间。 Debug info: [2023-08-06 22:22:51-023] 01:01:01:01:01:01:01:01 DevAddr: 01:84:17:D3 g_systick_reg_per:6 2b828e 2b7d7f 400003e8 g_systick_reg_post:7 bb80 bb4b 400003e8 (ß The normal register value regs:1.STK_CTRL 2.STK_LOAD 3.STK_VAL 4.STK_CALIB) -------------test1 TickCount:281704498-------------- -------------free heap:18328 12072-------------- g_systick_test:220752 tim17_test:201719 name state priority stack num test_task_creat X 11 126 6 IDLE R 0 81 2 Tmr Svc B 2 223 3 monitor_loop B 6 168 5 sensor_loop B 10 790 4 lm_handler_proc B 8 232 7 lorawan_process [2023-08-06 22:22:51-123] B 7 22 8 [2023-08-06 22:22:52-441] OnMacProcessNotify pre OnMacProcessNotify:1 282161s607:MAC txDone ----------start lm_handler_process TickCount:281704881-------------- (LmHandlerProcess() Semaphore received) ----------end lm_handler_process TickCount:281704883-------------- (LmHandlerProcess() Wait semaphore enter sleep) [2023-08-06 22:22:53-493] 282162s601:RX_1 on freq 922600000 Hz at DR 2 (First receive window) 282162s667:IRQ_RX_TX_TIMEOUT OnMacProcessNotify pre OnMacProcessNotify:1 282162s667:MAC rxTimeOut [2023-08-06 22:23:01-934] delay_handle g_lorawan_state:8 (is RTC timer) (The freertos cannot run) [2023-08-07 10:06:39-378] EXTI9_5_IRQHandler () (Use an external interrupt to trigger a print reg info) [2023-08-07 10:06:44-787] HAL_GPIO_EXTI_Callback:256 g_systick_reg_per:6 fee74e fee22c 400003e8 g_systick_reg_post:10007 2c 24 400003e8 (ß The register value of the exception regs:1.STK_CTRL 2.STK_LOAD 3.STK_VAL 4.STK_CALIB) -------------test1 TickCount:281704899-------------- -------------free heap:18328 12072-------------- 休眠唤醒相关代码: void PreSleepProcessing(uint32_t *ulExpectedIdleTime) { /* Called by the kernel before it places the MCU into a sleep mode because configPRE_SLEEP_PROCESSING() is #defined to PreSleepProcessing(). NOTE: Additional actions can be taken here to get the power consumption even lower. For example, peripherals can be turned off here, and then back on again in the post sleep processing function. For maximum power saving ensure all unused pins are in their lowest power state. */ uint32_t WakeUpTimer_timeOut_ms = app_freertos_tick_to_ms(*ulExpectedIdleTime); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); UTIL_TIMER_SetPeriod(&WakeUpTimer, WakeUpTimer_timeOut_ms); UTIL_TIMER_Start(&WakeUpTimer); Time_BeforeSleep = UTIL_TIMER_GetCurrentTime(); /Stop the systick here so that it stops even in sleep mode/ portNVIC_SYSTICK_CTRL_REG &= ~portNVIC_SYSTICK_ENABLE_BIT; HAL_TIM_Base_Stop_IT(&htim17); g_systick_reg_pre[0] = portNVIC_SYSTICK_CTRL_REG; g_systick_reg_pre[1] = portNVIC_SYSTICK_LOAD_REG; g_systick_reg_pre[2] = portNVIC_SYSTICK_CURRENT_VALUE_REG; g_systick_reg_pre[3] = portNVIC_SYSTICK_STK_CALIB_REG; UTIL_LPM_EnterLowPower(); /* (*ulExpectedIdleTime) is set to 0 to indicate that PreSleepProcessing contains its own wait for interrupt or wait for event instruction and so the kernel vPortSuppressTicksAndSleep function does not need to execute the wfi instruction */ *ulExpectedIdleTime = 0; } void PostSleepProcessing(uint32_t *ulExpectedIdleTime) { /* Called by the kernel when the MCU exits a sleep mode because configPOST_SLEEP_PROCESSING is #defined to PostSleepProcessing(). */ uint32_t SleepDuration = UTIL_TIMER_GetElapsedTime(Time_BeforeSleep); / Avoid compiler warnings about the unused parameter. / UNUSED(ulExpectedIdleTime); UTIL_TIMER_Stop(&WakeUpTimer); / Set the new reload value. / if (portNVIC_SYSTICK_CURRENT_VALUE_REG > (SleepDuration * CORE_TICK_RATE)) { /what remains to sleep/ portNVIC_SYSTICK_LOAD_REG = portNVIC_SYSTICK_CURRENT_VALUE_REG - (app_freertos_ms_to_tick(SleepDuration) * CORE_TICK_RATE); } else { portNVIC_SYSTICK_LOAD_REG = CORE_TICK_RATE; } / Clear the SysTick count flag and set the count value back to zero. / portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; / Restart SysTick. / portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT; HAL_TIM_Base_Start_IT(&htim17); g_systick_reg_post[0] = portNVIC_SYSTICK_CTRL_REG; g_systick_reg_post[1] = portNVIC_SYSTICK_LOAD_REG; g_systick_reg_post[2] = portNVIC_SYSTICK_CURRENT_VALUE_REG; g_systick_reg_post[3] = portNVIC_SYSTICK_STK_CALIB_REG; HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET); } 用户数据发送部分代码: void tcs_lorawan_send(int max_temp, int min_temp) { LmHandlerErrorStatus_t status = LORAMAC_HANDLER_ERROR; UTIL_TIMER_Time_t nextTxIn = 0; static uint16_t sn = 0; float temp; if (g_is_connect) { uint8_t len = 0; static uint16_t battery = 0xFFFF; static uint16_t batt_tmp; batt_tmp = SYS_GetBatteryLevel(); if (batt_tmp < battery) { battery = batt_tmp; } max_temp -= 2731; min_temp -= 2731; max_temp += MAX_TEMP_OFFSET; min_temp += MIN_TEMP_OFFSET; temp = objectTemperatureByDistance((float)max_temp / 10, (float)CONFIG.distance_corr / 100); max_temp = temp * 100; min_temp *= 10; APP_LOG(TS_ON, VLEVEL_M, "VDDA: %dmv\r\n", battery); APP_LOG(TS_ON, VLEVEL_M, "max_temp:%d min_temp:%d\r\n", max_temp, min_temp); if (((max_temp > TEMP_MAX_ERR) || (max_temp < TEMP_MIN_ERR)) || ((min_temp > TEMP_MAX_ERR) || (min_temp < TEMP_MIN_ERR))) { UTIL_TIMER_StartWithPeriod(&g_delay_timer, SEND_INTERVAL * 1000); g_lorawan_state = LORAWAN_STATE_SEND_RETRY; return; } AppData.Port = LORAWAN_USER_APP_PORT; / head / AppData.Buffer[len++] = 0xAA; if 1/ len (Skip Length) / len++; / serial number / AppData.Buffer[len++] = (uint8_t)sn & 0xFF; AppData.Buffer[len++] = (uint8_t)((sn >> 8) & 0xFF); sn++; / dev_t / AppData.Buffer[len++] = (uint8_t)PROTOCOL_DEV_TYPE & 0xff; AppData.Buffer[len++] = (uint8_t)((PROTOCOL_DEV_TYPE >> 8) & 0xff); / key (ignore)/ AppData.Buffer[len++] = 0x00; AppData.Buffer[len++] = 0x00; AppData.Buffer[len++] = 0x00; / data / AppData.Buffer[len++] = (uint8_t)(battery & 0xFF); AppData.Buffer[len++] = (uint8_t)((battery >> 8) & 0xFF); AppData.Buffer[len++] = (uint8_t)(max_temp & 0xFF); AppData.Buffer[len++] = (uint8_t)((max_temp >> 8) & 0xFF); AppData.Buffer[len++] = (uint8_t)(min_temp & 0xFF); AppData.Buffer[len++] = (uint8_t)((min_temp >> 8) & 0xFF); AppData.Buffer[len++] = (uint8_t)(CONFIG.distance_corr & 0xFF); AppData.Buffer[len++] = (uint8_t)((CONFIG.distance_corr
AppData.Buffer[len++] = CONFIG.emissivity; AppData.Buffer[len++] = CONFIG.max_temp_limit; AppData.Buffer[len++] = CONFIG.min_temp_limit; / set len / AppData.Buffer[1] = len; / set checksum / AppData.Buffer[len++] = get_checkSum(AppData.Buffer, len); endifAppData.BufferSize = len; status = LmHandlerSend(&AppData, LmHandlerParams.IsTxConfirmed, false); if (LORAMAC_HANDLER_SUCCESS == status) { APP_LOG(TS_ON, VLEVEL_L, "SEND REQUEST\r\n"); } else if (LORAMAC_HANDLER_DUTYCYCLE_RESTRICTED == status) { nextTxIn = LmHandlerGetDutyCycleWaitTime(); if (nextTxIn > 0) { APP_PRINTF("Next Tx in : ~%d second(s)\n", (nextTxIn / 1000)); } } } UTIL_TIMER_StartWithPeriod(&g_delay_timer, MAX(nextTxIn, SEND_INTERVAL * 1000)); } |
stm32wl 可以搭配芯片天线或者PCB天线吗
需要STM32WLE5CCU6 + LoRa 的例程
stm32wle5ccu6的demo原理图有吗,这个芯片支持跳频吗?
STM32WL33CCV的SWD烧录最小系统怎么搭建?用的哪一组SWD接口?
我的电脑识别不到STM32的ST-LINK驱动(特指针对芯片stm32wle5ccu6)
STM32WLE5运行官方pingpong例程无法接收到lora信号
STM32WL55启用Radio初始化,RTC待机唤醒模式失效
stm32wl如何获取RX接收的内容
STM32WL55LORA模式接收不到信息
STM32WL55JC的例程代码中的APP_LOG()是否能理解为串口打印
兄弟 你的STlink能正常使用吗 我的开发板下不进程序,是哪里的跳线帽要改变吗
[md]STM32WL55JC 的例程在哪里下载的
STM32CUBEMX