ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
2 мая
1246084 Топик полностью
Tyмблep (03.10.2022 16:28, просмотров: 218) ответил VladislavS. на В мелких контроллерах, типа кортексов или AVR таблица векторов прерываний это константные данный этапа компиляции. То есть, компилятор должен знать адрес на момент линковки. Всякие динамически создаваемые объекты плохо тут ложатся. Получается, либо установка векторов в рантайме с переносом таблицы векторов в RAM (если такая возможность есть). Либо прослойка просто через таблицу в RAM (если возможности перенести таблицу нет). В обоих случаях накладные расходы.
Это проблема поддержки со стороны разработчиков компилятора. 

Но даже там таблицу можно делать не одну, а несколько.

Одну в ROM, другую в RAM.


Если мы сами решаем эту проблему, то и проблемы то нет.

Как то так :

// --------------------------------------------------------------------------

//Определим интерфейс:

class I_interrupt

{

public:

virtual void work (int intNum)=0;

};

// --------------------------------------------------------------------------

// определим указатель на интерфейс

I_interrupt* pInt=NULL;

// --------------------------------------------------------------------------

// установим адрес интерфейса:

void Set_I_interrupt(I_interrupt* p)

{

pInt = p;

}

// --------------------------------------------------------------------------

//

//

//

// --------------------------------------------------------------------------

//Далее короткие функции прерываний в стиле С:

// Пусть для определённости будет так (AVR 8515):

interrupt [TIMER1_COMPB_vect] void t1_compb (void)

{

pInt->work(TIMER1_COMPB_vect);

}

// --------------------------------------------------------------------------

interrupt [TIMER1_COMPA_vect] void t1_compa (void)

{

pInt->work(TIMER1_COMPA_vect);

}

// --------------------------------------------------------------------------

//Пишем реализацию интерфейса для конкретного проекта:

class IntProject : virtual public I_interrupt

{

public:

virtual void work (int intNum);

virtual void routine_TIMER1_COMPB_vect();

virtual void routine_TIMER1_COMPA_vect();

};

// --------------------------------------------------------------------------

void IntProject::work (int intNum)

{

// тут возможно что-то общее для всех, если нужно

switch(intNum)

{

case TIMER1_COMPB_vect: routine_TIMER1_COMPB_vect(); break;

case TIMER1_COMPA_vect: routine_TIMER1_COMPA_vect(); break;

}

// тут возможно что-то общее для всех, если нужно

}

// --------------------------------------------------------------------------

void IntProject::routine_TIMER1_COMPB_vect()

{

// ...

}

// --------------------------------------------------------------------------

void IntProject::routine_TIMER1_COMPA_vect()

{

// ...

}

// --------------------------------------------------------------------------

// В результате работаем с прерываниями используя классы.

// Возможны варианты.

// используем:

void main (void)

{

// ...

IntProject intObject; Set_I_interrupt(&intObject);

// ...

}

После этого реализации обслуживания прерываний меняются

легко и просто.

---

Собственно, не совсем понятно, почему такое длительное обсуждение

получилось. А давайте попробуем написать класс для создания

потоков или окон для Виндус. Получится то же самое.

Процедура "в стиле С" с параметром "this" в любом случае потребуется.