¡ 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.