реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Перенос векторов прерываний в nRF51822
sevstels
сообщение Mar 19 2018, 13:55
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Подскажите если есть идеи, где мог сделать ошибкy.

Недавно подключить к готовому проекту Cortex M0 bootloader. Перенес вектора прерываний приложения из начала флеш в середину, сделал ремап векторов. scmRTOS запускается успешно но стал вылетать в HardFault_Handler после вызова channel.push() в прерывании UART.

Вылет происходит когда накладываюя 2 прерывания.
От системного таймера и вызова метода push().

Поиск выхода в точку падения по методу Сергей Борщ, в дизассемблере по шагам на выход из обработчика стабильно приводит к позиции scmRTOS: while(CurProcPriority != SchedProcPriority);

Размер стека я менял - не помогает.
Если медленно шагать по щагам в дизасме, найти точку вылета не получается. Все работает.

Я знаю, что каналы в прерываниях использовать не рекомендовано. Но программа отлично и долго работала в этом варианте. И только сдвиг векторов из начала flash порушил работоспособность.

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


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 19 2018, 14:52
Сообщение #2


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (sevstels @ Mar 19 2018, 15:55) *
Подскажите если есть идеи, где мог сделать ошибкy.

1) Вы перед запихиванием в канал проверяете наличие в нем свободного места?
2) Какая ассемблерная инструкция вызывает падение, какие значения имеют используемые в ней регистры?



--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 19 2018, 15:52
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



1. Свободное место проверяется, канал никогда не переполняется.

2. Не могу точно посмотреть. После выхода из обработчика и ввода в дебагер адреса из sp, оказываюсь на адресе в ram где лежит os_kernel. Никаких асм инструкций ..


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 19 2018, 18:45
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (sevstels @ Mar 19 2018, 17:52) *
2. Не могу точно посмотреть. После выхода из обработчика и ввода в дебагер адреса из sp, оказываюсь на адресе в ram где лежит os_kernel. Никаких асм инструкций ..
Недопонял. Вы же писали, что исключение происходит при выполнении кода "while(CurProcPriority != SchedProcPriority);". Посмотрите конкретную инструкцию в окне дизассемблера. И что за шаманство с вводом адреса из sp?

Вопрос третий - вылетает при первом же обращении к push()? Не может такого быть, что у вас прерывание возникает раньше, чем запустилась ОС?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 20 2018, 05:14
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



>> что за шаманство с вводом адреса из sp?

Нашел данную методику но она не помогает.

1. Первым важным для нас регистром является счетчик команд.
Переменная pc содержит значение счетчика команд где содержится адрес инструкции, которая выполнялась, когда произошла
Hard Fault ошибка (или другая ошибка).

Чтобы найти инструкцию по адресу, содержащемуся в переменной pc,
откройте окно Disassembly (IAR) в отладчике и вручную введите адрес в окно Go to для
просмотра asm инструкций по этому адресу.

2. Далее вручную установите точку останова в Disassembly отладчике или точку прерывания
выполнения или доступа по этому адресу. С установленной точкой
останова перезапустите приложение, чтобы увидеть, к какой
строке C/C++ кода относится инструкция.

3. Код обработчика HardFault_Handler()

#pragma section = "CSTACK"
#pragma optimize=none
extern "C" void HardFault_Handler(void)
{
volatile uint32_t r0;
volatile uint32_t r1;
volatile uint32_t r2;
volatile uint32_t r3;
volatile uint32_t r12;
volatile uint32_t lr;
volatile uint32_t pc;
volatile uint32_t psr;

uint32_t *pStackAddress = (uint32_t*)__section_begin("CSTACK");
r0 = pStackAddress++;
r1 = pStackAddress++;
r2 = pStackAddress++;
r3 = pStackAddress++;
r12 = pStackAddress++;
lr = pStackAddress++; //Link register
pc = pStackAddress++; //Program counter
psr = pStackAddress; //Program status register

//When the following line is hit, the variables contain the register values

volatile int i = 0;
while(i==0); //Stop here
}

