你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32WL V1.3.0的LoRaWAN_End_Node_FreeRTOS

[复制链接]
AndyWang2039 提问时间:2023-8-7 12:26 / 未解决

使用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

  1. & 0xFF);

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 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));

}

收藏 评论3 发布时间:2023-8-7 12:26

举报

3个回答
保研 回答时间:2023-8-22 21:17:08

兄弟 你的STlink能正常使用吗 我的开发板下不进程序,是哪里的跳线帽要改变吗$VU1%D827ELF9Q6A.png

IMG_6250.JPG

massimou88888 回答时间:2023-11-14 13:52:52

保研 发表于 2023-8-22 21:17
兄弟 你的STlink能正常使用吗 我的开发板下不进程序,是哪里的跳线帽要改变吗![$VU1%D827ELF9Q6A.png]( ...

[md]STM32WL55JC 的例程在哪里下载的

xingiot 回答时间:2024-2-1 11:40:54

massimou88888 发表于 2023-11-14 13:52
STM32WL55JC 的例程在哪里下载的

STM32CUBEMX

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版