cancel
Showing results for 
Search instead for 
Did you mean: 

Why are initializations in main executing repeatedly if I add a function?

AV.7
Associate

Hi! I am starting to learn embedded programming using a NUCLEO-F439ZI and can't seem to understand why are the initializations in main executing repeatedly when adding an initialization function call that i wrote. I haven't changed any part of the code that STM32CubeIDE generates, i've only added a new source folder with a few classes. What i want to do is perform an initialization on startup and then go about with the normal execution of the program.

I will attach the main function below, as well as the initialization files that i wrote.

int main(void)
{
	/* USER CODE BEGIN 1 */
	initModules(); // if i comment this out, everything works fine
	/* USER CODE END 1 */
 
	/* MCU Configuration--------------------------------------------------------*/
 
	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();
 
	/* USER CODE BEGIN Init */
 
	/* USER CODE END Init */
 
	/* Configure the system clock */
	SystemClock_Config();
 
	/* USER CODE BEGIN SysInit */
 
	/* USER CODE END SysInit */
 
	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_IWDG_Init();
	MX_USART1_UART_Init();
	/* USER CODE BEGIN 2 */
 
	/* USER CODE END 2 */
 
	/* Call init function for freertos objects (in freertos.c) */
	MX_FREERTOS_Init();
	/* Start scheduler */
	osKernelStart();
 
	/* We should never get here as control is now taken by the scheduler */
	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1)
	{
		/* USER CODE END WHILE */
 
		/* USER CODE BEGIN 3 */
	}
	/* USER CODE END 3 */
}

The Callback for external interrupt and initialization functions are declared in the following files:

#ifndef INIT_H_
#define INIT_H_
 
#include <usart.h>
 
#ifdef __cplusplus
extern "C"
{
#endif
 
extern void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);
extern void initModules(void);
 
#ifdef __cplusplus
}
#endif
 
#endif /* INIT_H_ */
#include "Init.h"
#include "Workers/SC20MPB.h"
 
#ifdef __cplusplus
extern "C"
{
#endif
 
static SC20MPB *gpCamera = nullptr;
 
static void createCamera();
 
void initModules(void)
{
	createCamera();
}
 
static void createCamera()
{
	if (nullptr == gpCamera)
	{
		static SC20MPB camera(&huart1);
		gpCamera = &camera;
//		gpCamera->setUARTHandle(&huart1); // stupid must be deleted
	}
}
 
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if (nullptr != gpCamera)
	{
		gpCamera->captureImageCmd();
	}
}
 
#ifdef __cplusplus
}
;
#endif

I have also tried adding 'initModules();' to freertos.c, but somehow i encounter the same problem. Please let me know if I should add any more pieces of code.

2 REPLIES 2
Danish1
Lead III

I have a few thoughts:

  1. You might not have given enough stack space to your project. Quite often, by default, only about 0.5k is allocated to the stack (so one can build even on the smallest of stm32f0) but the camera() call might need quite a lot more than that.
  2. You are calling camera() before HAL_Init(), SystemClock_Config(), MX_GPIO_Init(), MX_IWDG_Init(), MX_USART1_UART_Init(). If the camera() call actually tries to do anything (e.g. check that the camera is present on huart1, reset it) then it will fail because uart1 hasn't been initialised.
  3. If you get an external interrupt as soon as either MX_GPIO_Init() or MX_IWDG_Init() are called i.e. before MX_USART1_UART_Init(), then you will call gpCamera->captureImageCmd() and that will fail as uart1 isn't set up

Have you tried placing a breakpoint and then single-stepping through your code to see how far it gets?

Hope this helps,

Danish

Thanks fot your feedback Danish, i managed to debug further and narrow it down to me not resetting the watchdog anywhere. I am yet unsure how and where to do this, so i went about and deactivated the watchdog for now. I will add it later, once i am better accustomed to this environment and have solved other bugs.

For now, i am stuck with a problem regarding the response i get over UART from a camera. I've written a generic command issuing function but i cannot seem to be able to receive all bytes that the camera should send according to its manual and my previous experience working with it. Will attach some code with the hopes that someone might shed some light as to how i should use UART.

#ifndef WORKERS_SC20MPB_H_
#define WORKERS_SC20MPB_H_
 
#include <Workers/BaseCamera.h>
 
class SC20MPB: public BaseCamera
{
public:
	SC20MPB(UART_HandleTypeDef* inHandle);
	virtual ~SC20MPB();
	void captureImageCmd() override;
 
	void setUARTHandle(UART_HandleTypeDef* handle) override;
protected:
 
private:
	void readImageLengthCmd() override;
	void readImageDataCmd() override;
	void resetCameraCmd() override;
	void genericCmdIssue(u8 * cmd, u8 byteToSend, u8 bytesToReceive) override;
	void stopCaptureCmd() override;
	void setImageCompressionCmd(u8 compression) override;
 
	UART_HandleTypeDef* handle;
	volatile u8 rxBuffer[MAX_RX_BUFFER_SIZE];
	u8 captureImageBytes[5] = {0x56, 0x00, 0x36, 0x01, 0x00};
	u8 stopCaptureBytes[5] = {0x56, 0x00, 0x36, 0x01, 0x03};
	u8 setCompressionBytes[9] = {0x56, 0x00, 0x31, 0x05, 0x01, 0x01, 0x12, 0x04, 0x00};
};
 
#endif /* WORKERS_SC20MPB_H_ */
#include <Workers/SC20MPB.h>
 
SC20MPB::SC20MPB(UART_HandleTypeDef *inHandle) :
		handle(inHandle), rxBuffer
		{ }
{
	// TODO Auto-generated constructor stub
 
}
 
SC20MPB::~SC20MPB()
{
	// TODO Auto-generated destructor stub
}
 
void SC20MPB::captureImageCmd()
{
	genericCmdIssue(captureImageBytes, sizeof(captureImageBytes) / sizeof(u8),
			5);
}
 
void SC20MPB::resetCameraCmd()
{
 
}
 
void SC20MPB::readImageLengthCmd()
{
 
}
 
void SC20MPB::readImageDataCmd()
{
 
}
 
void SC20MPB::genericCmdIssue(u8 *cmd, u8 byteToSend, u8 bytesToReceive)
{
	if (nullptr == handle)
	{
		return;
	}
 
	auto result = HAL_UART_Transmit_IT(handle, cmd, byteToSend);
 
	if (HAL_OK != result)
	{
		return;
	}
 
	result = HAL_UART_Receive_IT(handle, (u8*) rxBuffer, bytesToReceive);
}
 
void SC20MPB::setUARTHandle(UART_HandleTypeDef *handle)
{
	this->handle = handle;
}
 
void SC20MPB::stopCaptureCmd()
{
	genericCmdIssue(stopCaptureBytes, sizeof(stopCaptureBytes) / sizeof(u8), 5);
}
 
void SC20MPB::setImageCompressionCmd(u8 compression)
{
	genericCmdIssue(setCompressionBytes,
			sizeof(setCompressionBytes) / sizeof(u8), 5);
}

The only way i can get some bytes written to my buffer is through HAL_UART_Receive_IT. If i am to use either HAL_UART_Receive or HAL_UART_Receive_DMA i only get an empty rxBuffer. However, even with HAL_UART_Receive_IT i still only get 2 or 3 bytes at most and never on the first command issued. Please ignore the hardcoded commands and return dimension, i only wanted to make sure that everything works before properly implementing them.