Initializing LwIP causes RTOS to stop working - freertos

Good day
The goal:
I am trying to configure FreeRTOS and LwIP so that I can set up MQTT.
I am using a STM32-NucleoF429ZI development board
What I have done:
I am using CubeMX to generate project files and I am using Visual Studio and VisualGDB for compiling and debugging.
I have set up FreeRTOS for the dev board using CMSIS_V2 and Heap_4.
I have set up LwIP with: Static IP and MEM_SIZE of 1024*10
I have kept all standard pinout (i.e. I have note cleared pinouts) of nucleo board
Ive set up an "Ethernet" thread and I am blinking and LED on the ethernet thread and the default thread.
Other than that no other setting has been changed. I did not set the MPU because as far as I can tell, this MCU does not have it.
The problem:
If I comment out the line MX_LWIP_Init();, (which cubeMX puts into the default thread), then the board runs fine and both LED's on both threads blink forever as far as I have tested. However, as soon as I leave MX_LWIP_Init();, FreeRTOS gets stuck as shown in the picture.
This occurs anywhere from 30 seconds to many minutes after powering the board
Please excuse the picture, but it shows where exactly the program is when I pause it. If I resume the debugger and pause it again, it always pauses in the same place.
I have tried moving MX_LWIP_Init(); into main.c with the other init functions and also into the ethernet thread where it should belong. All produce the same error at some point.
I can ping the board once I add MX_LWIP_Init();
freertos.c
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* #attention
*
* Copyright (c) 2022 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 "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "config.h"
#include "EthernetLwIP_thread.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 ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 128 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
extern void MX_LWIP_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/**
* #brief FreeRTOS initialization
* #param None
* #retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* USER CODE BEGIN RTOS_THREADS */
if (EthernetModule_Init() == Result_Successful)
{
logger("template module successfully initialized!!!");
}
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* #brief Function implementing the defaultTask thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* init code for LWIP */
//MX_LWIP_Init();
/* USER CODE BEGIN StartDefaultTask */
// Task timing
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
const TickType_t xDelay_Ticks = 1000; // Current RTOS clock config has 1 tick equal 1ms. Thus 20 ticks sets a frequency of 50Hz
/* Infinite loop */
while (1)
{
vTaskDelayUntil(&xLastWakeTime, xDelay_Ticks); // waits until a certain number of ticks have passed before it starts this task again in a timely manner
HAL_GPIO_TogglePin(LED_BLUE_PORT, LED_BLUE_PIN);
//HAL_GPIO_TogglePin(LED_RED_PORT, LED_RED_PIN);
//HAL_GPIO_TogglePin(LED_GREEN_PORT, LED_GREEN_PIN);
}
/* USER CODE END StartDefaultTask */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */
Ethernet src file
/* Ethernet_thread.c */
// Includes: ----------------------------------------------------------
#include "EthernetLwIP_thread.h"
#include "config.h"
// Instantiations: ----------------------------------------------------
// Thread declaration: ------------------------------------------------
osThreadId_t EthernetModule_ThreadId;
const osThreadAttr_t EthernetModule_Attributes = {
.name = "EthernetModule",
.priority = (osPriority_t) osPriorityHigh,
.stack_size = 1024 * 4 // This needs to be optimized at a later stage
};
void EthernetModule_Thread(void *argument);
// Functions: --------------------------------------------------------
// Initializing functions: ---------------------------------------------------------------------
MResult EthernetModule_HardwareInit()
{
return Result_Successful;
}
MResult EthernetModule_Init() {
MX_LWIP_Init();
if (EthernetModule_HardwareInit() == Result_Error)
return Result_Error;
EthernetModule_ThreadId = osThreadNew(EthernetModule_Thread, NULL, &EthernetModule_Attributes);
if (EthernetModule_ThreadId == NULL)
return Result_Error;
return Result_Successful;
}
// Thread: ---------------------------------------------------------------------------------------
void EthernetModule_Thread(void *argument)
{
// Task timing
TickType_t xLastWakeTime;
xLastWakeTime = xTaskGetTickCount();
const TickType_t xDelay_Ticks = 500;
while (1)
{
vTaskDelayUntil(&xLastWakeTime, xDelay_Ticks);
HAL_GPIO_TogglePin(LED_GREEN_PORT, LED_GREEN_PIN);
}
}

I am not sure the cause of this problem, but I have changed from FreeRTOS CMSIS_V2 to CMSIS_V1 and it resolved the issue. I dont know if there is a configuration in CMSIS_V2 that was wrong, or if there is an actual bug, but CMSIS_V1 and LwIP works great now.

Related

I have a problem reading ADC with DMA on STM32 F767zi. When I look into the buffer, all I see are zeros, and I do not know why?