По данной методике результат можно посмотреть на картинке.

Методика 2.
Шагаем в Disassembly из обработчика.

Момент останова в обработчике > картинка
Момент выхода из обработчика > картинка

>>Вопрос третий - вылетает при первом же обращении к push()?
Обычно после первого же, но иногда со второго.

>>прерывание возникает раньше, чем запустилась ОС?
Исключено. Прерывания запрещены до старта OS. Прерывание UART приходит с компа по моей команде, когда уже программа запущена. Если метод push() закомментировать, то все работает, но нет связи по UART.

Сообщение отредактировал sevstels - Mar 20 2018, 07:04


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 20 2018, 06:45
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



All pictures by one zip

На мой взгляд целесообразно ввести в port раздельное заполнение тестовым паттерном.
#define scmRTOS_STACK_PATTERN 0xAAAAAAAAUL
#define scmRTOS_PROCESS_PATTERN 0xBBBBBBBBUL

Сообщение отредактировал sevstels - Mar 20 2018, 07:56


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 20 2018, 14:13
Сообщение #7


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (sevstels @ Mar 20 2018, 07:14) *
Нашел данную методику но она не помогает.
По данной методике результат можно посмотреть на картинке.
На всех ваших картинках SP_main имет значения порядка 0x2000043x, то есть стек прерываний расположен где-то в начале ОЗУ и, судя по всему, довольно небольшого размера. Такое ощущение, что этот стек переполняется и затирает объект OS::Kernel, а дальше, при перепланировке, происходит унос черт знает куда из-за загрузки мусора в PC.

На картинке test-3 в архиве (по прямой ссылке другая картинка) отладчик показывает адрес OS:TKernel равный 0x0000122B, но этого не может быть - в этих адресах нет ОЗУ.


Расскажите более подробно о ремапе векторов. Возможно вы в нем затираете какие-то данные.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 20 2018, 17:46
Сообщение #8


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(sevstels @ Mar 19 2018, 15:55) *
Недавно подключить к готовому проекту Cortex M0 bootloader. Перенес вектора прерываний приложения из начала флеш в середину, сделал ремап векторов. scmRTOS запускается успешно но стал вылетать в HardFault_Handler после вызова channel.push() в прерывании UART.

Немного не вяжется: у вас Cortex M0 или Cortex M0+ ?
У Cortex M0 нет регистра VTOR, соответственно нельзя перенести таблицу векторов в середину флеш.
Можно только в начало ОЗУ.
Может дело в этом?
Тогда при первом прерывании программа и будет улетать неизвестно куда.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 20 2018, 18:47
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Baser @ Mar 20 2018, 19:46) *
Немного не вяжется: у вас Cortex M0 или Cortex M0+ ?
У Cortex M0 нет регистра VTOR, соответственно нельзя перенести таблицу векторов в середину флеш.
У M0+ вроде тоже нет. Но у них есть процедура отражения ОЗУ на начало памяти (remap), таким образом можно скопировать вектора в начало ОЗУ откуда угодно.
QUOTE (Baser @ Mar 20 2018, 19:46) *
Можно только в начало ОЗУ.
Собственно, да.

Меня очень смущает расположение основного стека близко к началу ОЗУ. Обычно его располагают в самом конце, чтобы он мог расти максимально далеко.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 20 2018, 22:00
Сообщение #10


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(Сергей Борщ @ Mar 20 2018, 20:47) *
У M0+ вроде тоже нет.

У STM Cortex-m0+ это семейство STM32L0, в нем есть VTOR
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 21 2018, 11:21
Сообщение #11


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Цитата(Baser @ Mar 21 2018, 02:46) *
Немного не вяжется: у вас Cortex M0 или Cortex M0+ ?
У Cortex M0 нет регистра VTOR, соответственно нельзя перенести таблицу векторов в середину флеш.
Можно только в начало ОЗУ.


