1. Ничего особо экстравагантного не потребовалось. Надо объявить функцию, которая вызывается по прерыванию. При этом ясно, что обычная функция и функция вызываемая по прерыванию имеют разные прологи/эпилоги.
2. Думаю, что Microsoft’овский компилятор не столь уж странен, если на нам написан WindowsCE под ARM. И уж не «страньше», чем многими любимый gcc. К тому же бесплатный.
3. Насчет нормальности такого подхода – это не факт. Совершенно ясно, что так (связка ассемблер + С/С++) делать можно. И так можно реализовать что-хочешь. Но мне при этом видится ряд неоптимальных решений. Первое. Приходится из ассемблерного модуля вызывать лишнюю функцию, написанную на С/С++. Второе. Так как вы понятия не имеете (если, конечно не заниматься такой веселой работой, как изучение ассемблерных кодов, порождаемых компилятором), какие регистры компилятор задействует в этой вызываемой функции, приходится записывать в стек на всякий случай все scratch регистры. Если бы функция, вызываемая по прерыванию, была бы написана непосредственно на ЯВУ c некоторым специальным ключевым словом (например, __interrupt), компилятор запихнул бы в стек только необходимый минимум регистров.
4. Потенциально можно вывернуться и по-другому, объявив функцию «голой» (__declspec(naked)), в inline asm’е самостоятельно прописать свой пролог/эпилог. Но в моем случае этот вариант не проходит, т.к. clarm не поддерживает встраевыемый ассемблер.
Чтобы не разводить дискуссию про то какой компилятор лучше или хуже, задам исходный вопрос по-другому:
Реализована ли в компиляторе С++ Microsoft для ARM ключевое слово __interrupt?
Я перебробовал различные варианты вызова функций с этим спецификатором и наполучал лишь кучу сообщений об ошибках. Вполне вероятно, что __interrupt не реализована, или реализована каким-либо специфическми образом.
|