Estoy intentando escribir una interrupción para mantener el tiempo básico medido en tics en un STM32F407VGT (Discovery Board).
Mi interrupción parece ejecutarse una vez (aunque no puedo estar seguro), pero luego falla/bloquea el procesador por completo. Todas las salidas de UART se detienen...
El código es esencialmente el mismo que el de "La guía definitiva del ARM Cortex-M3, 2.ª ed." (Joseph Yiu, Newnes.) ¿Podría ser un problema el hecho de que el STM32F4xx sea un ARM Cortex-M4? Si es así, ¿cómo soluciono esto? Inicialmente intenté usar TMR2, con problemas similares, lo que me hace pensar que es algo que me estoy perdiendo. También intenté usar SysTickConfig, con los mismos problemas.
uint32_t ticks;
void SysTickAlarm(void)
{
SysTick->CTRL = 0;
SCB->ICSR = SCB->ICSR & 0xFDFFFFFF;
ticks++;
return;
}
/*
* Initialise system timer
*/
void tick_init(void)
{
ticks = 0;
*((volatile unsigned int*)(SCB->VTOR + (15 << 2))) = (unsigned int) SysTickAlarm;
SysTick->CTRL = 0; // Disable SysTick
SysTick->LOAD = TICK_DELAY; // Delay for 10 ms
SysTick->VAL = 0; // Clear current value to 0
SysTick->CTRL = 0x7; // Enable SysTick+exception and use processor clock
}
/*
* get_ticks: Get the number of ticks since processor initialisation.
*/
uint32_t get_ticks()
{
return ticks;
}
main() llama a tick_init() y luego comienza a escupir printf("ticks=%d\n", get_ticks());
en un bucle. Pero se detiene con bastante rapidez, obtengo alrededor de 10 líneas antes de que se bloquee.
Soy muy nuevo en los procesadores ARM, por lo que probablemente sea algo muy simple, pero no puedo verlo.
Se ha creado un gran problema al deshacerse de la biblioteca de periféricos estándar (SPL). Este microcontrolador es bastante difícil de aprender con él, y mucho menos sin él. La biblioteca puede tener un diseño horrible, pero tiene la ventaja de que realmente funciona. Le sugiero que primero obtenga un programa de prueba simple que funcione con SPL, luego vuelva a implementar gradualmente su funcionalidad si realmente no puede usarlo (sin embargo, todavía tengo que ver una razón técnica para eso).
Para usar una interrupción en un Cortex-M3/M4, necesita lo siguiente:
SCB->VTOR
registro. Por defecto es 0, que (de nuevo por defecto) es el inicio de flash. Si la combinación de código de inicio/secuencia de comandos del enlazador configura la tabla de vectores correctamente, genial. El SPL hace eso. Parece que no lo haces (a menos que esté en el código que no publicaste). Mire cómo se hace en la biblioteca de periféricos estándar ( startup_stm32f4xx.s
y el script de enlace correspondiente para una cadena de herramientas basada en gcc).NVIC->ISER[x]
y NVIC->IPR[x]
registra. Ver implementación de NVIC_Init()
en la SPL y PM00214 sección 4.3.Si después de verificar todo eso todavía no puede hacer que funcione, lo mejor sería publicar un proyecto completo (pero mínimo) para analizar.
rmw_mask32(&GPIOB->MODER, 3, 1);
usando mi rmw_mask32
rutina para realizar GPIOB->MODER = (GPIOB->MODER & ~3) | 1
, pero usando LDREX/STREX para ser a prueba de interrupciones). ¿Hay alguna buena documentación de fácil búsqueda que diga cómo usar el SPL para tal propósito?
Al Bennett
Tomas O.
Espina
Tomas O.
*((volatile unsigned int*)(SCB->VTOR + (15 << 2))) = (unsigned int) SysTickAlarm;
para eso, pero no estoy seguro.Espina
Tomas O.