La placa Discovery STM32F4 solo funciona en modo DEBUG

Generé mi proyecto con STMCUBEMX con periféricos CAN, SPI, I2C e hice algo de codificación encima. El código básicamente sondea el CANBUS, almacena datos en algún IC a través de i2c y envía los datos procesados ​​al nodemcu conectado a través del SPI.

Estaba funcionando como debería hasta que decidí dejar de trabajar en modo de depuración y usarlo como un circuito independiente. Entonces, después de mostrar el código, desconecté el cable USB y lo volví a enchufar. Y fue entonces cuando comenzaron los comportamientos extraños. Cuando traté de depurar a través de los LED y descubrí que cualquier operación relacionada con SPI o I2C bloquea el código y no se enciende ningún LED después de ese punto. Una función normal que solo realiza operaciones aritméticas y no usa ningún periférico no impide que los LED también funcionen las interrupciones de CAN y el botón pulsador, como observé a través de los LED (siempre funcionan incluso cuando el circuito parece atascado). Tan pronto como flasheo el código, vuelve a funcionar como se esperaba.

Hasta ahora he probado:

  • Cambio del cristal de alta velocidad externa a alta velocidad interna
  • Alimentación de la placa desde una fuente externa (cable USB conectado a un adaptador de cargador de teléfono).
  • Cambiar a ST-Link en lugar de Jlink.
  • Quitar los esclavos SPI e I2C del circuito desenchufando los cables.

Dado que son los periféricos los que causan el problema, pensé que podría tener algo que ver con los relojes periféricos. Pero básicamente se quedó atascado después de este punto.

Estoy usando una placa disco stm32f4 a 84 mhz. Actualicé mi depurador a jlink desde st-link y estoy depurando a través de la extensión de código VS cortex-debug

Comienzo de mi principal

      int main(void)
    {

      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_SPI2_Init();
  MX_I2C1_Init();
  InitializeTimer();

  /* USER CODE BEGIN 2 */
  Can_Setup();

  if (HAL_CAN_Start(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }

  HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING);

  uint8_t Atr[64];
  uint16_t AtrLen = sizeof(Atr);
  int sw = smComSCI2C_Open(ESTABLISH_SCI2C, 0x00, Atr, &AtrLen);  // I2c peripheral init function, this is succesfull but not very stable. 
  if(sw == SW_OK)
  {
      HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12,GPIO_PIN_SET);
  }

    generateIdentity(); // uses i2c, the code stucks after this point
    generateAddress();  // uses i2c
    while(connectWifi() != 0 );  //uses SPI
    getNonce(&storedNonce);  //uses SPI

Mi función de reloj

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_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks 
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 4;
  RCC_OscInitStruct.PLL.PLLN = 84;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** 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_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

Función de inicio del sistema

void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;

  /* Reset CFGR register */
  RCC->CFGR = 0x00000000;

  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;

  /* Reset PLLCFGR register */
  RCC->PLLCFGR = 0x24003010;

  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;

  /* Disable all interrupts */
  RCC->CIR = 0x00000000;

#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
  SystemInit_ExtMemCtl(); 
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */

  /* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}

He estado atascado en este problema durante los últimos días, y la fecha límite para el proyecto es muy pronto. Todas las ayudas son muy apreciadas :)

¿Puedes github todo tu proyecto? Hay muchas cosas que puede ser.
Cuando lo ejecutó en el depurador, ¿eliminó todos los puntos de interrupción antes de soltar el depurador?

Respuestas (2)

elimine DWT_Delay() Parece que causa los problemas en el modo de lanzamiento.

Debe tener mucho cuidado al usar HAL_Delay(), o cualquier otro retraso basado en interrupciones para el caso. HAL_Delay() está siendo incrementado por el temporizador SysTick. Si configura las prioridades NVIC de otras interrupciones frente al temporizador SysTick, existe la posibilidad de que el temporizador no haga el tic en el ciclo de la CPU, por lo que se atascará en un bucle sin fin. Asegúrese de que cuando use HAL_Delay, el temporizador SysTick tenga mayor prioridad que el resto.