HardFault_Handler when trying to run ai_network_run
Hi ,
I go into the hardfault handler when trying to run the ai_network_run which I call inside my run_inference function which is inside my ADC ISR , then it calls ai_platform_network_process , that is where we get thrown into the HardFault Handler . here is my code in case anyone has improvements please don’t hesitate to reply .
Note : I tried all the previously mentioned suggestions like clocking CRC and increasing stack size , I increased both stack size and heap size to 0x8000 .
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2024 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 "main.h"
#include "app_x-cube-ai.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "ai_platform.h"
#include <stdio.h>
#include <string.h>
#include "network.h"
#include "network_data.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
MDF_HandleTypeDef AdfHandle0;
MDF_FilterConfigTypeDef AdfFilterConfig0;
CRC_HandleTypeDef hcrc;
DCACHE_HandleTypeDef hdcache1;
I2C_HandleTypeDef hi2c1;
I2C_HandleTypeDef hi2c2;
OSPI_HandleTypeDef hospi1;
OSPI_HandleTypeDef hospi2;
SPI_HandleTypeDef hspi2;
TIM_HandleTypeDef htim3;
UART_HandleTypeDef huart4;
UART_HandleTypeDef huart5;
UART_HandleTypeDef huart1;
PCD_HandleTypeDef hpcd_USB_OTG_FS;
/* USER CODE BEGIN PV */
//ai_u8 data_activations0[AI_NETWORK_DATA_ACTIVATION_1_SIZE];
ai_buffer ai_input[AI_NETWORK_IN_NUM];
ai_buffer ai_output[AI_NETWORK_OUT_NUM];
float input_data[AI_NETWORK_IN_1_SIZE]; // Input buffer
float output_data[AI_NETWORK_OUT_1_SIZE]; // Output buffer
ai_handle network = AI_HANDLE_NULL;
ai_error err;
#define ADC_BUFFER_SIZE 180 // Number of ADC samples for one ECG input
static uint16_t adc_buffer[ADC_BUFFER_SIZE];
static uint16_t sample_index = 0;
uint8_t normal_flag = 0;
uint8_t abnormal_flag = 0;
// UART buffer
char buf[100];
int buf_len = 0;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void SystemPower_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADF1_Init(void);
static void MX_I2C1_Init(void);
static void MX_I2C2_Init(void);
static void MX_ICACHE_Init(void);
static void MX_OCTOSPI1_Init(void);
static void MX_OCTOSPI2_Init(void);
static void MX_SPI2_Init(void);
static void MX_UART4_Init(void);
void MX_USART1_UART_Init(void);
static void MX_UCPD1_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
static void MX_ADC1_Init(void);
static void MX_DCACHE1_Init(void);
static void MX_UART5_Init(void);
static void MX_CRC_Init(void);
static void MX_TIM3_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* 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 Power */
SystemPower_Config();
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
// Enable CRC clock (important for AI network initialization)
//__HAL_RCC_CRC_CLK_ENABLE();
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADF1_Init();
MX_I2C1_Init();
MX_I2C2_Init();
MX_ICACHE_Init();
MX_OCTOSPI1_Init();
MX_OCTOSPI2_Init();
MX_SPI2_Init();
MX_UART4_Init();
MX_USART1_UART_Init();
MX_UCPD1_Init();
MX_USB_OTG_FS_PCD_Init();
MX_ADC1_Init();
MX_DCACHE1_Init();
MX_UART5_Init();
MX_CRC_Init();
MX_TIM3_Init();
MX_X_CUBE_AI_Init();
/* USER CODE BEGIN 2 */
__HAL_RCC_CRC_CLK_ENABLE();
ai_handle network = AI_HANDLE_NULL;
ai_error err;
ai_network_params ai_params = {
AI_NETWORK_DATA_WEIGHTS(ai_network_data_weights_get()),
AI_NETWORK_DATA_ACTIVATIONS(data_activations0)
};
// Create and initialize the network
// err = ai_network_create_and_init(&network, data_activations0, NULL);
// if (err.type != AI_ERROR_NONE) {
// printf("AI Network Init Failed\r\n");
// Error_Handler(); // Handle initialization failure
// }
err = ai_network_create(&network, AI_NETWORK_DATA_CONFIG);
if (err.type != AI_ERROR_NONE) {
HAL_UART_Transmit(&huart5, (uint8_t *)"Network Creation Failed\r\n", 25, HAL_MAX_DELAY);
Error_Handler();
}
if (!ai_network_init(network, &ai_params)) {
HAL_UART_Transmit(&huart5, (uint8_t *)"Network Init Failed\r\n", 22, HAL_MAX_DELAY);
Error_Handler();
}
//buf_len = sprintf(buf, "AI Network Initialized\r\n");
//HAL_UART_Transmit(&huart5, (uint8_t *)buf, buf_len, 100);
//calibrate ADC for better accuracy and start it with interrupt
if(HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) != HAL_OK)
Error_Handler();
if(HAL_ADC_Start_IT(&hadc1) != HAL_OK)
Error_Handler();
//start PWM Generation
if(HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)
Error_Handler();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_Delay(4000); // Delay between classifications
if (normal_flag) {
normal_flag = 0;
HAL_UART_Transmit(&huart5, (uint8_t *)"Normal Heartbeat Detected!\r\n", 30, HAL_MAX_DELAY);
}
if (abnormal_flag) {
abnormal_flag = 0;
HAL_UART_Transmit(&huart5, (uint8_t *)"Abnormal Heartbeat Detected!\r\n", 32, HAL_MAX_DELAY);
}
/* USER CODE END WHILE */
MX_X_CUBE_AI_Process();
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/* USER CODE BEGIN 4 */
void run_inference(void) {
ai_error err;
ai_i32 nbatch;
// Check if network is valid, if not, recreate it
if (network == AI_HANDLE_NULL) {
printf("Reinitializing network...\r\n");
// Recreate and reinitialize the network
err = ai_network_create_and_init(&network, data_activations0, NULL);
if (err.type != AI_ERROR_NONE) {
printf("AI Network Init Failed\r\n");
Error_Handler(); // Handle initialization failure
}
}
for (int i = 0; i < ADC_BUFFER_SIZE; i++) {
input_data[i] = (float)adc_buffer[i] / 16384.0f; // Normalize ADC values
}
// Initialize AI input and output buffers without using n_batches
ai_input[0].data = AI_HANDLE_PTR(input_data);
ai_output[0].data = AI_HANDLE_PTR(output_data);
// Run the inference on the network
nbatch = ai_network_run(network, ai_input, ai_output);
if (nbatch != 1) {
// If inference fails, print error message and return
HAL_UART_Transmit(&huart5, (uint8_t *)"Error: Inference failed!\r\n", 26, HAL_MAX_DELAY);
return;
}
// Get the inference result and print classification result
if (output_data[0] > 0.5f) {
// Abnormal heartbeat detected
HAL_UART_Transmit(&huart5, (uint8_t *)"Abnormal Heartbeat Detected!\r\n", 30, HAL_MAX_DELAY);
abnormal_flag = 1;
} else {
// Normal heartbeat detected
HAL_UART_Transmit(&huart5, (uint8_t *)"Normal Heartbeat Detected!\r\n", 27, HAL_MAX_DELAY);
normal_flag = 1;
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if (hadc->Instance == ADC1) {
if (sample_index < ADC_BUFFER_SIZE) {
adc_buffer[sample_index++] = HAL_ADC_GetValue(&hadc1); // Store ADC value
}
if (sample_index >= ADC_BUFFER_SIZE) {
// Once buffer is full, run inference
run_inference();
sample_index = 0; // Reset the sample index for the next reading
}
}
}
