I am new to FreeRTOS, and I am busy with a large project. I noticed that HAL_Delay() gave problems on certain parts and I changed them if possible to osDelay(). However, I am now putting the files togetherand when I compile the code it give me a few warnings but when I try to debug, it gives me a hardfault when it starts initializing the MX_UART8_Init() in the main.
So it even doesn’t get to the osKernelInitialize(); and so on. I don’t know why this happend and hope I get help from this forum.
Below I have inserted the main.c. The ide I use is stmcubeide V1.16.1 with the cmsis V2.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.cpp
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2023 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include <cstdio>
#include <iostream>
#include <cstdint>
#include "main.h"
#include "cmsis_os.h"
//standard HAL libraries
#include "systemClock.h"
#include "adc.h"
#include "bdma.h"
#include "dma.h"
#include "i2c.h"
#include "mdma.h"
#include "memorymap.h"
#include "octospi.h"
#include "rtc.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "usb_device.h"
#include "gpio.h"
#include "stm32h7xx_ll_dma.h"
#include "stm32h723xx.h"
#include "usbd_cdc.h"
#include "usbd_cdc_if.h"
#include "usbd_core.h"
#include "stm32_error_handler.h"
#include "callbacks.h"
#if defined(USE_FULL_ASSERT)
#include "stm32_assert.h"
#endif /* USE_FULL_ASSERT */
//user libraries
#include "generic.h"
#include "rtc.hpp"
#include "dataStorage.hpp"
#include "setpointManager.hpp"
#include "xLDRefpres.hpp"
#include "ADS131A04.hpp"
#include "rs485.hpp"
#include "usb.h"
#include "userButton.hpp"
#include "dataLogger.hpp"
#include "securityManager.hpp"
#include "modbus.hpp"
#include "statusManager.hpp"
#include "sensorControll.hpp"
#include "DAC_1_4.hpp"
#include "statusLed.hpp"
#include "flashCommands.hpp"
//#ifndef NVIC_PRIORITYGROUP_0
// #define NVIC_PRIORITYGROUP_0 ((uint32_t)0x00000007) /*!< 0 bit for pre-emption priority,
// 4 bits for subpriority */
// #define NVIC_PRIORITYGROUP_1 ((uint32_t)0x00000006) /*!< 1 bit for pre-emption priority,
// 3 bits for subpriority */
// #define NVIC_PRIORITYGROUP_2 ((uint32_t)0x00000005) /*!< 2 bits for pre-emption priority,
// 2 bits for subpriority */
// #define NVIC_PRIORITYGROUP_3 ((uint32_t)0x00000004) /*!< 3 bits for pre-emption priority,
// 1 bit for subpriority */
// #define NVIC_PRIORITYGROUP_4 ((uint32_t)0x00000003) /*!< 4 bits for pre-emption priority,
// 0 bit for subpriority */
//#endif
//defines ----------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif
void HAL_Delay(uint32_t Delay);
uint32_t HAL_GetTick(void);
void StartStatusLedThread(void *argument);
void StartSensorControlThread(void *argument);
void StartAdcSensorThread(void *argument);
void StartRefSensorThread(void *argument);
void StartSetpointThread(void *argument);
void StartAnalogOutThread(void *argument);
void StartStatusThread(void *argument);
void StartLogThread(void *argument);
void StartSecurityThread(void *argument);
void StartButtonThread(void *argument);
void StartModbusThread(void *argument);
//void StartWatchDogThread(void *argument);
//macros ----------------------------------------------------------
extern "C"
{
int _write(int file, char *ptr, int len)
{
int i=0;
for(i=0; i<len; i++)
{
ITM_SendChar((*ptr++));
}
return len;
}
} /*extern "C"*/
//definition of threads
osThreadId_t StatusLedHandler;
const osThreadAttr_t StatusLed_attributes = {.name = "StatusLedThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t SensorControlHandler;
const osThreadAttr_t SensorControl_attributes = {.name = "SensorControlThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t AdcSensorHandler;
const osThreadAttr_t AdcSensor_attributes = {.name = "AdcSensorThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t RefSensorHandler;
const osThreadAttr_t RefSensor_attributes = {.name = "RefSensorThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t SetpointHandler;
const osThreadAttr_t Setpoint_attributes = {.name = "SetpointThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t AnalogOutHandler;
const osThreadAttr_t AnalogOut_attributes = {.name = "AnalogOutThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t StatusHandler;
const osThreadAttr_t Status_attributes = {.name = "StatusThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t LogHandler;
const osThreadAttr_t Log_attributes = {.name = "LogThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t SecurityHandler;
const osThreadAttr_t Security_attributes = {.name = "SecurityThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t ButtonHandler;
const osThreadAttr_t Button_attributes = {.name = "ButtonThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
osThreadId_t ModbusHandler;
const osThreadAttr_t Modbus_attributes = {.name = "ModbusThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
//osThreadId_t WatchDogHandler;
//const osThreadAttr_t WatchDog_attributes = {.name = "WatchDogThread", .stack_size = 128 * 4, .priority = (osPriority_t) osPriorityNormal};
//definition of the ms timer
osTimerId_t oneMsTimerHandle;
const osTimerAttr_t oneMsTimer_attributes = {.name = "msTimer"};
//definition of mutex
osMutexId_t eqDaMutexHandler;
const osMutexAttr_t eqDaMutex_attributes = {.name = "eqDaMutex"};
rtcTimer rtc;
//main code ---------------------------------------------------------
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
//Reset of all peripherals, Initializes the Flash interface and the Systick.
HAL_Init();
//Configure the system clock
SystemClock_Config();
//Configure the peripherals common clocks
PeriphCommonClock_Config();
//Initialize all configured peripherals
MX_GPIO_Init();
MX_DMA_Init();
MX_BDMA_Init();
MX_MDMA_Init();
MX_ADC2_Init();
MX_ADC3_Init();
MX_ADC1_Init();
MX_TIM1_Init();
MX_I2C2_Init();
MX_I2C3_Init();
MX_OCTOSPI1_Init();
MX_SPI4_Init();
MX_SPI6_Init();
MX_UART8_Init();
MX_RTC_Init();
MX_USB_DEVICE_Init();
rtc.rtcInit();
//Init scheduler
osKernelInitialize();
sd.setUint32ValueName( paramNames::INFO_SOFTWARE_VS, SoftwareVersion ); //serienummer wordt per EQ_DA ingesteld bij fabrieks-setup
sd.setUint32ValueName( paramNames::INFO_HARDWARE_VS, HardwareVersion );
sd.setUint32ValueName( paramNames::INFO_PARAM_VS, ParameterVersion );
HAL_GPIO_WritePin( LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_SET );
HAL_GPIO_WritePin( LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_SET );
HAL_GPIO_WritePin( LED_B_GPIO_Port, LED_B_Pin, GPIO_PIN_SET );
//Wait for everything to be inited
// HAL_Delay(100);
//Creation of the ms timer
oneMsTimerHandle = osTimerNew(timerCallback, osTimerPeriodic, NULL, &oneMsTimer_attributes);
//Creation of the mutex
eqDaMutexHandler = osMutexNew(&eqDaMutex_attributes);
//Create the threads
SensorControlHandler = osThreadNew(StartSensorControlThread, NULL, &SensorControl_attributes);
AdcSensorHandler = osThreadNew(StartAdcSensorThread, NULL, &AdcSensor_attributes);
RefSensorHandler = osThreadNew(StartRefSensorThread, NULL, &RefSensor_attributes);
SetpointHandler = osThreadNew(StartSetpointThread, NULL, &Setpoint_attributes);
AnalogOutHandler = osThreadNew(StartAnalogOutThread, NULL, &AnalogOut_attributes);
StatusHandler = osThreadNew(StartStatusThread, NULL, &Status_attributes);
LogHandler = osThreadNew(StartLogThread, NULL, &Log_attributes);
SecurityHandler = osThreadNew(StartSecurityThread, NULL, &Security_attributes);
ButtonHandler = osThreadNew(StartButtonThread, NULL, &Button_attributes);
ModbusHandler = osThreadNew(StartModbusThread, NULL, &Modbus_attributes);
//release the semaphore mutex
osMutexRelease(eqDaMutexHandler);
//Start scheduler
osKernelStart();
//We should never get here as control is now taken by the scheduler
//Infinite loop
while (1)
{
osDelay(1000);
HAL_GPIO_WritePin( LED_R_GPIO_Port, LED_R_Pin, GPIO_PIN_RESET ); //turn off the rgb led if something goes wrong
HAL_GPIO_WritePin( LED_G_GPIO_Port, LED_G_Pin, GPIO_PIN_RESET );
HAL_GPIO_WritePin( LED_B_GPIO_Port, LED_B_Pin, GPIO_PIN_RESET );
}
}
void StartStatusLedThread(void *argument)
{
osTimerStart(oneMsTimerHandle, 75); //start the ms timer
while(1)
{
osDelay(1000);
}
}
void StartSensorControlThread(void *argument)
{
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
sensorControll inputA( sd.getDataBoolName(paramNames::EXT_SENSOR_A_ENABLE_CHANNEL), CHAN_EN_CH1_GPIO_Port, CHAN_EN_CH1_Pin,
sd.getDataBoolName(paramNames::EXT_SENSOR_A_ENABLE_VIRT_GND), VIRT_GND_nEN_CH1_GPIO_Port, VIRT_GND_nEN_CH1_Pin,
sd.getDataUint16Name(paramNames::EXT_SENSOR_A_SENSOR_SIGNAL_TYPE), mA_EN_CH1_GPIO_Port, mA_EN_CH1_Pin);
inputA.run();
sensorControll inputB( sd.getDataBoolName(paramNames::EXT_SENSOR_B_ENABLE_CHANNEL), CHAN_EN_CH2_GPIO_Port, CHAN_EN_CH2_Pin,
sd.getDataBoolName(paramNames::EXT_SENSOR_B_ENABLE_VIRT_GND), VIRT_GND_nEN_CH2_GPIO_Port, VIRT_GND_nEN_CH2_Pin,
sd.getDataUint16Name(paramNames::EXT_SENSOR_B_SENSOR_SIGNAL_TYPE), mA_EN_CH2_GPIO_Port, mA_EN_CH2_Pin);
inputB.run();
sensorControll inputC( sd.getDataBoolName(paramNames::EXT_SENSOR_C_ENABLE_CHANNEL), CHAN_EN_CH3_GPIO_Port, CHAN_EN_CH3_Pin,
sd.getDataBoolName(paramNames::EXT_SENSOR_C_ENABLE_VIRT_GND), VIRT_GND_nEN_CH3_GPIO_Port, VIRT_GND_nEN_CH3_Pin,
sd.getDataUint16Name(paramNames::EXT_SENSOR_C_SENSOR_SIGNAL_TYPE), mA_EN_CH3_GPIO_Port, mA_EN_CH3_Pin);
inputC.run();
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartAdcSensorThread(void *argument)
{
DMA_HandleTypeDef SPI4_RX;
DMA_HandleTypeDef SPI4_TX;
static ADS131A04 spi_ADC(hspi4, SPI4_TX, SPI4_RX,ADC_nCS_GPIO_Port, ADC_nCS_Pin);
hspi4.hdmarx = &SPI4_RX;
hspi4.hdmatx = &SPI4_TX;
HAL_GPIO_WritePin( ADC_RESET_GPIO_Port, ADC_RESET_Pin, GPIO_PIN_SET );
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
spi_ADC.run();
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartRefSensorThread(void *argument)
{
uint8_t busAddress = 0x40;
DMA_HandleTypeDef i2c3DmaRecv;
DMA_HandleTypeDef i2c3DmaSend;
I2C_HandleTypeDef hi2c3;
static xLDRefpres refP(busAddress, hi2c3, i2c3DmaRecv, i2c3DmaSend, MTF_RESET_GPIO_Port, MTF_RESET_Pin);
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
refP.run();
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartSetpointThread(void *argument)
{
static setpointManager spm(sd, rtc);
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
spm.getSetpoint(sd, rtc); //needed variablen are saved in dataStorage
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartAnalogOutThread(void *argument)
{
DAC_1_4 analogOut(*sd.getDataFloatName(paramNames::XTR305VALUE), hspi6, DAC_SS_GPIO_Port, DAC_SS_Pin, XTR_M1_GPIO_Port, XTR_M1_Pin, XTR_M2_GPIO_Port, XTR_M2_Pin, XTR_OD_GPIO_Port, XTR_OD_Pin);
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
analogOut.run();
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartStatusThread(void *argument)
{
static statusManager statm;
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
statm.manage(sLed);
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartLogThread(void *argument)
{
dataLogger dlog;
flashCommands fcmd;
dlog.logInit(sd, fcmd);
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
dlog.run(sd, fcmd);
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartSecurityThread(void *argument)
{
static security scrty;
static tps2660x tps;
static sht30Sensor sht30;
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
scrty.checkSafety(sd, sht30, tps);
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartButtonThread(void *argument)
{
userButton button;
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
button.checkUserButton();
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
void StartModbusThread(void *argument)
{
modbus mb(sd);
flashCommands fcmd;
rs485 rs;
sht30Sensor sht30;
dataLogger dlog;
rs.init();
while(1)
{
osMutexAcquire(eqDaMutexHandler, osWaitForever);
mb.sessionStateMachine(fcmd, rs, sht30, dlog, sd);
osMutexRelease(eqDaMutexHandler);
osDelay(1000);
}
osThreadTerminate(NULL);
}
// HAL_Delay is used mostly in device init and config
void HAL_Delay(uint32_t Delay)
{
vTaskDelay(Delay);
}
uint32_t HAL_GetTick(void)
{
return xTaskGetTickCount();
}
#ifdef __cplusplus
}
#endif