Проект базируется на nRF51822, а это Cortex M0, VTOR нет. Но на мой взгляд, таблицу перенести можно. Для этого в стандартный (нулевой) адрес FLASH следует записать таблицу общую для bootloader и для application.

Bootloader: *iar_startup.s file
В этой таблице заменить все вектора на адрес функции обработчика прерывания.

Код
Address from 0x0000
            SECTION .main_intvec
     __vector_table_main
             DCD     sfe(CSTACK)
             DCD     Reset_Handler
             DCD     irq_forwarder
             DCD     irq_forwarder
             DCD     0; Reserved
             DCD     0; Reserved
             DCD     0; Reserved
             DCD     0; Reserved
             .......


Далее собственная таблица векторов bootloader. Она может располагаться где угодно в пространстве FLASH, задается в настройках линкера.
Any FLASH address

Код
   SECTION .boot_intvec
     __vector_table
             DCD     sfe(CSTACK)
             DCD     Reset_Handler
             DCD     NMI_Handler
             DCD     HardFault_Handler
             DCD     0                        ; Reserved
             DCD     0                        ; Reserved
             DCD     0                        ; Reserved
             DCD     0                        ; Reserved
             DCD     0                        ; Reserved
             DCD     0                        ; Reserved
             DCD     0                        ; Reserved
             DCD     SVC_Handler
             DCD     0                        ; Reserved
             DCD     0                        ; Reserved
             DCD     PendSV_Handler
             DCD     SysTick_Handler

Далее за основной таблицей прерываний располагаем функцию форварда адресов:

Linker file:
place at address mem: 0xc8 {readonly section .irq_forwarder};
keep { section .irq_forwarder };

Code file:

Переменная irq_table_offset может указывать смещение как во FLASH так и в RAM.

Код
irq_table_offset @ 0x20000000 = (unsigned long) __section_begin(".boot_intvec");
     typedef void (*irq_handler_t)(void);
    
     __root void irq_forwarder(void)
     {
      
       //Read the number of the currently executing interrupt handler from IPSR.
       //See the Cortex-M0 user guide for details.
       uint32_t irq_interrupt_number = __get_IPSR();
      
       //Find the address offset in the vector table
       //for the currently running interrupt, irq_interrupt_number * 4
       uint32_t vector_table_offset = irq_interrupt_number << 2;
      
       //Get the address of the vector in the offset vector table
       uint32_t offset_vector_address = vector_table_offset + irq_table_offset;
       ///uint32_t offset_vector_address = vector_table_offset + (uint32_t)&irq_ram_table[0];
    
       //Read the address of the IRQ handler to branch to from the offset vector
       irq_handler_t irq_handler=(irq_handler_t)(*(uint32_t*)offset_vector_address);
    
       //Branch to the irq_handler
       irq_handler();
     }


При запуске bootloader инициализация:
irq_table_offset = (unsigned long) __section_begin(".boot_intvec");

При запуске application from bootloader инициализация:
Код
typedef void (*application_main_t)(void);
    
  apl_base_addr = find_application();
  launch_application(apl_base_addr);

     void launch_application(unsigned long base_addr)
     {
       unsigned long *pData;
       unsigned long appl_cstack_pointer;
       application_main_t appl_reset_handler;
          
       //Get application CSTACK value  
       pData = (unsigned long*)base_addr;
       appl_cstack_pointer = *pData++; //+4 bytes
    
       //Get Reset_Handler vector value from application intvec table
       appl_reset_handler = *(application_main_t*)(pData);
                
       //Set mode flag
       NRF_POWER->GPREGRET = DEV_APPLICATION_MODE;
          
       //Set application CStack pointer
       __set_SP(appl_cstack_pointer);
    
       //Jump to application Reset_Handler
       appl_reset_handler();
     }

