STM32F0 Se bloquea de una declaración de cadena literal

0

¡ literalmente siento que me estoy volviendo loco! Estoy tratando de escribir un programa excepcionalmente simple que pueda solicitar una lista de redes WiFi locales usando un ESP8266 y el comando AT + CWLAP. Sin embargo, el problema no se encuentra en el lado UART o ESP8266.

He escrito una función que puede enviar una cadena a través de UART al ESP8266. Sin embargo, si intento llamar a esta función y le paso una cadena literal, por ejemplo: U_TxStr ("Hola"), hace que todo el microcontrolador se cuelgue en la sección del código ASM de inicio "CopyDataInit". He intentado agregar un controlador de fallas difíciles que encontré en línea, ¡pero esto no ha ayudado en absoluto, ya que el programa ni siquiera logra llegar hasta aquí!

Si, en cambio, inicializo una matriz de caracteres con una cadena, por ejemplo: char str [16]="Hello", y paso str como un puntero a la función U_TxStr, el programa funciona bien y no hay problemas. ¿Cuál podría ser el problema aquí? Parece que el microcontrolador no puede copiar la cadena del flash y en la RAM (¿en la pila?), Lo que provoca que se cuelgue en la inicialización, ¿suena bien y cómo puedo solucionarlo?

Estoy usando CooCox y una placa de descubrimiento STM32F0

Listado de código completo:

#include <stm32f0xx_gpio.h>
#include <stm32f0xx_rcc.h>
#include <stm32f0xx_usart.h>
#include <stm32f0xx_misc.h>
#include <string.h>

#define U_TX        GPIO_Pin_2
#define U_RX        GPIO_Pin_3
#define U_TXPS      GPIO_PinSource2
#define U_RXPS      GPIO_PinSource3
#define U_AF        GPIO_AF_1
#define U_GPIO      GPIOA

#define U_CHAN0     GPIO_Pin_0
#define U_CHAN1     GPIO_Pin_1

#define U_UIRQ      USART2_IRQn
#define U_USART     USART2
#define U_UBUFSIZ   512

char ubuf[U_UBUFSIZ] = {0};

volatile uint8_t devchan = 0;
volatile uint16_t dcnt = 0;
volatile uint32_t msec = 0, tlast = 0;

GPIO_InitTypeDef G;
USART_InitTypeDef U;
NVIC_InitTypeDef N;

void SysTick_Handler(void){
    msec++;
}

volatile uint32_t f = 0;

static void hard_fault_handler_c(unsigned int * hardfault_args)
{
    unsigned int stacked_r0;
    unsigned int stacked_r1;
    unsigned int stacked_r2;
    unsigned int stacked_r3;
    unsigned int stacked_r12;
    unsigned int stacked_lr;
    unsigned int stacked_pc;
    unsigned int stacked_psr;

    stacked_r0 = ((unsigned long) hardfault_args[0]);
    stacked_r1 = ((unsigned long) hardfault_args[1]);
    stacked_r2 = ((unsigned long) hardfault_args[2]);
    stacked_r3 = ((unsigned long) hardfault_args[3]);

    stacked_r12 = ((unsigned long) hardfault_args[4]);
    stacked_lr = ((unsigned long) hardfault_args[5]);
    stacked_pc = ((unsigned long) hardfault_args[6]);
    stacked_psr = ((unsigned long) hardfault_args[7]);

    for(;;);
}

void HardFault_Handler(void)
{
    asm volatile(
            "movs r0, #4\t\n"
            "mov  r1, lr\t\n"
            "tst  r0, r1\t\n" /* Check EXC_RETURN[2] */
            "beq 1f\t\n"
            "mrs r0, psp\t\n"
            "ldr r1,=hard_fault_handler_c\t\n"
            "bx r1\t\n"
            "1:mrs r0,msp\t\n"
            "ldr r1,=hard_fault_handler_c\t\n"
            : /* no output */
            : /* no input */
              : "r0" /* clobber */
    );
}

