|
AT90USB1287 не отрабатывает внешние прерывания, В чем дело? |
|
|
|
Aug 4 2008, 03:41
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Отлаженый проект переношу с MEGA324P на AT90USB1287. После соответствующей коррекции программы перестало отрабатывать нажатия на матричной клавиатуре 4х4. Изменилась схема подключения клавиатуры: раньше COL и RAW подключались к двум разным портам. Теперь занимают один PORTF. И, так как у AT90USB1287 только PORTB имеет PCINT (зачем было так ограничивать функциональность МК ?!!), то выводы RAW через диоды анодами подключены к выводу внешнего прерывания INT6 (PORTE6). Прерывания настраиваю как обычно: Код int main() { // Initialise ACSR = (1<<ACD); // Analog Comparator Disable ................. PORTE = (1<<KEY_INT); // INT6 -> input, pull-up - ON
key_Init(); __enable_interrupt(); // set the Global Interrupt Enable Bit ..................................... ///////////////////////////////////////////
#define ENABLE_INT6 {EIFR |= (1<<INTF6); EIMSK |= (1<<INT6);}// Clear interrupt status flag, Enable external interrupt INT6 #define DISABLE_INT6 EIMSK &= ~(1<<INT6) // Disable external interrupt INT6
void key_Init(void) { /* Init ports */ KEYMATRIX_DDR = 0x0f; // Set row lines to input, Set column lines to output KEYMATRIX_PORT = 0xf0; // Pull row lines high, Drive all column lines low /* Enable external interrupt */ ENABLE_INT6; // Enable pin change interrupt INT6 } Выяснилось, что не вызывается обработчик прерывания INT6. Проверяю по звуковому сигналу BEEP. В симуляторе в AVRSTUDIO тоже прогнал - не вызываются прерывания: ни по низкому уровню, ни по фронтам (заднему и переднему). АЦП (PORTF) не использую. В чем дело? PS. Схему и код выкладываю, чтобы не возникало лишних вопросов.
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 32)
|
Aug 5 2008, 10:47
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(SysRq @ Aug 5 2008, 12:48)  Фьюз JTAGEN проверьте. JTAGEN=1 -> отключен. Какие еще будут варианты?
|
|
|
|
|
Aug 5 2008, 13:40
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(GDI @ Aug 5 2008, 15:44)  В вшем коде не видно настройки DDRE... DDRE6 (INT6) = 0 (input). Я - не новичек  . В Интернете пробегала информация, что у этого камня не правильно пронумерованы вектора прерывания. Прийду домой проверю, хотя на мой взгляд, эта версия очень уж невероятная...
|
|
|
|
|
Aug 5 2008, 13:47
|
Профессионал
    
Группа: Свой
Сообщений: 1 235
Регистрация: 14-05-05
Из: Санкт-Петербург
Пользователь №: 5 008

|
Цитата у этого камня не правильно пронумерованы вектора прерывания. Вполне возможно что не в самом камне а в заголовочном файле где они описаны, да и в эррату заглянуть тоже можно. Цитата Я - не новичек  И на старуху бывает проруха
--------------------
|
|
|
|
|
Aug 5 2008, 14:47
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
alux, прочитайте ответ Александра Редчука на телесиськах Вот оно, добавлять смысла нету
Сообщение отредактировал sKWO - Aug 5 2008, 14:51
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 5 2008, 15:42
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(sKWO @ Aug 5 2008, 17:47)  прочитайте ответ Александра Редчука на телесиськах Этот пост я и раньше видел. Лишний раз подтверждает, что с прерываниями не все чисто. Но там у нее хоть одно прерывание срабатывало. У меня же ни в симуляторе, ни в железе не срабатывает ни по PCINT0, ни по INT0...INT7. При симуляции внешних прерываний никакие флаги прерываний не взводятся. Может стоит написать в поддержку Atmel? PS. Ради интереса создал тестовый проект для ATmega128. Те же условия, что и для AT90USB1287. Симулирую прерывания,- все срабатывают, как и положено. Нужно предъявлять рекламацию Atmel. Или я чего-то не учел ?..
|
|
|
|
|
Aug 6 2008, 14:38
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
А можно понтересоваться (в целях повышения образованности  ), у вас ОС какая-то используется? Код #pragma vector=INT6_vect OS_INTERRUPT void INT6_ISR() { OS::TISRW_SS ISRW; //... } Собрал на WinAVR простенький код, прерывание работает в отладчике AVRStudio правильно. Код #include <avr\io.h> #include <avr\interrupt.h>
#define ENABLE_INT6 {EIFR |= (1<<INTF6); EIMSK |= (1<<INT6);}// Clear interrupt status flag, Enable external interrupt INT6 #define DISABLE_INT6 EIMSK &= ~(1<<INT6) // Disable external interrupt INT6
volatile unsigned char a = 0, b = 0;
SIGNAL(INT6_vect) { a++; DISABLE_INT6; // Prevent further external interrupts }
int main(void) { ACSR = (1 << ACD); // Analog Comparator Disable PORTE = (1 << 6); // INT6 -> input, pull-up - ON sei(); while(1) { b++; ENABLE_INT6; } return 0; } Makefile стандартный, создан через MFile из комплекта WinAVR, и задан MCU = at90usb1287.
|
|
|
|
|
Aug 6 2008, 15:02
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(alux @ Aug 5 2008, 18:42)  Этот пост я и раньше видел. Лишний раз подтверждает, что с прерываниями не все чисто. Но там у нее хоть одно прерывание срабатывало. Читайте внимательно, второе не срабатывало изза того, что она перепутала порт на седьмое прерывание. Как по мне то INT даже удобнее и оперативнее чем РСINT(в качестве обработкаи) хотя, правда если захотите будить МК по нажатию любой кнопки то РСINT имеет преимущество. Поискал в нете, для винавр номера векторов в хедере отличны от ДШ, но это ничего страшного, всё работает. Есть правда какаято запара с вотчдогом, до конца не разобрался.
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 6 2008, 15:43
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(SysRq @ Aug 6 2008, 17:38)  у вас ОС какая-то используется? scmRTOS Рекомендую! Цитата(SysRq @ Aug 6 2008, 17:38)  Собрал на WinAVR простенький код, прерывание работает в отладчике AVRStudio правильно. А у меня тот же код, сгенеренный в IARе (ubrof8) для AT90USB1287 не работает в AVRStudio. Получается, что IAR v5.11B виноват? Я уже начал писать рекламацию Atmel.
|
|
|
|
|
Aug 6 2008, 23:20
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(alux @ Aug 6 2008, 19:43)  Получается, что IAR v5.11B виноват? Хм. Поставил под VirtualBox'ом на XPFundamentals себе IAR (30 дней триал) посмотреть что за зверь и за что его все любят  , собрал такой код: Код #include <ioavr.h> #include <inavr.h>
#define INT6 6 // почему-то пришлось задать вручную; видимо, с IAR с разбегу не разобрался #define INTF6 6 // почему-то пришлось задать вручную; видимо, с IAR с разбегу не разобрался
#define ENABLE_INT6 {EIFR |= (1<<INTF6); EIMSK |= (1<<INT6);}// Clear interrupt status flag, Enable external interrupt INT6 #define DISABLE_INT6 EIMSK &= ~(1<<INT6) // Disable external interrupt INT6
volatile unsigned char a = 0, b = 0;
#pragma vector=INT6_vect __interrupt void INT6_ISR() { a++; DISABLE_INT6; // Prevent further external interrupts }
int main( void ) { PORTE = (1 << 6); // INT6 -> input, pull-up - ON __enable_interrupt(); // set the Global Interrupt Enable Bit while(1) { b++; ENABLE_INT6; } return 0; } При отладке в AVRStudio прерывание работает правильно! В опциях проекта ничего не менял, кроме установки --cpu=usb1287. IAR: Цитата IAR Assembler for AVR 5.11B/W32 (5.11.2.5) Translates Atmel assembler to IAR assembler 1.25 (1.2.4.109) IAR C/C++ Compiler for AVR 5.11B/W32 [Evaluation] (5.11.2.3) IAR XLINK 4.61C (4.61.3.0) IAR Build Utility 5.1.1.453.7838 (5.1.1.453) AVRStudio: 4.14 build 589
|
|
|
|
|
Aug 7 2008, 05:00
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(Т.Достоевский @ Aug 7 2008, 03:44)  если на порту INTx = 0, то застрянет в прерывании Я уже говорил, что пробовал разные варианты (по фронту, спаду, по уровню). Не в этом дело. Читайте внимательно посты. Цитата(SysRq @ Aug 7 2008, 02:20)  Хм. Поставил под VirtualBox'ом на XPFundamentals себе IAR (30 дней триал) посмотреть что за зверь и за что его все любят  , собрал такой код: ............. При отладке в AVRStudio прерывание работает правильно! В опциях проекта ничего не менял, кроме установки --cpu=usb1287. Сделал то же самое (этот же пример кода, IAR v.5.11B, ubrof8) - не работает!!! Кто то из нас двоих не прав!
|
|
|
|
|
Aug 7 2008, 10:12
|

Местный
  
Группа: Участник
Сообщений: 355
Регистрация: 27-03-07
Из: Україна, Чуднів
Пользователь №: 26 530

|
Цитата(alux @ Aug 7 2008, 12:01)  Проверить проект смогу вечером. Пока могу предположить две версии: 1) различия триальной и "вылеченной" версии IAR; (маловероятно) не моловероятно, а исключено. вылеч версия 4.21А нормально компилит и всё работает на ура. Проджект прикрепляю. Цитата(SysRq @ Aug 7 2008, 02:20)  [code] #define INT6 6 // почему-то пришлось задать вручную; видимо, с IAR с разбегу не разобрался #define INTF6 6 // почему-то пришлось задать вручную; видимо, с IAR с разбегу не разобрался SysRq, это всё решается настройками прожекта Project\Options, на закладке General Options находим System, и здесь ставим галочку напротив Enable bit definitions in I\O-include file.
Прикрепленные файлы
1287.rar ( 13.29 килобайт )
Кол-во скачиваний: 28
--------------------
нельзя недооценивать предсказуемость глупости
|
|
|
|
|
Aug 7 2008, 10:16
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(sKWO @ Aug 7 2008, 13:12)  не моловероятно, а исключено. вылеч версия 4.21А нормально компилит и всё работает на ура. Остается версия номер 2. PS. Если не трудно, проверьте эту версию у себя. Т.е. в файле iousb1287.h раскомментировать определения для PE0...PE7 и изменить PE1 на UPE1.
|
|
|
|
|
Aug 7 2008, 14:08
|

Чайник, 1 литр
   
Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168

|
Цитата(alux @ Aug 7 2008, 14:16)  ...раскомментировать определения для PE0...PE7 и изменить PE1 на UPE1. На этом тестовом коде эти изменения никак не отражаются, все работает. -- Цитата(sKWO @ Aug 7 2008, 14:12)  SysRq, это всё решается настройками прожекта Благодарю! Этот пример выше был написан сильно с разбегу - за две минуты с момента установки IAR'а; сейчас я уже в курсе немного :)
|
|
|
|
|
Aug 7 2008, 15:25
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(SysRq @ Aug 7 2008, 17:08)  На этом тестовом коде эти изменения никак не отражаются, все работает. У меня с этими изменениями все-равно не работает  . Остается еще одно различие: у меня AVRStudio v.4.13. Качаю последнюю v.4.14. Там пофиксено: Код 7163: The simulator subscripts for AT90USB128/64 and AT90USB162/82 have been fixed. Хотя, на мой взгляд, это вряд ли поможет. Ведь в железе не работает! Цитата(sKWO @ Aug 7 2008, 13:12)  вылеч версия 4.21А нормально компилит и всё работает на ура. Проджект прикрепляю. У меня ни этот проект (у Вас AVRStudio какой версии?) Цитата(SysRq @ Aug 7 2008, 08:53)  ... ни этот проект НЕ РАБОТАЕТ!!! Это было бы смешно, если б не было так печально. Почему у меня не работают прерывания? PS. Проблема решилась установкой последней версии AVRStudio v4.14 build 589. По крайней мере в симуляторе уже стал вызываться обработчик внешнего прерывания. Спасибо всем за помощь.
|
|
|
|
|
Aug 8 2008, 18:58
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Обработчик внешнего прерывания не вызывается из-за OS::Run(); Код void main() { ........................ TCCR0B = 0x03; // Start System Timer f_clk/64 TIMSK0 |= (1<<TOIE0); // Разрешить прерывания Timer0 по переполнению (OVF) OS::Run(); // Период переполнения Timer0 при f_clk=7.3728 Mhz 2.222 ms }
#pragma vector=INT6_vect OS_INTERRUPT void INT6_ISR() { OS::TISRW_SS ISRW;
DISABLE_INT6; // Prevent further external interrupts
Int6.SignalISR(); PORTC |= (1<<BEEP); // <<<<<<<<< Это для контроля входа в прерывание } А почему, не пойму никак. Раньше на Mega324P работало нормально...  Этот вопрос скорее к отцам операционной системы scmRTOS. PS. Проблема решилась опять-таки установкой последней версии scmRTOS v.3.05  Причина была скорее всего из-за следующего Bugfixes: Код EWAVR port: support for devices with more then 64 kbytes flash added in target assembler file.
|
|
|
|
|
Sep 4 2008, 15:38
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Снова проблема с внешним прерыванием. На этот раз при входе в POWER_DOWN не выходит из него при нажатии на кнопку. Сигнал внешнего прерывания от клавиатурной матрицы 4х4 подключен через аноды диодов на PE6(INT6). Прерывание INT6 настроено на low level. Вот пример кода: Код // Sleep Functions #define SELECT_IDLE SMCR &= ~((1<<SM0)|(1<<SM1)|(1<<SM2)) // Idle mode #define SELECT_ADC SMCR |= (1<<SM0) // ADC Noise Reduction Mode #define SELECT_POWERDOWN SMCR |= (1<<SM1) // Macro to select powerdown sleep mode #define SELECT_POWERSAVE SMCR |= (1<<SM0)|(1<<SM1) // Power Save Mode #define SELECT_STANDBY SMCR |= (1<<SM1)|(1<<SM2) // Standby Mode #define SELECT_EXT_STANDBY SMCR |= (1<<SM0)|(1<<SM1)|(1<<SM2) // Extended Standby Mode
#define SLEEP_ENABLE SMCR |= (1<<SE) // Set the SE (sleep enable) bit #define SLEEP_DISABLE SMCR &= ~(1<<SE) // Clear the SE (sleep enable) bit
int main() { ................................ SLEEP_ENABLE; SELECT_IDLE;
__enable_interrupt(); // set the Global Interrupt Enable Bit TCCR0B = 0x03; // Start System Timer f_clk/64 TIMSK0 |= (1<<TOIE0); // Разрешить прерывания Timer0 по переполнению (OVF) // Период переполнения Timer0 при f_clk=7.3728 Mhz 2.222 ms OS::Run(); }
void TLCD::OnOff(bool On) { if(On) {;} else { ............................................... PORTD |= (1<<SHDN); // Отключить аналоговую периферию //TIMSK0 &= ~(1<<TOIE0); SELECT_POWERDOWN; __sleep(); SELECT_IDLE; //TIMSK0 |= (1<<TOIE0); PORTD &= ~(1<<SHDN); // Включить аналоговую периферию } По команде __sleep() входит в POWER_DOWN. Это подтверждает снижение токопотребления и высокий уровень на SHDN. Но почему не просыпается при нажатии на кнопку, не могу понять.  .. Перепад в "0" на INT6 при нажатии наблюдаю тестером. PS. В errata есть замечание по поводу: 2. High current consumption in sleep mode If a pending interrupt cannot wake the part up from the selected mode, the current consumption will increase during sleep when executing the SLEEP instruction directly after a SEI instruction.
Problem Fix/workaround Before entering sleep, interrupts not used to wake up the part from the sleep mode should be disabled.У меня используется прерывание таймера0. Но запрещение перед входом в режим и разрешение по выходу из режима Power_Down не решает проблему. Какие будут предположения по данной проблеме?
|
|
|
|
|
Sep 5 2008, 06:12
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(SasaVitebsk @ Sep 4 2008, 21:55)  Надеюсь вы учли, что просыпаться только Only "INT3:0 or level interrupt INT7:4" Повторю еще раз. Прерывание INT6 настроено на low level. PS. По даташиту AT90USB1287 : Wake-up Sources from Power-down -> For INT7:4, only level interrupt.
|
|
|
|
|
Sep 5 2008, 07:33
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(alux @ Sep 4 2008, 18:38)  Код int main() { ................................ SLEEP_ENABLE; SELECT_IDLE;
__enable_interrupt(); // set the Global Interrupt Enable Bit TCCR0B = 0x03; // Start System Timer f_clk/64 TIMSK0 |= (1<<TOIE0); // Разрешить прерывания Timer0 по переполнению (OVF) // Период переполнения Timer0 при f_clk=7.3728 Mhz 2.222 ms OS::Run(); } не читал, но осуждаюпролетая над ЧереповцомПробегая мимо интернета нет времени внимательно вчитываться во всю тему, поэтому по теме ответить могу лишь то, что в той старой теме "не всё чисто" было не с прерываниями у 90usb, а с "очиткой". Автором были спутаны INT7 и PCINT7. Не по основной теме: не рекомендую разрешать прерывания до запуска OS::Run() - потребности в этом нет, а что-то левое может и вылезти. Прерывания разрешаются автоматически в конце переключения на первый выполняемый процесс, так как стек каждого процесса инициализируется конструктором таким образом, что в нём сидит образ статусного регистра с установленным битом разрешения прерываний, таким образом при первом переключении на процесс "восстанавливается" SREG.I == 1 и прерывания разрешены.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 5 2008, 09:12
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Цитата(ReAl @ Sep 5 2008, 10:33)  не рекомендую разрешать прерывания до запуска OS::Run() - потребности в этом нет, а что-то левое может и вылезти. Этот вопрос я уже поднимал ранее:Потребность иногда есть, например, когда необходимо проинициализировать АЦП, а SPI настроен по прерыванию: Код ......................... __enable_interrupt(); // set the Global Interrupt Enable Bit ad7799_Init(); TCCR0B = 0x03; // Start System Timer f_clk/64 TIMSK0 |= (1<<TOIE0); // Разрешить прерывания Timer0 по переполнению (OVF) // Период переполнения Timer0 при f_clk=7.3728 Mhz 2.222 ms OS::Run(); // при f_clk=20 Mhz 0.8192 ms } Получается сразу после ad7799_Init(); до запуска ОС нужно сделать __disable_interrupt(); ? Почему из POWER_DOWN не вызывается обработчик внешнего прерывания INT6 , настроенный по низкому уровню? Вызов ISR контролирую по изменению вывода BEEP: Код #pragma vector=INT6_vect OS_INTERRUPT void INT6_ISR() { OS::TISRW_SS ISRW;
DISABLE_INT6; // Prevent further external interrupts
Int6.SignalISR(); PORTC |= (1<<BEEP); }
|
|
|
|
|
Sep 6 2008, 08:33
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Второй раз наступаю на одни и те же грабли: Код void TLCD::OnOff(bool On) { if(On) {;} else { TCritSect cs; <<<<<<<<<<<!!!!!!!!!!!!!!!!!!!!!!!! ks0108ClearScreen(); // display clear ............................................................................. PORTD |= (1<<SHDN); // Отключить аналоговую периферию SELECT_POWERDOWN; __sleep(); SELECT_IDLE; PORTD &= ~(1<<SHDN); // Включить аналоговую периферию powerdown.Signal(); // Сигнал для инициализации меню после выхода из Power_Down } } Когда входим в Power Down, прерывания запрещены ( TCritSect cs;). Поэтому не вызывается обработчик прерывания. Прошу прощения, за свою невнимательность. И код в предыдущем посте я привел без этого момента
|
|
|
|
|
Sep 6 2008, 12:53
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(alux @ Sep 5 2008, 12:12)  Потребность иногда есть, например, когда необходимо проинициализировать АЦП, а SPI настроен по прерыванию: Код ......................... __enable_interrupt(); ad7799_Init(); TCCR0B = 0x03; TIMSK0 |= (1<<TOIE0); OS::Run(); } А почему бы не сделать это в начале функции процесса, которого этот АЦП интересует? Код template<> OS_PROCESS void TProc1::Exec() { ad7799_Init(); for(;;) { // ну а тут как обычно } } Цитата(alux @ Sep 5 2008, 12:12)  Получается сразу после ad7799_Init(); до запуска ОС нужно сделать __disable_interrupt(); ? Уже не нужно. Т.е. количественно ситуацию это изменит, качественно - нет. Смотрим. Пусть между разрешением прерываний и началом нормальной работы ОС возникает какое-то "осевое" прерывание, то же клавиатурное INT6 (маловероятно? ну тогда пусть от UART, в который кто-то ломится). В начале обработчика стоит OS::TISRW_SS ISRW;, смотрим код конструктора Код class TISRW_SS { public: INLINE TISRW_SS() { ISR_Enter(); } INLINE ~TISRW_SS() { ISR_Exit(); }
private: //----------------------------------------------------- INLINE void ISR_Enter() // volatile { if(Kernel.ISR_NestCount++ == 0) { SavedSP.DataSP = GetDataSP(); SavedSP.ReturnSP = GetReturnSP(); SetISRStackPointers(); // <---- ОЙ !!! } } . . . };
// А вот и ОЙ !!! INLINE inline void SetISRStackPointers() { ABS_WORD(28) = reinterpret_cast<word>(__segment_end("CSTACK")); SP = reinterpret_cast<word>(__segment_end("RSTACK")) - 1; } Итого обработчик прерывания переключил стек на осноной стек программы (он всё равно не используется при нормальном выполнении программы с scmRTOS. И имеет возможность затереть, например, находящийся там адрес возврата из того же любимого ad7799_Init();. Конечно, может повезти. И обработчик прерывания не затрёт основной стек. Но заглянем в другие порты - во многих (AVR/GCC, MSP430/*, ARM7) функция ISR_Enter() сделана одинаково и вот так: Код INLINE void ISR_Enter() { if(Kernel.ISR_NestCount++ == 0) { Kernel.ProcessTable[Kernel.CurProcPriority]->StackPointer = GetStackPointer(); SetISRStackPointer(); } } В данном случае вместо записанного конструктором процесса адреса "сэмулированного" тем же конструктором начального стекового кадра процесса будет записан адрес где-то в серёдке основного стека и OS::Run() для OS_Start() даст этот адрес.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|