Траблы происходят из за использования форвардера Я не смог его обьявить как __task, компилятор воспротивился, чтоб запретить сохранять на стеке адрес возврата. Видимо проблема в этой точке кода. Помогите исправить и проверить идею Практически на 90% работает sm.gif

>> Меня очень смущает расположение основного стека близко к началу ОЗУ. Обычно его располагают в самом конце.
Пока не могу преодолеть. Усилия перенести стек в конец RAM, яростно отвергаются линкером.

Код
place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
place in ROM_region   { readonly };
place in RAM_region   { readwrite, block CSTACK, block HEAP };
//place at end of RAM_region {readwrite};


Строка place at end of RAM_region вызывает выдачу моря ошибок линковки.


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 21 2018, 12:20
Сообщение #12


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(sevstels @ Mar 21 2018, 13:21) *
Помогите исправить и проверить идею Практически на 90% работает sm.gif

Не слишком углублялся в вашу идею, уж больно она нестандартная laughing.gif
А чем вам не угодил стандартный способ ремапа векторов прерываний с копированием в начало ОЗУ?
При этом создаются два независимых проекта, можно отлаживаться как отдельно, так и вместе (в ИАРе).
Ссылки на примеры на STM32, но принципы то одинаковы:
Bootloader on STM32F0
Interrupt vector table relocation on cortex M0

з.ы. зря вы закинули свой вопрос в эту тему, судя по всему, ваши проблемы никак не касаются scmRTOS...
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 21 2018, 13:40
Сообщение #13


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



>> чем не угодил стандартный способ ремапа
Не нашел функцию SYSCFG_MemoryRemapConfig.



--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 21 2018, 13:59
Сообщение #14


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(sevstels @ Mar 21 2018, 15:40) *
>> чем не угодил стандартный способ ремапа
Не нашел функцию SYSCFG_MemoryRemapConfig.

Похоже вы правы - глянул, System configuration controller (SYSCFG) это периферия STM32F0, она не входит в ядро Cortex-M0. Так что в вашем nRF51822 его может и не быть. А что производитель рекомендует для ремапа? Тот метод, что вы применили?
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 21 2018, 14:35
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Производитель еще тот крендель. Они ничего не рекомендуют кроме своих сборок. Обойти их безумный индуский код стороной - было лучшее решение в данном случае.

Вероятно они поленились и в их 'авторско горяче-финской' модификации ядра никак не предусмотрен перенос векторов. Теперь каждый спасется как может...


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 21 2018, 14:51
Сообщение #16


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Ух ты, сколько интересного я пропустилsm.gif

Предлагаю попробовать сделать форвардер на каждый вектор в отдельности. Возможно, глючит определение активного прерывания.

ЗЫ. И надо бы это обсуждение в отдельную тему вынести.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 21 2018, 15:00
Сообщение #17


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Проверял. Смещение текущего прерывания четко определяет без ошибок. Более того, bootloader полностью рабочий через форвардер, пишет, проверяет, запускает. Прерывания нормально используются, ничего не крэшится.

Трудности начинаются в приложении. Оно под scmRTOS, поэтому и написал в эту ветку, тк причина была не совсем очевидна.


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 21 2018, 15:13
Сообщение #18


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(sevstels @ Mar 21 2018, 20:00) *
Проверял. Смещение текущего прерывания четко определяет без ошибок.


И тем не менее. Попробуйте сделать пять-шесть отдельных обработчиков (думаю, для тестового приложения хватит), каждый из которых проверяет переменную "работает_приложение", и прыгает на соответствующий обработчик в приложении. Возможно по шагам оно всё хорошо работает, а без отладки, да ещё при наложении прерываний - плохо.

Кстати, использовать очереди в прерываниях очень даже можно. Единственное условие - проверять, что в очереди есть место.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 21 2018, 15:27
Сообщение #19


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Уже этот вариант тестил. В ОЗУ выделил константу, которую приложение на старте инит величиной смещения своих векторов. Для бута значение одно, для приложения - совсем другое. Это делается при запрещенных прерываниях на самом старте.
Примите во внимание момент. Если не дергать метод push(), то приложение не падает. Все прерывания четко отработывают, их 6.


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Mar 21 2018, 18:15
Сообщение #20


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



