2025-11-10 3:09 AM
Hello,
I have modbus master and slave device, where I have design modbus master for testing in that way that it will continuously send modbus request after each successfull response, and if any response fail then it stop.
Now on I'm getting continuous response from slave device and working fine. The issue is with slave device having undesired behavior if we restart the slave device.
Slave device has custom bootloader and slave device. So once we start the device it will start bootloader and bootloader will take care to check integrity of slave application and if all well, then jump to slave application.
So, if I dump the code in release mode (via bootloader) first time then slave device continuously give response on each request and it continue until I stop or reset and even after master reset and ON again, the slave device still continue to work well.
Note: It works in all the way if we dump a debug code, only issue with release code. I have remove bootloader and allow to run slave application on 0th address and it work well even after multiple restart.
Now after system restart, again bootloader will take part, check slave application integrity and jump to slave application, But now I can see the delay in the response. (For understanding the wakeup, I have implement lptimer to wakeup at each 2 sec), So the response take 2 second delay and then respond, and this continue. Where this delay doesn't observed on the first time of bootup.
So ideally I will go to low power mode if there is no rx/tx going on.
void enterLowPowerMode()
{
HAL_UARTEx_EnableStopMode(&hlpuart1);
HAL_SuspendTick();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
HAL_ResumeTick();
Reset_SystemClock();// Internally I'm calling the same function SystemClock_Config()
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}static void MX_LPUART1_UART_Init(void)
{
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 115200;
hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
hlpuart1.Init.StopBits = UART_STOPBITS_1;
hlpuart1.Init.Parity = UART_PARITY_NONE;
hlpuart1.Init.Mode = UART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
hlpuart1.FifoMode = UART_FIFOMODE_ENABLE;
if (HAL_UART_Init(&hlpuart1) != HAL_OK)
{
Error_Handler();
}
if (HAL_RS485Ex_Init(&hlpuart1, UART_DE_POLARITY_HIGH, 0, 0) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
{
Error_Handler();
}
if (HAL_UARTEx_EnableFifoMode(&hlpuart1) != HAL_OK)
{
Error_Handler();
}
}During initialization, I also done this
__HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI);
// make sure that no LPUART transfer is on-going
while (__HAL_UART_GET_FLAG(&huart_, USART_ISR_BUSY) == SET);
// make sure that LPUART is ready to receive
while (__HAL_UART_GET_FLAG(&huart_, USART_ISR_REACK) == RESET);
RS485_RX_ENABLE();
__HAL_UART_ENABLE_IT(&huart_, UART_IT_RXNE);
HAL_UARTEx_ReceiveToIdle_IT(&huart_, &gRxBuf[0], 256);
Note.
Bootloader = 0th address
Slave Application: 0x80006800
_Min_Heap_Size = 0x200; /* required amount of heap */
_Min_Stack_Size = 0x400; /* required amount of stack */
/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
FLASH (rx) : ORIGIN = 0x8006800, LENGTH = 114K
}I have also tried to use example of wakeup on start bit, non-empty register, but doesnt help. Or may be the sequence I have not used correctly.
Here, I'm completely out of thoughts, what going wrong on system restart?
Thanks,
Nitin Patil
Solved! Go to Solution.
2025-11-10 9:19 PM
Hello,
Its very easy fix, and I have invest lot of time by doing example code in multiple way, but the solution is to just remove the optimization, where in debug mode it doesnt have any optimization so it works well, but in release it has optimization of O2, so setting to None resolve my issue.
I still need clarity if any on has, it looks like due to optimization the STOP2 mode and IWDG not working correctly. And once I remove it started working. Help me to understand why optimization affect the feature.
Thansk,
Nitin
2025-11-10 9:19 PM
Hello,
Its very easy fix, and I have invest lot of time by doing example code in multiple way, but the solution is to just remove the optimization, where in debug mode it doesnt have any optimization so it works well, but in release it has optimization of O2, so setting to None resolve my issue.
I still need clarity if any on has, it looks like due to optimization the STOP2 mode and IWDG not working correctly. And once I remove it started working. Help me to understand why optimization affect the feature.
Thansk,
Nitin
2025-11-11 1:57 AM
Hello @npatil15
Use Volatile keyword for variables or registers accessed by both your code and hardware (or interrupts). This tells the compiler not to optimize accesses to these variables.