Інформація, яку видає OpenOCD при звичайному завантаженні програми у flash-пам’ять мікроконтролера, деколи може допомогти так, як наче це був запущений зневаджувач.
Переписую на свій смак шматки, які вже працювали зі стандартною бібліотекою від NXP. При чергових змінах програми вона начисто перестає працювати. Знаходжу дрібну помилку (замість змінної часу повертається константа періоду), виправляю, перешиваю…
Знову висить.
І тут помічаю, що OpenOCD сповістив мене про те, що ядро перед програмуванням знаходилося не в стані Thread, тобто виконання програми, а в стані обробки преривання:
TargetName Type Endian TapName State
-- ------------------ ---------- ------ ------------------ ------------
0* lpc1766.cpu cortex_m3 little lpc1766.cpu running
target state: halted
target halted due to debug-request, current mode: Handler SysTick
xPSR: 0x6100000f pc: 0x00002628 msp: 0x10007f70
Але ж обробка SysTick складається у мене зараз зі скидання флагу та інкременту змінної, кілька тактів при тактовій 100 МГц. Потрапити на неї — дуже низька імовірність.
void SysTick_Handler(void)
{
SysTick->CTRL &= ~ST_CTRL_COUNTFLAG;
++systick_ticks;
}
Ще раз запускаю програматор і знову отримую «Handler SysTick», що вже зовсім неймовірно за нормальних умов.
О, точно!
Так я ж забув дописати extern "C" перед обробником преривання SysTick_Handler(), коли перетягував цей шматок з С-шного файлу у C++-овий. А запускалка startup.c очікує імена без декору C++.
Відразу написав файл lpc17xx_handlers.h, простіше буде включати його в усі файли з обробниками преривань і не думати, треба ставити extern "C" чи ні.
Хоча може краще було б зробити так:
#ifdef __cplusplus
#define CM3_HANDLER extern "C"
#else
#define CM3_HANDLER
#endif
І писати CM3_HANDLER перед кожним обробником преривання, аналогічно OS_INTERRUPT в програмах з scmRTOS.
Я ще подумаю