push() вызывает перепланировку. Взводит флаг прерывания PendSV.

Есть ещё одна мысль. А вы в прерываниях не забыли объявить OS:TISRW?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 21 2018, 18:29
Сообщение #21


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Нет, все на месте, первым делом макрос проверяю. Вероятно все же дело в функции форварда векторов, вернее в нюансах ее сборки компилятором. Я в arm asm не силен, видимо придется вникать чтоб разобраться. Тк у гуру походу тоже идей нет.


Сообщение отредактировал sevstels - Mar 21 2018, 18:45


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 22 2018, 09:24
Сообщение #22


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(sevstels @ Mar 21 2018, 16:35) *
Производитель еще тот крендель. Они ничего не рекомендуют кроме своих сборок. Обойти их безумный индуский код стороной - было лучшее решение в данном случае.

Вероятно они поленились и в их 'авторско горяче-финской' модификации ядра никак не предусмотрен перенос векторов. Теперь каждый спасется как может...

Глянул форум Нордика, действительно, есть только такое единственное предложение по ремапу векторов. Видимо и в их библиотеках применяется подобный метод, который они называют MBR. Так что метод должен работать, видимо дело в нюансах, что-то упустили.

Цитата(sevstels @ Mar 21 2018, 17:00) *
Проверял. Смещение текущего прерывания четко определяет без ошибок. Более того, bootloader полностью рабочий через форвардер, пишет, проверяет, запускает. Прерывания нормально используются, ничего не крэшится.

Трудности начинаются в приложении. Оно под scmRTOS...

Навскидку, если очевидные вещи вы уже проверили, еще могут быть такие узкие места:
1. Еще раз проверить функции ремапа на реентерабельность, нет ли скрытых камней при обработке вложенных прерываний.
2. Разграничение физических областей кода бутлодера и приложения. Нет ли какого-нибудь ограничения чтения одной области из другой области через какие-нибудь биты защиты кода или через MPU (Memory Protection Unit).
3. На всех ли векторах прерываний в обеих таблицах есть заглушки при неиспользуемых векторах. А то может возникнуть прерывание, на которое вы не рассчитывали, а там пустота или другой код.
Go to the top of the page
 
+Quote Post
sevstels
сообщение Mar 22 2018, 15:57
Сообщение #23


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Спасибо.
К сожалению таймаут на месяц. Вернусь с отпуска, продолжу.


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 23 2018, 11:01
Сообщение #24


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Чтобы за время вашего отпуска мысли не забылись, изложу их кратенько тут:
1) в launch_application я не заметил установки нового значения в irq_table_offset.
2) irq_forwarder писали индусы. Накой этот закат солнца вручную? "Машина должна работать, а человек - думать". С расчетом всех этих адресов прекрасно справляется компилятор :
CODE
typedef void (*irq_handler_t)(void);

// pointer to interrupt vectors table
irq_handler_t * irq_table @ 0x20000000 = (irq_handler_t *) __section_begin(".boot_intvec");

void irq_forwarder(void)
{
    //Branch to IPSR-th handler the irq_table
    irq_table[__get_IPSR()]();
}

3) __root не нужен для irq_forwarder - на него есть ссылка из таблицы векторов. А если ссылки нет - то функция не нужна, ее можно выкинуть и __root тут никак не поможет.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
sevstels
сообщение May 2 2018, 01:39
Сообщение #25


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Снимаю шляпу... реально гениально.
Ваша версия irq_forwarder не только быстрее но и работает.
Проверил как с векторами в flash так и в ram - падения прекратились и все работает как в приложении так и буте. Спасибо... респект.


--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 21:21
Рейтинг@Mail.ru


Страница сгенерированна за 0.01649 секунд с 7
ELECTRONIX ©2004-2016