The size of my buffer is 4096 and I want to fill the buffer with the adc values that are read.
#define ADC_BUF_LEN 4096
uint16_t adc_buf[ADC_BUF_LEN];
I am using this function to start the reading process of the ADC using DMA
HAL_ADC_Start_DMA(&hadc2, (uint32_t*)adc_buf, ADC_BUF_LEN);
Here are my configurations for the ADC
hadc2.Instance = ADC2;
hadc2.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV6;
hadc2.Init.Resolution = ADC_RESOLUTION_12B;
hadc2.Init.ScanConvMode = ADC_SCAN_DISABLE;
hadc2.Init.ContinuousConvMode = ENABLE;
hadc2.Init.DiscontinuousConvMode = DISABLE;
hadc2.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc2.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc2.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc2.Init.NbrOfConversion = 1;
hadc2.Init.DMAContinuousRequests = ENABLE;
hadc2.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
if (HAL_ADC_Init(&hadc2) != HAL_OK)
{
Error_Handler();
}
This my DMA configuration
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
/* DMA2_Stream2_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
}
These are my interrupt functions. I set a toggle breakpoint on the first interrupt and when I debug, the LED does not turn on which suggests that the DMA isn't working?
/* USER CODE BEGIN 4 */
//Called when first half of buffer is filled
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc) {
//HAL_ADC_GetValue(&hadc2);
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
}
//Called when buffer is completely filled
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc){
HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
}
I set the prescaled to be divided by 6 if this information helps.
Please give me some advice!
Thank you in advance.

Using both CAN1 & CAN2 both in STM32F446 properly?