void USART2_IRQHandler(void){
    uint8_t data;
    if(USART_GetITStatus(U_USART, USART_IT_RXNE) != RESET){
        USART_ClearITPendingBit(U_USART, USART_IT_RXNE);

        data = USART_ReceiveData(U_USART);

        if(dcnt<U_UBUFSIZ) ubuf[dcnt++] = data;

        tlast = msec;
    }
}

void U_TxByte(const char d){
    USART_SendData(U_USART, d);
    while(USART_GetFlagStatus(U_USART, USART_FLAG_TXE) == RESET);
}

void U_TxStr(const char *s){
    while(*s){
        U_TxByte(*s);
        s++;
    }
}

void U_WaitStr(uint32_t t){
    while((msec-tlast)<t);
}

void U_ClrBuf(void){
    memset(ubuf, 0, U_UBUFSIZ*sizeof(char));
    dcnt = 0;
}

int main(void)
{
    RCC_DeInit();
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

    G.GPIO_Pin = U_TX | U_RX;
    G.GPIO_Mode = GPIO_Mode_AF;
    G.GPIO_OType = GPIO_OType_PP;
    G.GPIO_PuPd = GPIO_PuPd_UP;
    G.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_Init(U_GPIO, &G);

    GPIO_PinAFConfig(U_GPIO, U_TXPS, U_AF);
    GPIO_PinAFConfig(U_GPIO, U_RXPS, U_AF);

    G.GPIO_Pin = U_CHAN0 | U_CHAN1;
    G.GPIO_Mode = GPIO_Mode_IN;
    G.GPIO_OType = GPIO_OType_PP;
    G.GPIO_PuPd = GPIO_PuPd_UP;
    G.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_Init(U_GPIO, &G);

    if(GPIO_ReadInputDataBit(U_GPIO, U_CHAN0)) devchan += 1;
    if(GPIO_ReadInputDataBit(U_GPIO, U_CHAN1)) devchan += 2;

    N.NVIC_IRQChannel = U_UIRQ;
    N.NVIC_IRQChannelPriority = 1;
    N.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&N);

    USART_DeInit(U_USART);
    U.USART_BaudRate = 115200;
    U.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    U.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
    U.USART_Parity = USART_Parity_No;
    U.USART_StopBits = USART_StopBits_1;
    U.USART_WordLength = USART_WordLength_8b;
    USART_Init(U_USART, &U);
    USART_ClearITPendingBit(U_USART, USART_IT_RXNE);
    USART_ITConfig(U_USART, USART_IT_RXNE, ENABLE);
    USART_Cmd(U_USART, ENABLE);

    SysTick_Config(SystemCoreClock/1000);

    //Works
    /*char str[12] = "AT+CWLAP\r\n";
    U_ClrBuf();
    U_TxStr(str);
    U_WaitStr(500);*/

    //Breaks
    /*U_ClrBuf();
    U_TxStr("AT+CWLAP\r\n");
    U_WaitStr(500);*/

    while(1)
    {

    }
}

Editar: Para referencia, probé una placa diferente y tengo el mismo problema. Declarar globalmente los arrays de caracteres no hace ninguna diferencia :(

Actualización: Así que decidí probar todas las cadenas de herramientas disponibles (por si acaso). ¡GCC Arm 4.8 a 5 y, extrañamente, compilar con 4.8 no da este problema! Todavía no he comparado los ensamblados producidos, pero es extraño que el problema parezca venir con las revisiones posteriores de GCC.

    
pregunta Pyrohaz

1 respuesta

1
  

STM32F0

Que tiene un núcleo Cortex M0.

Cortex M0 es sensible a la desalineación. Su problema suena a lot como si solo faltara una declaración de alineación en el skript del vinculador, lo que hace que una versión del programa falle al intentar copiar el segmento de datos de la memoria flash a la RAM.

Ambos lados deben estar alineados con 4 bytes para que funcione el código de copia de inicio habitual.

Su programa de trabajo es ligeramente diferente en código o tamaño de datos, ocultando el problema.

    
respondido por el Turbo J

Lea otras preguntas en las etiquetas