48043
[i] Работа с прерываниями в К1986ВЕ1QI (К1986ВЕ1FI, К1986ВЕ1GI) при исполнении из ОЗУ
Дата последнего изменения: 23.07.2024 09:32:22
Материал из настоящей статьи, относящийся к микросхеме К1986ВЕ1QI, распространяется в том числе на микроконтроллеры К1986ВЕ1FI и К1986ВЕ1GI
Таблица векторов прерываний в микроконтроллере К1986ВЕ1QI всегда расположена с нулевого адреса и не может быть перенесена. При разработке программного обеспечения, исполняющегося из ОЗУ, нужно это учитывать и для возможности использования прерываний применять следующие методы:1. Во Flash-памяти расположить программу, в которой описать функции-подпрограммы обработки прерываний, например, для Timer 1 это может выглядеть так:
TIMER1_IRQHandler(void);
Фрагмент кода 1Эта функция описана в файле startup_MDR32F1QI.s. А уже внутри этой функции (TIMER1_IRQHandler) должен вызываться реальный обработчик прерываний, расположенный в памяти ОЗУ.
2. Обработчики прерываний расположены в ОЗУ, а во Flash-памяти, в таблице векторов прерываний указать верные адреса этих обработчиков. Тогда при возникновении прерывания процессор обратится к таблице во Flash память, в которой возьмёт адрес обработчика прерывания, расположенного в ОЗУ.
Реализация первого метода
В качестве примера работы возьмем проект для отладочной платы К1986ВЕ1QI из этой статьи для IDE Keil. Этот проект будет загружаться в ОЗУ и использоваться, как основа: прерывания в проекте возникают по приёму данных через ИК-порт (отправить данные можно со второй такой же платы или со смартфона). По аналогии можно настроить работу с любыми прерываниями.Дополнительно для скачивания в конце статьи доступен проект, загружаемый во Flash-память, чтобы наладить корректную работу прерываний.
Нужно не забыть прикрепить к основному проекту файл Setup.ini для запуска из ОЗУ согласно этой статье. Для удобства запуск производится с начального адреса 0x20100000.
После первичного запуска проекта из ОЗУ и отправки на отладочную плату данных прерывания не возникают. Обработчик в программе называется UART1_Handler.
Теперь во Flash-память необходимо записать программу, которая будет считывать значение адреса этого прерывания и "прыгать" на него после его возникновения.
Программа исполняется в микроконтроллере К1986ВЕ1QI с адресов 0x20100000, для UART1_IRQHandler необходимо считать значение памяти по адресу 0x20100058 (адрес высчитывается согласно таблице "Принцип формирования прерываний" из спецификации на микросхему), а затем перейти по полученному адресу. Таким образом произойдет выполнение обработчика прерывания из ОЗУ.
Код программы, записываемой во Flash-память:
#include <MDR32FxQI_port.h>
#include <MDR32FxQI_rst_clk.h>
#define HWREG(x) (*((volatile uint32_t *)(x))) // Макрос для считывания значения по определенному адресу
void UART1_IRQHandler(void);
int main()
{
NVIC_EnableIRQ(UART1_IRQn); //Enable UART1 interrupt
while(1)
{
UART1_IRQHandler();
}
}
//--- UART1 interrupt routine ---
void UART1_IRQHandler()
{
int A;
A = HWREG(0x20100058); // Занести в переменную А значение памяти по адресу 0x20100058 (UART1_IRQHandler), чтобы корректно прыгнуть в обработчик прерывания в программе ОЗУ
typedef void (*funcptr)();
funcptr funcInRAM = (funcptr) (A);
funcInRAM(); // Прыжок
}
Фрагмент кода 2Реализация второго метода
Второй метод менее мобильный, но тоже имеет право на жизнь.Внесём следующие изменения в проект для Flash-памяти:
- Необходимо в main.c оставить только следующие строки кода:
#include <MDR32FxQI_port.h>
Фрагмент кода 3
#include <MDR32FxQI_rst_clk.h>
void UART1_IRQHandler(void);
int main()
{
NVIC_EnableIRQ(UART1_IRQn); //Enable UART1 interrupt
while(1)
{
UART1_IRQHandler();
}
- В файле startup*.s (стартовый файл) необходимо изменить строчку "DCD UART1_IRQHandler" на "DCD address", где address - значение адреса, которое нужно считать в режиме отладки проекта под ОЗУ по адресу 0x20100058. Теперь программа из Flash-памяти будет отправлять процессор на выполнение обработчика прерывания в ОЗУ. Подробнее на рисунке 1:
Рисунок 1 - Значение address в окне Memory
Файлы для скачивания
Теги
Особенности применения "Know-How"