I want to use both CAN1 and CAN2 for my application with 500kbps and 125kbps speeds respectively. I have initialized both of them as per my requirements using HAL. Where in Tx is implemented in polling and Rx in interrupts. CAN1 Tx and Rx working perfect. Coming to CAN2 Tx is working and Rx is not working. Interrupt itself is not firing up for CAN2 Rx (HAL_CAN_RxFifo0MsgPendingCallback is not being called). I've read in datasheet that SRAM sharing process is happening between 2 CANs. I'm unable to comprehend that. Is that an issue?
I'm attaching the code also. Please check and help!
Little overview - all MCU clocks running at - 16 MHz using internal HSI, No filter in CAN configs
################ MAIN FILE ####################
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;
/* USER CODE BEGIN PV */
CAN_TxHeaderTypeDef txheader;
uint8_t txdata[8];
CAN_RxHeaderTypeDef RxHeader;
uint8_t RxData[8];
CAN_TxHeaderTypeDef txheader1;
uint8_t txdata1[8];
CAN_RxHeaderTypeDef RxHeader1;
uint8_t RxData1[8];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);
static void MX_CAN2_Init(void);
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t fill = 0;
/* 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_CAN1_Init();
MX_CAN2_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
txheader.DLC = 8;
txheader.ExtId = 0x11111111;
txheader.IDE = CAN_ID_EXT;
txheader.RTR = CAN_RTR_DATA;
for(uint8_t i = 0; i<8;i++)
{
txdata[i] = i;
}
// txdata[0] = fill;
HAL_Delay(250);
HAL_CAN_AddTxMessage(&hcan1,&txheader,txdata, (uint32_t *)CAN_TX_MAILBOX0);
HAL_Delay(250);
HAL_CAN_AddTxMessage(&hcan2,&txheader,txdata, (uint32_t *)CAN_TX_MAILBOX0);
}
/* USER CODE END 3 */
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
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_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
/**
* #brief CAN1 Initialization Function
* #param None
* #retval None
*/
static void MX_CAN1_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
CAN_FilterTypeDef sFilterConfig;
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 2;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = DISABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
HAL_CAN_Start(&hcan1);
/*##-4- Activate CAN RX notification #######################################*/
if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
/* USER CODE END CAN1_Init 2 */
}
/**
* #brief CAN1 Initialization Function
* #param None
* #retval None
*/
static void MX_CAN2_Init(void)
{
/* USER CODE BEGIN CAN1_Init 0 */
CAN_FilterTypeDef sFilterConfig;
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 8;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_13TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE;
hcan2.Init.AutoWakeUp = DISABLE;
hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
sFilterConfig.FilterBank = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
sFilterConfig.FilterIdHigh = 0x0000;
sFilterConfig.FilterIdLow = 0x0000;
sFilterConfig.FilterMaskIdHigh = 0x0000;
sFilterConfig.FilterMaskIdLow = 0x0000;
sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
sFilterConfig.FilterActivation = ENABLE;
sFilterConfig.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(&hcan2, &sFilterConfig) != HAL_OK)
{
/* Filter configuration Error */
Error_Handler();
}
HAL_CAN_Start(&hcan2);
/*##-4- Activate CAN RX notification #######################################*/
if (HAL_CAN_ActivateNotification(&hcan2, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
{
/* Notification Error */
Error_Handler();
}
/* USER CODE END CAN1_Init 2 */
}
/**
* #brief GPIO Initialization Function
* #param None
* #retval None
*/
static void MX_GPIO_Init(void)
{
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOA_CLK_ENABLE();
}
/* USER CODE BEGIN 4 */
/**
* #brief Rx Fifo 0 message pending callback
* #param hcan: pointer to a CAN_HandleTypeDef structure that contains
* the configuration information for the specified CAN.
* #retval None
*/
uint8_t cflag;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
/* Get RX message */
if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
{
/* Reception Error */
Error_Handler();
}
/* Display LEDx */
if ((RxHeader.StdId == 0x321) && (RxHeader.IDE == CAN_ID_STD) && (RxHeader.DLC == 2))
{
}
/* Display LEDx */
if ((RxHeader.ExtId == 0x11111111) && (RxHeader.IDE == CAN_ID_EXT) && (RxHeader.DLC == 8))
{
cflag = 1;
}
else
cflag = 0;
}
/* USER CODE END 4 */
##################### MSP FILE ######################
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
static uint32_t HAL_RCC_CAN1_CLK_ENABLED=0;
/**
* #brief CAN MSP Initialization
* This function configures the hardware resources used in this example
* #param hcan: CAN handle pointer
* #retval None
*/
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hcan->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN CAN1_MspInit 1 */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
/* USER CODE END CAN1_MspInit 1 */
}
else if(hcan->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspInit 0 */
/* USER CODE END CAN2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_CAN2_CLK_ENABLE();
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB13 ------> CAN2_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* CAN2 interrupt Init */
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
/* USER CODE BEGIN CAN2_MspInit 1 */
/* USER CODE END CAN2_MspInit 1 */
}
}
/**
* #brief CAN MSP De-Initialization
* This function freeze the hardware resources used in this example
* #param hcan: CAN handle pointer
* #retval None
*/
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
{
if(hcan->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
else if(hcan->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspDeInit 0 */
/* USER CODE END CAN2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN2_CLK_DISABLE();
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
/**CAN2 GPIO Configuration
PB12 ------> CAN2_RX
PB13 ------> CAN2_TX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_12|GPIO_PIN_13);
/* CAN2 interrupt DeInit */
HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
/* USER CODE BEGIN CAN2_MspDeInit 1 */
/* USER CODE END CAN2_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
######################### IT FILE #############################
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan2;
/**
* #brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/**
* #brief This function handles CAN2 RX0 interrupt.
*/
void CAN2_RX0_IRQHandler(void)
{
/* USER CODE BEGIN CAN2_RX0_IRQn 0 */
/* USER CODE END CAN2_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan2);
/* USER CODE BEGIN CAN2_RX0_IRQn 1 */
/* USER CODE END CAN2_RX0_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/**
* #brief This function handles CAN1 RX0 interrupt request.
* #param None
* #retval None
*/
extern CAN_HandleTypeDef hcan1;
void CAN1_RX0_IRQHandler(void)
{
HAL_CAN_IRQHandler(&hcan1);
}
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
I solved my problem. Got help from ST community. Please refer to the link below.
https://community.st.com/s/feed/0D53W00000RQCwgSAH?t=1608012202888
Problem was filter configuration for CAN1 and CAN2. There are 28 filter banks (0-27) split between CAN1 and CAN2. First half (0-13) for CAN1 and the rest for CAN2. So just make some changes in the code posted above -
CAN 1:
sFilterConfig.FilterBank = 0;
:
sFilterConfig.SlaveStartFilterBank = 14;
CAN2:
sFilterConfig.FilterBank = 14; // previously 0
:
sFilterConfig.SlaveStartFilterBank = 14; // previously 27
Thanks to Lundin for suggesting sync point. Use this website for CAN Bit time calculations for various chips -
http://www.bittiming.can-wiki.info/

stm32 usart receive timeout

I am trying to read informations from a external sensor by USART, using a Nucleo stm32wb board. The sensor is using a 9600 baud rate and I know that it is fonctionnal. My pin connections are also good.
Furthermore, I can see on my logic analyzer that data are always sent.
The problem is that I always got a receive timeout no matter what timeout using.
Here is my code :
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 clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
HW_RTC_Init();
/* USER CODE BEGIN 2 */
int incomingBytes[100];
uint8_t d = 'a';
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
HAL_UART_Receive(&huart1, &d, 1, 1000);
if(d == 0x42){
incomingBytes[0] = d;
for(int i = 1;i<31;i++){
HAL_UART_Receive(&huart1, &d, 1, 1000);
incomingBytes[i] = d;
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief USART1 Initialization Function
* #param None
* #retval None
*/
static void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 9600;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
Any idea of what I could forgot?

STM32F411, FreeRTOS and CubeMX HardFault_Handler() after connecting to port

I need help with my project. I'm using Atollic TrueSTUDIO, CubeMX and FreeRTOS. I have project in which I recived data from ADC and I'm trying to send it by USB. Everything works fine until I open port at PC (I'm trying HTerm, RealTerm, etc), after that dubugging stops and HardFault_Handler() appears.
Here is my main.c (everything is generate by CubeMX for FreeRTOS:
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_hal.h"
#include "cmsis_os.h"
#include "usb_device.h"
/* USER CODE BEGIN Includes */
#include "usbd_cdc_if.h"
#include "time.h"
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_memtomem_dma2_stream0;
osThreadId defaultTaskHandle;
osThreadId sendTaskHandle;
osThreadId recivedTaskHandle;
osThreadId prepareTaskHandle;
osSemaphoreId myBinarySem01Handle;
osSemaphoreId myBinarySem02Handle;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
#define length 2048
uint16_t preparedData[(length/8)];
uint8_t dataToSend[(length/16)];
uint16_t recivedData[(length/2)];
uint8_t sendCounter = 0;
clock_t start, end;
int cpu_time_used = 0;
SemaphoreHandle_t xSemaphore = NULL;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART2_UART_Init(void);
void StartDefaultTask(void const * argument);
void StartSendTask(void const * argument);
void StartADCTask(void const * argument);
void StartPrepareTask(void const * argument);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* #brief The application entry point.
*
* #retval None
*/
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 clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* Create the semaphores(s) */
/* definition and creation of myBinarySem01 */
osSemaphoreDef(myBinarySem01);
myBinarySem01Handle = osSemaphoreCreate(osSemaphore(myBinarySem01), 1);
/* definition and creation of myBinarySem02 */
osSemaphoreDef(myBinarySem02);
myBinarySem02Handle = osSemaphoreCreate(osSemaphore(myBinarySem02), 1);
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* Create the thread(s) */
/* definition and creation of defaultTask */
osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 128);
defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
/* definition and creation of sendTask */
osThreadDef(sendTask, StartSendTask, osPriorityNormal, 0, 512);
sendTaskHandle = osThreadCreate(osThread(sendTask), NULL);
/* definition and creation of recivedTask */
osThreadDef(recivedTask, StartADCTask, osPriorityNormal, 0, 1024);
recivedTaskHandle = osThreadCreate(osThread(recivedTask), NULL);
/* definition and creation of prepareTask */
osThreadDef(prepareTask, StartPrepareTask, osPriorityNormal, 0, 1024);
prepareTaskHandle = osThreadCreate(osThread(prepareTask), NULL);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* 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 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 72;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
}
/* ADC1 init function */
static void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_12B;
hadc1.Init.ScanConvMode = ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 4;
hadc1.Init.DMAContinuousRequests = ENABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = 2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_12;
sConfig.Rank = 3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_13;
sConfig.Rank = 4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* USART2 init function */
static void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/**
* Enable DMA controller clock
* Configure DMA for memory to memory transfers
* hdma_memtomem_dma2_stream0
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* Configure DMA request hdma_memtomem_dma2_stream0 on DMA2_Stream0 */
hdma_memtomem_dma2_stream0.Instance = DMA2_Stream0;
hdma_memtomem_dma2_stream0.Init.Channel = DMA_CHANNEL_0;
hdma_memtomem_dma2_stream0.Init.Direction = DMA_MEMORY_TO_MEMORY;
hdma_memtomem_dma2_stream0.Init.PeriphInc = DMA_PINC_ENABLE;
hdma_memtomem_dma2_stream0.Init.MemInc = DMA_MINC_ENABLE;
hdma_memtomem_dma2_stream0.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_memtomem_dma2_stream0.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_memtomem_dma2_stream0.Init.Mode = DMA_NORMAL;
hdma_memtomem_dma2_stream0.Init.Priority = DMA_PRIORITY_LOW;
hdma_memtomem_dma2_stream0.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_memtomem_dma2_stream0.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_memtomem_dma2_stream0.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_memtomem_dma2_stream0.Init.PeriphBurst = DMA_PBURST_SINGLE;
if (HAL_DMA_Init(&hdma_memtomem_dma2_stream0) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/* DMA interrupt init */
/* DMA2_Stream4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream4_IRQn);
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(LD2_GPIO_Port, LD2_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin : B1_Pin */
GPIO_InitStruct.Pin = B1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(B1_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pin : LD2_Pin */
GPIO_InitStruct.Pin = LD2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LD2_GPIO_Port, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* #brief Function implementing the defaultTask thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void const * argument)
{
/* init code for USB_DEVICE */
MX_USB_DEVICE_Init();
/* USER CODE BEGIN 5 */
/* Infinite loop */
for(;;)
{
// vTaskResume( sendTaskHandle );
// vTaskResume( prepareTaskHandle );
// vTaskResume( recivedTaskHandle );
// vTaskSuspend( defaultTaskHandle );
}
/* USER CODE END 5 */
}
/* USER CODE BEGIN Header_StartSendTask */
/**
* #brief Function implementing the sendTask thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_StartSendTask */
void StartSendTask(void const * argument)
{
/* USER CODE BEGIN StartSendTask */
MX_USB_DEVICE_Init();
/* Infinite loop */
for(;;)
{
if( xSemaphoreTake( myBinarySem01Handle, ( TickType_t ) 100 ) )
{
HAL_GPIO_WritePin( LD2_GPIO_Port, LD2_Pin, !HAL_GPIO_ReadPin( LD2_GPIO_Port, LD2_Pin) );
volatile uint8_t send = CDC_Transmit_FS( dataToSend, (length/16) );
if( xSemaphoreGive( myBinarySem01Handle ) == pdTRUE )
{
taskYIELD();
}
} else {
taskYIELD();
}
}
/* USER CODE END StartSendTask */
}
/* USER CODE BEGIN Header_StartADCTask */
/**
* #brief Function implementing the recivedTask thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_StartADCTask */
void StartADCTask(void const * argument)
{
/* USER CODE BEGIN StartADCTask */
/* Infinite loop */
for(;;)
{
if( xSemaphoreTake( myBinarySem01Handle, ( TickType_t ) 100 ) )
{
HAL_GPIO_WritePin( LD2_GPIO_Port, LD2_Pin, !HAL_GPIO_ReadPin( LD2_GPIO_Port, LD2_Pin) );
for( int i = 0 ; i < (length/8) ; i++ ){
HAL_ADC_Start_DMA( &hadc1, recivedData, (length/2));
}
if( xSemaphoreGive( myBinarySem01Handle ) == pdTRUE )
{
taskYIELD();
}
} else {
taskYIELD();
}
}
/* USER CODE END StartADCTask */
}
/* USER CODE BEGIN Header_StartPrepareTask */
/**
* #brief Function implementing the prepareTask thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_StartPrepareTask */
void StartPrepareTask(void const * argument)
{
/* USER CODE BEGIN StartPrepareTask */
/* Infinite loop */
for(;;)
{
if( xSemaphoreTake( myBinarySem01Handle, ( TickType_t ) 100 ) )
{
HAL_GPIO_WritePin( LD2_GPIO_Port, LD2_Pin, !HAL_GPIO_ReadPin( LD2_GPIO_Port, LD2_Pin) );
volatile uint8_t counter = 0;
for( int i = 0; i < (length / ( 2 * 16 * 4)); i ++){
for( int j = 0; j < 16; j++){
preparedData[counter] += recivedData[i * 16 + j * 4];
preparedData[counter + 1] += recivedData[i * 16 + j * 4 + counter + 1];
preparedData[counter + 2] += recivedData[i * 16 + j * 4 + counter + 2];
preparedData[counter + 3] += recivedData[i * 16 + j * 4 + counter + 3];
}
counter += 4;
}
for( int i = 0; i < (length / 16); i += 2){
dataToSend[0 + i] = preparedData[i / 2] >> 8;
dataToSend[1 + i] = (preparedData[i / 2] << 8) >> 8;
}
if( xSemaphoreGive( myBinarySem01Handle ) == pdTRUE )
{
taskYIELD();
}
} else {
taskYIELD();
}
}
/* USER CODE END StartPrepareTask */
}
/**
* #brief This function is executed in case of error occurrence.
* #param file: The file name as string.
* #param line: The line in file as a number.
* #retval None
*/
void _Error_Handler(char *file, int line)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
while(1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* #brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* #param file: pointer to the source file name
* #param line: assert_param error line source number
* #retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
Here is my usbd_cdc_if.c:
/* Includes ------------------------------------------------------------------*/
#include "usbd_cdc_if.h"
/* USER CODE BEGIN INCLUDE */
/* USER CODE END INCLUDE */
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/** #addtogroup STM32_USB_OTG_DEVICE_LIBRARY
* #brief Usb device library.
* #{
*/
/** #addtogroup USBD_CDC_IF
* #{
*/
/** #defgroup USBD_CDC_IF_Private_TypesDefinitions USBD_CDC_IF_Private_TypesDefinitions
* #brief Private types.
* #{
*/
/* USER CODE BEGIN PRIVATE_TYPES */
/* USER CODE END PRIVATE_TYPES */
/**
* #}
*/
/** #defgroup USBD_CDC_IF_Private_Defines USBD_CDC_IF_Private_Defines
* #brief Private defines.
* #{
*/
/* USER CODE BEGIN PRIVATE_DEFINES */
/* Define size for the receive and transmit buffer over CDC */
/* It's up to user to redefine and/or remove those define */
#define APP_RX_DATA_SIZE 128
#define APP_TX_DATA_SIZE 128
/* USER CODE END PRIVATE_DEFINES */
/**
* #}
*/
/** #defgroup USBD_CDC_IF_Private_Macros USBD_CDC_IF_Private_Macros
* #brief Private macros.
* #{
*/
/* USER CODE BEGIN PRIVATE_MACRO */
/* USER CODE END PRIVATE_MACRO */
/**
* #}
*/
/** #defgroup USBD_CDC_IF_Private_Variables USBD_CDC_IF_Private_Variables
* #brief Private variables.
* #{
*/
/* Create buffer for reception and transmission */
/* It's up to user to redefine and/or remove those define */
/** Received data over USB are stored in this buffer */
uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
/** Data to send over USB CDC are stored in this buffer */
uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
/* USER CODE BEGIN PRIVATE_VARIABLES */
/* USER CODE END PRIVATE_VARIABLES */
/**
* #}
*/
/** #defgroup USBD_CDC_IF_Exported_Variables USBD_CDC_IF_Exported_Variables
* #brief Public variables.
* #{
*/
extern USBD_HandleTypeDef hUsbDeviceFS;
/* USER CODE BEGIN EXPORTED_VARIABLES */
/* USER CODE END EXPORTED_VARIABLES */
/**
* #}
*/
/** #defgroup USBD_CDC_IF_Private_FunctionPrototypes USBD_CDC_IF_Private_FunctionPrototypes
* #brief Private functions declaration.
* #{
*/
static int8_t CDC_Init_FS(void);
static int8_t CDC_DeInit_FS(void);
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);
static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
/* USER CODE BEGIN PRIVATE_FUNCTIONS_DECLARATION */
/* USER CODE END PRIVATE_FUNCTIONS_DECLARATION */
/**
* #}
*/
USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
{
CDC_Init_FS,
CDC_DeInit_FS,
CDC_Control_FS,
CDC_Receive_FS
};
/* Private functions ---------------------------------------------------------*/
/**
* #brief Initializes the CDC media low layer over the FS USB IP
* #retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Init_FS(void)
{
/* USER CODE BEGIN 3 */
/* Set Application Buffers */
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
return (USBD_OK);
/* USER CODE END 3 */
}
/**
* #brief DeInitializes the CDC media low layer
* #retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_DeInit_FS(void)
{
/* USER CODE BEGIN 4 */
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* #brief Manage the CDC class requests
* #param cmd: Command code
* #param pbuf: Buffer containing command data (request parameters)
* #param length: Number of data to be sent (in bytes)
* #retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length)
{
/* USER CODE BEGIN 5 */
switch(cmd)
{
case CDC_SEND_ENCAPSULATED_COMMAND:
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
break;
case CDC_SET_COMM_FEATURE:
break;
case CDC_GET_COMM_FEATURE:
break;
case CDC_CLEAR_COMM_FEATURE:
break;
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
case CDC_SET_LINE_CODING:
break;
case CDC_GET_LINE_CODING:
break;
case CDC_SET_CONTROL_LINE_STATE:
break;
case CDC_SEND_BREAK:
break;
default:
break;
}
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* #brief Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* #note
* This function will block any OUT packet reception on USB endpoint
* untill exiting this function. If you exit this function before transfer
* is complete on CDC interface (ie. using DMA controller) it will result
* in receiving more data while previous ones are still not sent.
*
* #param Buf: Buffer of data to be received
* #param Len: Number of data received (in bytes)
* #retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len)
{
/* USER CODE BEGIN 6 */
USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_CDC_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
/**
* #brief CDC_Transmit_FS
* Data to send over USB IN endpoint are sent over CDC interface
* through this function.
* #note
*
*
* #param Buf: Buffer of data to be sent
* #param Len: Number of data to be sent (in bytes)
* #retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
*/
uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 7 */
USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
if (hcdc->TxState != 0){
return USBD_BUSY;
}
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
/* USER CODE END 7 */
return result;
}
Could someone help me?
I solved it myself, so sorry for spam thread. But if it will be helpfull for someone I used Queue.
Here is how my code looks like after add 2 Queues in CubeMX (recivedData 1024 uint16_t and dataToSend 128 uint8_t):
void StartSendTask(void const * argument)
{
/* USER CODE BEGIN StartSendTask */
MX_USB_DEVICE_Init();
/* Infinite loop */
for(;;)
{
if( xQueueReceive(dataToSendHandle, sender, 10) ){
if( xSemaphoreTake( myBinarySem02Handle, ( TickType_t ) 10 ) )
{
counter4++;
HAL_GPIO_WritePin( LD2_GPIO_Port, LD2_Pin, !HAL_GPIO_ReadPin( LD2_GPIO_Port, LD2_Pin) );
volatile uint8_t send = CDC_Transmit_FS( sender, (length/8) );
xSemaphoreGive( myBinarySem02Handle );
}
}
}
/* USER CODE END StartSendTask */
}
/* USER CODE BEGIN Header_StartADCTask */
/**
* #brief Function implementing the recivedTask thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_StartADCTask */
void StartADCTask(void const * argument)
{
/* USER CODE BEGIN StartADCTask */
/* Infinite loop */
for(;;)
{
if( xSemaphoreTake( myBinarySem01Handle, ( TickType_t ) 10 ) )
{
HAL_GPIO_WritePin( LD2_GPIO_Port, LD2_Pin, !HAL_GPIO_ReadPin( LD2_GPIO_Port, LD2_Pin) );
counter1++;
for( int i = 0 ; i < (length/4) ; i++ ){
HAL_ADC_Start_DMA( &hadc1, reciver, length);
}
if( xSemaphoreGive( myBinarySem01Handle ) == pdTRUE )
{
xQueueSend(recivedDataHandle, reciver, 10);
vTaskDelay(1);
}
}
}
/* USER CODE END StartADCTask */
}
/* USER CODE BEGIN Header_StartPrepareTask */
/**
* #brief Function implementing the prepareTask thread.
* #param argument: Not used
* #retval None
*/
/* USER CODE END Header_StartPrepareTask */
void StartPrepareTask(void const * argument)
{
/* USER CODE BEGIN StartPrepareTask */
/* Infinite loop */
for(;;)
{
if( xQueueReceive(recivedDataHandle, reciver, 10) ){
HAL_GPIO_WritePin( LD2_GPIO_Port, LD2_Pin, !HAL_GPIO_ReadPin( LD2_GPIO_Port, LD2_Pin) );
counter2++;
if( xSemaphoreTake( myBinarySem01Handle, ( TickType_t ) 10 ) )
{
if( xSemaphoreTake( myBinarySem02Handle, ( TickType_t ) 10 ) )
{
volatile uint8_t counter = 0;
for( int i = 0; i < (length / (16 * 4)); i ++){
for( int j = 0; j < 16; j++){
prepared[counter] += reciver[i * 16 + j * 4 + counter];
prepared[counter + 1] += reciver[i * 16 + j * 4 + counter + 1];
prepared[counter + 2] += reciver[i * 16 + j * 4 + counter + 2];
prepared[counter + 3] += reciver[i * 16 + j * 4 + counter + 3];
}
counter += 4;
}
if( xSemaphoreGive( myBinarySem02Handle ) == pdTRUE )
{
xSemaphoreGive( myBinarySem01Handle );
}
} else {
xSemaphoreGive( myBinarySem01Handle );
}
}
if( xSemaphoreTake( myBinarySem02Handle, ( TickType_t ) 10 ) )
{
counter3++;
for( int i = 0; i < (length / 8); i += 2){
sender[0 + i] = prepared[i / 2] >> 8;
sender[1 + i] = (prepared[i / 2] << 8) >> 8;
}
if( xSemaphoreGive( myBinarySem02Handle ) == pdTRUE )
{
xQueueSend(dataToSendHandle, sender, 10);
}
}
}
}
/* USER CODE END StartPrepareTask */
}

CubeMX stm32 FreeRTOS + USB host MSC for USB Flash memory

Using CubeMX, TrueStudio, an STM32F767ZI, and HAL, I am developing software to access a USB Flash drive using FatFS though the USB host port.
The board has a host and device USB connector attached to the MCU.
Within CubeMX, I configured FreeRTOS, USB Host MSC, and FatFS.
This works, I can see these different states when plugging and unplugging the flash drive:
--- Plugging in USB flash drive ---
HOST_USER_CONNECTION
HOST_USER_CONNECTION
HOST_DEV_ATTACHED
phost->device.speed: 1
HOST_ENUMERATION
HOST_SET_CONFIGURATION
HOST_SET_WAKEUP_FEATURE
HOST_CHECK_CLASS
USBH_MSC_InterfaceInit
HOST_CLASS_REQUEST
USBH_MSC_ClassRequest
HOST_CLASS
USBH_MSC_Process
processId: 3, Appli_state 1
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 623395
info.capacity.block_size: 512
capacity : 3116 MB
HOST_USER_CLASS_ACTIVE
FATFS_LinkDriver Failed
USBDISKPath:
processId: 2, Appli_state 2
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 62333951
info.capacity.block_size: 512
capacity : 31166 MB
--- Unplugging USB flash drive ---
HOST_USER_DISCONNECTION
HOST_DEV_DISCONNECTED
USBH_MSC_InterfaceDeInit
processId: 5, Appli_state 3
USBH_MSC_GetLUNInfo
info.capacity.block_nbr : 62333951
info.capacity.block_size: 512
capacity : 31166 MB
So, after MX_USB_HOST_Init(); was called in freertos.c all the above happened.
FATFS_LinkDriver() is called from MX_FATFS_Init().
But the functions in usbh_diskio.c are not called, so something went wrong there.
The pieces of code I'm looking at are these:
freertos.c, where MX_USB_HOST_Init() is called, after this the MSC is registered.
/* StartDefaultTask function */
void StartDefaultTask(void const * argument)
{
/* init code for FATFS */
MX_FATFS_Init();
/* init code for LWIP */
MX_LWIP_Init();
/* init code for USB_HOST */
MX_USB_HOST_Init();
/* init code for USB_DEVICE */
MX_USB_DEVICE_Init();
/* init code for LIBJPEG */
MX_LIBJPEG_Init();
/* USER CODE BEGIN StartDefaultTask */
MSC_LUNTypeDef info;
uint8_t lun = 0;
uint16_t val = 0;
/* Infinite loop */
for(;;)
{
/* USB Host Background task */
// USBH_Process(&hUsbHostFS);
val++;
if (val >= 1000)
{
if (processIdOld != processId)
{
printf("processId: %d, Appli_state %d\n", processId, Appli_state);
processIdOld = processId;
USBH_MSC_GetLUNInfo(&hUSB_Host, lun, &info);
uint32_t cap = info.capacity.block_nbr / 2000;
printf("info.capacity.block_nbr : %ld\n", info.capacity.block_nbr);
printf("info.capacity.block_size: %d\n", info.capacity.block_size);
printf("capacity : %d MB\n", cap);
}
// printf("1");
// fflush(stdout);
// HAL_GPIO_TogglePin(PIO10_LED_RS_ERR_GPIO_Port, PIO10_LED_RS_ERR_Pin);
val = 0;
}
osDelay(1);
}
/* USER CODE END StartDefaultTask */
}
usb_host.c, where USB is initialized, and I can see USBH_UserProcess is called when I plug/unplug the USB flash drive.
void MX_USB_HOST_Init(void)
{
/* USER CODE BEGIN USB_HOST_Init_PreTreatment */
/* USER CODE END USB_HOST_Init_PreTreatment */
/* Init host Library, add supported class and start the library. */
USBH_Init(&hUsbHostFS, USBH_UserProcess, HOST_FS);
USBH_RegisterClass(&hUsbHostFS, USBH_AUDIO_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_CDC_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_MSC_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_HID_CLASS);
USBH_RegisterClass(&hUsbHostFS, USBH_MTP_CLASS);
USBH_Start(&hUsbHostFS);
/* USER CODE BEGIN USB_HOST_Init_PostTreatment */
/* USER CODE END USB_HOST_Init_PostTreatment */
}
/*
* user callback definition
*/
static void USBH_UserProcess (USBH_HandleTypeDef *phost, uint8_t id)
{
/* USER CODE BEGIN CALL_BACK_1 */
switch(id)
{
case HOST_USER_SELECT_CONFIGURATION:
printf("HOST_USER_SELECT_CONFIGURATION\n");
break;
case HOST_USER_DISCONNECTION:
printf("HOST_USER_DISCONNECTION\n");
Appli_state = APPLICATION_DISCONNECT;
break;
case HOST_USER_CLASS_ACTIVE:
printf("HOST_USER_CLASS_ACTIVE\n");
Appli_state = APPLICATION_READY;
break;
case HOST_USER_CONNECTION:
printf("HOST_USER_CONNECTION\n");
Appli_state = APPLICATION_START;
break;
default:
break;
}
/* USER CODE END CALL_BACK_1 */
}
The above part works fine, sofar.
Except the linking of the usbh driver.
Has anybody used this or know good working examples?

Resources