Сергей Борщ 186 February 9, 2011 Posted February 9, 2011 · Report post Есть ни что иное, как запрещение прерываний на время окончания записи в ЕЕПРОМВнимательно читайте даташит и включайте голову. Это запрещение прерываний на две команды запуска процесса записи, 4 такта. В IAR EWAVR 5.50 в файле eeprom.s90 нет запрещений прерываний на время ожидания окончания записи в ЕЕПРОМВ IAR EWAVR 5.50 есть ключевое слово __eeprom. eeprom.s90 пора забыть еще в версии 1.26. Ждать окончания записи можно и с разрешенными прерываниями. Quote Share this post Link to post Share on other sites More sharing options...
quarter2 0 February 9, 2011 Posted February 9, 2011 (edited) · Report post Внимательно читайте даташит и включайте голову. Это запрещение прерываний на две команды запуска процесса записи, 4 такта. Про пример из даташита - согласен. В примере как раз прерывания отключаются на время запуска процесса записи в ЕЕПРОМ. Но в файле eeprom.s90 как раз прерывания отключаются на время окончания записи в ЕЕПРОМ: ;---------------------------------------------------------- ; ?eewait ; ; Wait for previous eeprom write operation to complete ; ; SIZE: 6 bytes RSEG CODE:CODE:NOROOT(1) ?eewait: CLI SBIS EECR,EEWE ; Loop until previous write is completed RET OUT SREG,T0 RJMP ?eewait В IAR EWAVR 5.50 есть ключевое слово __eeprom. eeprom.s90 пора забыть еще в версии 1.26. Неправильно. Все переменные, которые объявлены ключевым словом __eeprom при компиляции для работы с областью памяти ЕЕПРОМ используют файл eeprom.s90 Ждать окончания записи можно и с разрешенными прерываниями. Если бы не наступал на эти грабли - не поднимал бы вопрос. Без запрещения прерываний на время окончания записи есть вероятность некорректной записи данных в область ЕЕПРОМ Edited February 9, 2011 by quarter2 Quote Share this post Link to post Share on other sites More sharing options...
Сергей Борщ 186 February 9, 2011 Posted February 9, 2011 · Report post Неправильно. Все переменные, которые объявлены ключевым словом __eeprom при компиляции для работы с областью памяти ЕЕПРОМ используют файл eeprom.s90 Не совсем так - они используют функции из библиотеки. Возможно, источником при компиляции библиотеки является этот самый eeprom.s90. Если вы добавите этот файл в проект, то его функции заменять одноименные библиотечные. Давно не пользуюсь ИАРом для AVR, не могу посмотреть что он там берет из библиотеки. Посмотрел старый проект - использовался компилятор версии 2.28, прерывания мною не запрещались, прерывания шли довольно активно, сбоев при записи не было. Без запрещения прерываний на время окончания записи есть вероятность некорректной записи данных в область ЕЕПРОМПрерывания тут не при чем - никогда не держу прерывания запрещенными во время записи и ни разу не нарывался на некорректную запись. Возможно вы используете (хотя бы и на чтение) __eprom-переменные в прерываниях, в этом случае - да, будут проблемы. Но это уже не проблема прерываний, а неверное архитектурное решение. Quote Share this post Link to post Share on other sites More sharing options...
quarter2 0 February 9, 2011 Posted February 9, 2011 · Report post Не совсем так - они используют функции из библиотеки. Возможно, источником при компиляции библиотеки является этот самый eeprom.s90. Если вы добавите этот файл в проект, то его функции заменять одноименные библиотечные. На IAR EWAVR только что откомпилил простенькую программку с записью в ЕЕПРОМ, при это файл eeprom.s90 в проект не включал. В дебаг-режиме увидел, что линкер точно подставляет в выходной код строки из C:\Program Files\IAR Systems\Embedded Workbench 5.5\avr\src\lib\eeprom.s90 Возможно вы используете (хотя бы и на чтение) __eprom-переменные в прерываниях, в этом случае - да, будут проблемы. Но это уже не проблема прерываний, а неверное архитектурное решение. Нет, в прерываниях __eprom-переменные не использую. При этом ЕЕПРОМ случайным образом, то пишется правильно, то с ошибками. Если включаю в проект файл eeprom.s90, в котором отключаются прерывания - данные в ЕЕПРОМ пишутся абсолютно правильно. Quote Share this post Link to post Share on other sites More sharing options...
SWD 0 February 28, 2011 Posted February 28, 2011 · Report post Здравствуйте. scmRTOS работает на ATxmega128A1 (спасибо ReAl за подсказки). Пока в контексте сохраняются не все RAMP регистры (пока не нужны). Возникли трудности с многоуровневым контроллером прерываний. Критические секции вставил и в SYS_TIMER_CRIT_SECT() и в обёртки TISRW/TISRW_SS. Уровни всех прерываний установлены LO, при установке уровня прерывания системного таймера MED через пару секунд все перестает работать. У кого какие мысли по этому поводу?, как заставить ОСь работать с различными уровнями прерываний? Quote Share this post Link to post Share on other sites More sharing options...
SWD 0 March 1, 2011 Posted March 1, 2011 · Report post Добавил сохранение в контекст RAMPD и RAMPX. Проблему прерываний решил установкой уровня программного прерывания "HI". Возможно, есть и другие решения …, предположительно два … ) Quote Share this post Link to post Share on other sites More sharing options...
ReAl 0 March 1, 2011 Posted March 1, 2011 · Report post Возникли трудности с многоуровневым контроллером прерываний. Критические секции вставил и в SYS_TIMER_CRIT_SECT() и в обёртки TISRW/TISRW_SS. Уровни всех прерываний установлены LO, при установке уровня прерывания системного таймера MED через пару секунд все перестает работать. У кого какие мысли по этому поводу?, как заставить ОСь работать с различными уровнями прерываний? Надеюсь, доберусь до этого где-то в середине марта. Раньше никак, хотя всё думал «ну вот в ближайшие выходные». Quote Share this post Link to post Share on other sites More sharing options...
quarter2 0 April 22, 2011 Posted April 22, 2011 · Report post Вопрос к разработчикам scmRTOS: 1. почему исходники не содержат __watchdog_reset() хотя бы через #define ? каждый раз после апдейта приходится практически во всех файлах после while и for вставлять __watchdog_reset() 2. было бы неплохо внести дополнения в описание класса process: template<TPriority pr, size_t stack_size, size_t rstack_size> class process : public TBaseProcess { public: INLINE_PROCESS_CTOR process(); int StackFree() { word Free = 0; for(;;) { // stack always has non-0xAB items. if( Stack[Free] != 0xAB ) return Free; ++Free; } } int StackUsed() { return stack_size - StackFree(); } OS_PROCESS static void exec(); private: stack_item_t Stack [stack_size/sizeof(stack_item_t)]; stack_item_t RStack[rstack_size/sizeof(stack_item_t)]; }; template<TPriority pr, uint16_t stack_size, uint16_t rstack_size> process<pr, stack_size, rstack_size>::process() : TBaseProcess( &Stack[stack_size/sizeof(stack_item_t)] , &RStack[rstack_size/sizeof(stack_item_t)] , pr , reinterpret_cast<void (*)()>(exec) #if scmRTOS_DEBUG_ENABLE == 1 , Stack , RStack #endif ) { stack_item_t *pDst = Stack; word Size = StackPointer - Stack; while(Size) { *pDst++ = 0xAB; --Size; } } т.к. StackUsed() и StackFree() очень сильно помогают при отладке Quote Share this post Link to post Share on other sites More sharing options...
ReAl 0 April 22, 2011 Posted April 22, 2011 · Report post 1. почему исходники не содержат __watchdog_reset() хотя бы через #define ? каждый раз после апдейта приходится практически во всех файлах после while и for вставлять __watchdog_reset() 1. Назачем нужен WDT, который тупо сбрасывается во всех цилах? 2. Где в потрохах scmRTOS есть циклы, в которых управление задерживается на время, критичное с точки зрения успевания сбросить WDT ? 2. было бы неплохо внести дополнения в описание класса process:Контроль стеков и профилировщик добавлены в ветке репозитория branches/pre-v400, которая в скором времени превратится в scmRTOS v4.00 Quote Share this post Link to post Share on other sites More sharing options...
Артём__ 1 January 16, 2012 Posted January 16, 2012 · Report post Здраствуйте. Попробовал недавно scmRTOS - понравилось, но толку...для xmeg поддержки нет, а хотелось бы. Появилось желание перенести версию 3.10 на хмегу. Но возникло столько вопросов и непонятных моментов, что кажется хотелки так хотелками и остануться... Попытаюсь здесь изложить моменты которые, как мне кажется нужно поменять в версии и вызывающие у меня сомнения. хотелось бы увидеть критику/советы как сделать лучше/как делать не надо, тд и тп. Общие для разных схем переключения контекста моменты. 1. Функции SetDataSP/GetDataSP: Заменить на (для начала сгодится, хотя лишний call/ret, но как лучше не нашёл): GetDataSP: mov R16, R28 mov R17, R29 ret SetDataSP: mov R29,R17 mov R28,R16 ret и соотв. extern "C" { TStackItem* GetDataSP(); }; extern "C" { void SetDataSP(TStackItem* sp); }; 2. Добавить в контекст RAMP_XYD. С этим понятно. 3. Были тут высказаны идеи о включении в контекст регистра разрешённых прерываний, но мне кажется что это необязательно. Или нет? I. Схема переключения контекста по прерыванию. 1. Добавить запрет прерыванию после перехода на вектор ContextSwitcher_ISR, но пока не понял куда именно добавить чтоб и наверняка и критическая секция была как можно короче? save_SREG cli; запрет прерываний save_SP save_regs save_SFRS ;cli; запрет прерываний или здесь правильней? mov r16,r28 ; load current stack pointer mov r17,r29 ; as argument xcall OS_ContextSwitchHook ; mov r28,r16 ; set next stack pointer mov r29,r17 ; from return value 2. Ещё совершенно непонятный для меня момент: каким уровнем лучше расположить ContextSwitcher_ISR? Или не это непринципиально, а атомарность переключения? С этой схемой как бы всё. Или нет? Тогда что я упустил? II. Схема с прямой передачей управления. 1. Прерывания с TISRW_SS Если я правильно понял, то в мегах выход из прерывания при переключении реализуется таким путём: переход на вектор прерывания-> функция прерывания-> вариант 1: перепланировка не нужна->reti вариант 2: перепланировка нужна->OS_ContextSwitcher->ret Если использовать прерывания, использующие сервисы ОС, только одного уровня, то можно так: OS_ContextSwitcher: save_SREG save_SP save_regs save_SFRS mov r30,r16; Curr_SP_addr mov r31,r17; std Z+0,r28; save process's Stack Pointer std Z+1,r29; mov r28,r18; load next process Stack Pointer mov r29,r19; lds R16, 0x00A0; PMIC.STATUS andi R16, 7 BRNE Int_RestoreContext L_RestoreContext: restore_SFRS restore_regs restore_SP restore_SREG ret Int_RestoreContext: restore_SFRS restore_regs restore_SP restore_SREG reti Но решение какое-то ограниченное... Попробовал изменить TISRW_SS class TISRW_SS { public: INLINE TISRW_SS(byte int_level) { #if scmRTOS_CONTEXT_SWITCH_SCHEME==0 CurrentInterruptLevelMask=~int_level; CurrentInterruptLevelMask&=scmRTOS_INTERRUPT_LEVEL_MASK; #endif ISR_Enter(); } INLINE ~TISRW_SS() { ISR_Exit(); } private: #if scmRTOS_CONTEXT_SWITCH_SCHEME==0 byte CurrentInterruptLevelMask; #endif //----------------------------------------------------- INLINE void ISR_Enter() // volatile { TCritSect cs; if(Kernel.ISR_NestCount++ == 0) { SavedSP.DataSP = GetDataSP(); SavedSP.ReturnSP = GetReturnSP(); SetISRStackPointers(); } #if scmRTOS_CONTEXT_SWITCH_SCHEME == 1 DisableContextSwitch(); #endif } //----------------------------------------------------- INLINE void ISR_Exit() { TCritSect cs; if (--Kernel.ISR_NestCount==0) { SetReturnSP(SavedSP.ReturnSP); SetDataSP (SavedSP.DataSP); } #if scmRTOS_CONTEXT_SWITCH_SCHEME==0 if (PMIC.STATUS&CurrentInterruptLevelMask) return ; #endif Kernel.SchedISR(); } //----------------------------------------------------- }; Но тоже какая-та ерунда: теперь получается что все прерывания одного уровня должны либо использовать, либо не использовать TISRW_SS. В общем тоже костыль получился, хотя и выглядит работающим (см. приложение). В связи с этой проблемой вопрос: можно ли заставить IAR сделать функию прерывания ещё и __monitor (возможно ли это в хмегах вообще - запретить прерывание более высокого уровня след. командой после перехода с вектора прерывания и будет ли этот запрет отрабатываться)? Этот вариант завтра попробую. Спасибо. xm.rar Quote Share this post Link to post Share on other sites More sharing options...
ReAl 0 February 12, 2012 Posted February 12, 2012 · Report post Ой-ой-ой... Мне самому xmega до сих пор как-то не нужна, вот я и тяну. В очередной раз достал наверх макетку с atxmega128a1, помигал светодиодом, буду искать время на scmRTOS на ней. Quote Share this post Link to post Share on other sites More sharing options...
Артём__ 1 February 12, 2012 Posted February 12, 2012 · Report post Ой-ой-ой... Это вы о чём? По поводу моей писанины или вообще? Мне самому xmega до сих пор как-то не нужна, вот я и тяну. Это понятно. STM8 лучше xmeg-и? В очередной раз достал наверх макетку с atxmega128a1, помигал светодиодом, буду искать время на scmRTOS на ней. Ждём. Quote Share this post Link to post Share on other sites More sharing options...
a9d 0 February 12, 2012 Posted February 12, 2012 · Report post Стмка на порядок дешевле. И там есть свои вкусности. Например можно подгружать с внешней памяти функции в оперативку и выполнять их. Но у них есть большой минус связанный с ихним трехуровневым конвейером. Из за него нельзя делать софтварные задержки и будут проблемы с софтварным 1-wire. Quote Share this post Link to post Share on other sites More sharing options...
Артём__ 1 February 12, 2012 Posted February 12, 2012 · Report post Стмка на порядок дешевле. Реально на порядок? Посмотрю. Например можно подгружать с внешней памяти функции в оперативку и выполнять их. Жаль в АВР такого нет. Полезная возможность. Но у них есть большой минус связанный с ихним трехуровневым конвейером. Из за него нельзя делать софтварные задержки и будут проблемы с софтварным 1-wire. Зачем программно? Аппаратные ресурсы надо задействовать. Quote Share this post Link to post Share on other sites More sharing options...
a9d 0 February 12, 2012 Posted February 12, 2012 · Report post stm8 настолько дешевые, что стоят почти как stm32. И тут стоит вопрос нахрена их брать? В ST конечно умные дядьки сидят и они выпустили ультра дешевые stm8 с менее прочной флешпамять(100 гарантированных циклов записи), но полностью совместимый с полноценными микроконтроллерами. Т.е. проект разрабатываешь на нормальном камне а в серию идут дешевые мк. Quote Share this post Link to post Share on other sites More sharing options...