完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
使用STM32WLV1.3.0的LoRaWAN_End_Node_FreeRTOS,stm32wle5cc芯片,发现运行几天后大概率出现systick周期由1ms变为4us的问题,导致freertos任务无法正常运行。
从debug信息中发现STK_LOAD寄存器被修改为很小的值,每次出问题的位置都是在lorawan发送一帧数据的过程中,MAC txDone到MAC rxTimeOut之间。 Debug info: [2023-08-0622:22:51-023] 01:01:01:01:01:01:01:01 DevAddr: 01:84:17:D3 g_systick_reg_per:62b828e 2b7d7f 400003e8 g_systick_reg_post:7bb80 bb4b400003e8(ß The normal register value regs:1.STK_CTRL2.STK_LOAD 3.STK_VAL 4.STK_CALIB) -------------test1TickCount:281704498-------------- -------------freeheap:18328 12072-------------- g_systick_test:220752tim17_test:201719 namestate priority stack num test_task_creatX 11 126 6 IDLER 081 2 TmrSvcB 2 223 3 monitor_loopB 6168 5 sensor_loopB 10 790 4 lm_handler_procB 8 232 7 lorawan_process [2023-08-0622:22:51-123] B 7 22 8 [2023-08-0622:22:52-441] OnMacProcessNotify pre OnMacProcessNotify:1 282161s607:MACtxDone ----------startlm_handler_process TickCount:281704881-------------- (LmHandlerProcess() Semaphore received) ----------endlm_handler_process TickCount:281704883-------------- (LmHandlerProcess() Wait semaphore enter sleep) [2023-08-0622:22:53-493] 282162s601:RX_1 on freq 922600000 Hz at DR 2 (First receive window) 282162s667:IRQ_RX_TX_TIMEOUT OnMacProcessNotifypre OnMacProcessNotify:1 282162s667:MACrxTimeOut [2023-08-0622:23:01-934] delay_handle g_lorawan_state:8 (is RTC timer) (Thefreertos cannot run) [2023-08-0710:06:39-378] EXTI9_5_IRQHandler()(Use anexternal interrupt to trigger a print reg info) [2023-08-0710:06:44-787] HAL_GPIO_EXTI_Callback:256 g_systick_reg_per:6fee74e fee22c 400003e8 g_systick_reg_post:100072c 24400003e8(ß The register value of the exceptionregs:1.STK_CTRL 2.STK_LOAD 3.STK_VAL 4.STK_CALIB) -------------test1TickCount:281704899-------------- -------------freeheap:18328 12072-------------- 休眠唤醒相关代码: voidPreSleepProcessing(uint32_t *ulExpectedIdleTime) { /* Called bythe 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 evenlower. For example, peripherals can be turned off here, and then back on again inthe post sleep processing function. For maximum power saving ensure allunused pins are in their lowest power state. */ uint32_tWakeUpTimer_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(); /Stopthe 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 kernelvPortSuppressTicksAndSleep function does not need to execute the wfi instruction */ *ulExpectedIdleTime = 0; } voidPostSleepProcessing(uint32_t *ulExpectedIdleTime) { /* Called bythe kernel when the MCU exits a sleep mode because configPOST_SLEEP_PROCESSING is #defined to PostSleepProcessing(). */ uint32_tSleepDuration = UTIL_TIMER_GetElapsedTime(Time_BeforeSleep); / Avoidcompiler warnings about the unused parameter. / UNUSED(ulExpectedIdleTime); UTIL_TIMER_Stop( WakeUpTimer); / Set thenew 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 theSysTick count flag and set the count value back to zero. / portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL; / RestartSysTick. / 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); } 用户数据发送部分代码: voidtcs_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: %dmvrn", battery); APP_LOG(TS_ON, VLEVEL_M, "max_temp:%d min_temp:%drn", 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); endif AppData.BufferSize = len; status = LmHandlerSend( AppData, LmHandlerParams.IsTxConfirmed, false); if (LORAMAC_HANDLER_SUCCESS == status) { APP_LOG(TS_ON, VLEVEL_L, "SEND REQUESTrn"); } 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)); } |
|
相关推荐
1个回答
|
|
此问题的原因可能是因为在lorawan发送一帧数据的过程中,发生了中断冲突或者频繁的中断触发,导致systick周期被意外修改。
解决这个问题的方法有以下几种: 1. 检查硬件连接:确保硬件连接正确,没有松动或者短路现象,检查外设和芯片之间的引脚连接是否正确。 2. 检查中断冲突:查看中断优先级设置是否正确,确保关键任务的中断优先级设置正确,没有和其他中断产生冲突。 3. 检查软件逻辑:查看代码中是否存在逻辑问题,比如使用了不正确的延时函数或者中断禁用函数等,确保代码的逻辑正确。 4. 使用调试工具:使用调试工具如调试器或者逻辑分析仪来跟踪程序的执行过程,查看中断触发的时机和频率,以及其他相关的寄存器值。 如果问题仍然存在,建议联系芯片厂商或者参考官方文档寻求更详细的技术支持。 |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1751 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1632 浏览 3 评论
4192 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1778 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
2241 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-12 21:30 , Processed in 0.636824 second(s), Total 78, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号