Артём__ 0 26 апреля, 2012 Опубликовано 26 апреля, 2012 · Жалоба Открыл проект 1-EventFlag для AVR\IAR. Заменил M168 на M128: Error[Pe020]: identifier "SPMCR" is undefined P:\IAR_PROJECT\scm400\MEGA\1-EventFlag\Src\scmRTOS_TARGET_CFG.h 100 Error[Pe020]: identifier "SPMCR" is undefined P:\IAR_PROJECT\scm400\MEGA\1-EventFlag\Src\scmRTOS_TARGET_CFG.h 101 Error[Pe020]: identifier "SPMCR" is undefined P:\IAR_PROJECT\scm400\MEGA\1-EventFlag\Src\scmRTOS_TARGET_CFG.h 106 Error[Pe020]: identifier "SPMCR" is undefined P:\IAR_PROJECT\scm400\MEGA\1-EventFlag\Src\scmRTOS_TARGET_CFG.h 110 Это так и раньше было? Или что-то забыли добавить? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Еще небольшое замечание по ходу. Пользовательская функция system_timer_user_hook() в scmRTOS вызывается после перепланировщика. Ну, не после планировщика - планировщик всегда вызывается при выходе из прерывания, т.е. последним. Возможно, вы имели в виду, после функции Kernel.system_timer()? Может лучше ее вынести в начало обработчика системного таймера? В различных системах, где требуется манипуляция системами тактирования и режимами энергопотребления это идеологически правильно производить именно system_timer_user_hook(), но делать это лучше до вызова перепланировщика RTOS. Не очень понимаю проблему. Хук этот предназначен для выполнения пользовательского кода внутри обработчика системного таймера, и код этот как-то не предполагается, что тесно связан с потрохами ОС. Не могли бы вы пояснить на примере? Открыл проект 1-EventFlag для AVR\IAR. Заменил M168 на M128: Это так и раньше было? Или что-то забыли добавить? Так было всегда. Проблема тут в том, что описания регистров у AVR для разных МК нередко отличаются. Поэтому код, связанный с ними, и вынесен на уровень проекта, чтобы не привязывать исходники ОС к конкретным МК. Если меняется МК, то в этом конфигурационном заголовке надо и имена соответствующим образом поменять. А пример - он на то и пример, чтобы показать, как делается. Пользователь может вообще всё сделать по-своему - например, выбрать в качестве источника прерывания переключения контекстов какой-нибудь другой аппаратный модуль вместо используемого в примере. Просто SPM показался наиболее подходящим для этой цели. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Открыл проект 1-EventFlag для AVR\IAR. Заменил M168 на M128: Это так и раньше было? Или что-то забыли добавить? 51 //--------------------------------------------------------------------------- 52 // Sample target 53 // The sample is intended for following AVR microcontrollers: 54 // atmega48..atmega328 55 // atmega640..atmega2561 56 // Some changes in register names may be needed for other AVRs. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба 51 //--------------------------------------------------------------------------- 52 // Sample target 53 // The sample is intended for following AVR microcontrollers: 54 // atmega48..atmega328 55 // atmega640..atmega2561 56 // Some changes in register names may be needed for other AVRs. Ясно, не заметил. Раньше М128 без проблем запускалась. Ну да ладно, у Атмела местами такой бардак с именами, что на все случаи трудно сделать. Не очень понимаю проблему. Хук этот предназначен для выполнения пользовательского кода внутри обработчика системного таймера, и код этот как-то не предполагается, что тесно связан с потрохами ОС. Не могли бы вы пояснить на примере? Если я правильно понял, то проблема в том, что непонятно как строить системы, использующие различные режимы энергосбережения: в Idle_hook происходит засыпание МК в глубокий sleep с выключением кварца и прочей периферии. Просыпаться МК может например по прерыванию системного таймера, но все источники тактирования заглушены и их надо запустить и дождаться их готовности. Так вот как это правильней сделать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Если я правильно понял, то проблема в том, что непонятно как строить системы, использующие различные режимы энергосбережения: в Idle_hook происходит засыпание МК в глубокий sleep с выключением кварца и прочей периферии. Просыпаться МК может например по прерыванию системного таймера, но все источники тактирования заглушены и их надо запустить и дождаться их готовности. Так вот как это правильней сделать? Это, как я понимаю, зависит от конкретного МК. Только не ясно, как это связано с хуком системного таймера и его положением внутри обработчика прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Это, как я понимаю, зависит от конкретного МК. Такие вещи у всех МК специфичны. Только не ясно, как это связано с хуком системного таймера и его положением внутри обработчика прерывания. Системный таймер (работающий от часового кварца например) может быть источником пробуждения. А system_timer_user_hook можно бы использовать как функцию где включается периферия и кварц после сна. И чем раньше system_timer_user_hook будет вызван, тем лучше, так как после пробуждения МК работает от медленного RC. Сейчас сделано так: OS_INTERRUPT void OS::SystemTimer_ISR() { scmRTOS_ISRW_TYPE ISR; Kernel.system_timer(); #if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 0 DISABLE_NESTED_INTERRUPTS(); #endif #if scmRTOS_SYSTIMER_HOOK_ENABLE == 1 system_timer_user_hook(); #endif } А может лучше так? Пока выполняется Kernel.system_timer() происходит в фоне стабилизация кварца. OS_INTERRUPT void OS::SystemTimer_ISR() { scmRTOS_ISRW_TYPE ISR; #if scmRTOS_SYSTIMER_HOOK_ENABLE == 1 system_timer_user_hook(); #endif Kernel.system_timer(); #if scmRTOS_SYSTIMER_NEST_INTS_ENABLE == 0 DISABLE_NESTED_INTERRUPTS(); #endif } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Nixon 4 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Это не столько связано с включением/отключением кварца, сколько с переключением источника тактирования. Например я при idle переключаю основной CLK с 48MHz на 32kHz/1kHz (не могу я уснуть полностью - кое что делать приходится), по таймеру получаю управление в функцию хука, которая производит обратное действие, но перепланировка rtos при этом выполняется раньше, еще при работе от низкочастотного источника синхронизации. Получаем лишние задержки. _Артём_ все правильно написал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mdmitry 0 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Вопрос скорее по порту GCC ARM, навеян этим. Из каких соображений не используется структура .init секций? Насколько мне известно, в коммерческой (и триальной (была у меня)) сборках от CodeSourcery секции есть. Это связано с необходимостью писать соответствующий сложный startup? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Всё очень просто - когда писался порт, этого механизма не было. Тем более, стартап и линкерный скрипт всё равно свои, так что как сделали сначала, так и осталось. Только линкерный скрипт подправили при переходе на .init_array. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mdmitry 0 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Всё очень просто - когда писался порт, этого механизма не было. ?? Не знаю как на ARM, а на AVR .init было реализовано в 2008 (тут упомянуто). Порт для Cortex создавался же существенно позже. Эта поддержка была наверняка реализована в компиляторе. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба ?? Не знаю как на ARM, а на AVR .init было реализовано в 2008 (тут упомянуто). Порт для Cortex создавался же существенно позже. Эта поддержка была наверняка реализована в компиляторе. Так вы "не знаете", или всё же утверждаете "наверняка"? :) Порт для кортексов выпущен в 2009 году. В это время компилятор GCC только-только узнал о кортексах. Тот же самый Sourcery G++ Lite 2009q1-161 из своего дефолтного стартапа банально не вызывал конструкторы глобальных объектов, и не линковал их. Поэтому были написаны свой скрипт и стартап. И в чём, по-вашему, заключается "эта поддержка в компиляторе" при условии написания своего стартапа и линкерного скрипта? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ReAl 0 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба ?? Не знаю как на ARM, а на AVR .init было реализовано в 2008 (тут упомянуто). Порт для Cortex создавался же существенно позже. Эта поддержка была наверняка реализована в компиляторе. В компиляторе+линкере реализована поддержка секций вообще. Для AVR это часть avr-libc. В идущих в ней линкерных скриптах секции указаны в нужном порядке, в gcrt1.S используются некоторые из секций для нужд стартапа, остальные отданы пользователю. С компилятором тут связано разве что то, что он помещает конструкторы в выделенную для них секцию именно из этой группы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mdmitry 0 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Порт для кортексов выпущен в 2009 году. В это время компилятор GCC только-только узнал о кортексах. Тот же самый Sourcery G++ Lite 2009q1-161 из своего дефолтного стартапа банально не вызывал конструкторы глобальных объектов, и не линковал их. Поэтому были написаны свой скрипт и стартап. Глянул на lite и trial: в lite нет многих файлов инициализации, которые есть в trial. Следовательно: Так вы "не знаете", или всё же утверждаете "наверняка"? :) В trial есть, в lite нет. И в чём, по-вашему, заключается "эта поддержка в компиляторе" при условии написания своего стартапа и линкерного скрипта? При этом условии ни в чем. Понятно, что писать свой аналог тяжело, и следовательно, не необходимо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 15 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба С компилятором тут связано разве что то, что он помещает конструкторы в выделенную для них секцию именно из этой группы. Именно! Но не для arm-gcc. Раньше (во время выпуска первых версий порта для кортексов) конструкторы помещались в секцию .ctors, а сейчас они переехали в .init_array. Получается, что arm-gcc вообще никак не поддерживал эти .init, а использовал и использует другие механизмы :) Кстати, вот здесь klen очень подробно расписал, как должен работать механизм с .init_array. И ещё вот здесь обсуждали это. В trial есть, в lite нет. Извините, но не верю. Линкерные-то скрипты - они все есть и в lite. И там нет поддержки .initX секций. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mdmitry 0 27 апреля, 2012 Опубликовано 27 апреля, 2012 · Жалоба Извините, но не верю. Линкерные-то скрипты - они все есть и в lite. И там нет поддержки .initX секций. Зарегистрируйтесь здесь, скачайте, установите и сравните. Там несколько файлов с копирайтом CodeSourcery, включая бинарные. В составе поставки расширенные библиотеки и другие отличия. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться