Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: scmRTOS. Порт под AT91SAM7X
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
LessNik
Привет всем.
Решил поиграться с scmRTOS. Скачал порт под арм, но поддержки AT91Sam7x... там не было. Дописал часть сам, но ОС работает как-то не стабильно. Может где-то ошибся...
Может кто-нибудь поделится уже отлаженным портом?
Сергей Борщ
Цитата(LessNik @ Jan 9 2008, 14:23) *
Решил поиграться с scmRTOS. Скачал порт под арм, но поддержки AT91Sam7x... там не было.
А чем SAM7X отличается от SAM7S с точки зрения исходников ОС? Я бегло просматривал документацию на SAM7X, но не нашел там принципиальных отличий, которые могли бы повлиять на работу ОС.
LessNik
Цитата(Сергей Борщ @ Jan 9 2008, 15:45) *
А чем SAM7X отличается от SAM7S с точки зрения исходников ОС? Я бегло просматривал документацию на SAM7X, но не нашел там принципиальных отличий, которые могли бы повлиять на работу ОС.


Принципиальных различий вроде нет, но возникли некоторые проблемы:
1. Вылазила ошибка Memory access timed out @ 00003F00 -> JTAG speed too high при попытке выполнить Reset.
Поправил mac файл, вроде легче стало. Надеюсь тут не ошибся:

Код
_InitRSTC() {
    __writeMemory32(0xA5000001, 0xFFFFFD08,"Memory");    // Allow user reset
}

_InitPLL() {

    __message "Set Main Oscillator";
    __writeMemory32(0x00004001,0xFFFFFc20,"Memory");    // MOSC
    while( !(__readMemory32(0xFFFFFc68,"Memory") & 0x1)  );

    __message "Set PLL to 96MHz";
    __writeMemory32(0x10483f0e,0xFFFFFc2c,"Memory");    // LOCK
    while( !(__readMemory32(0xFFFFFc68,"Memory") & 0x4)  );

    __message "Set Master Clock to 48MHz";
    __writeMemory32(0x00000004,0xFFFFFc30,"Memory");    // MCKRDY
    while( !(__readMemory32(0xFFFFFc68,"Memory") & 0x8)  );
    __writeMemory32(0x00000007,0xFFFFFc30,"Memory");    // MCKRDY
    while( !(__readMemory32(0xFFFFFc68,"Memory") & 0x8)  );
}


execUserPreload()
{
    Reset();
    Remap_RAM();
    __writeMemory32(0xD3,0x98,"Register");                          // CPSR = SVC mode, ARM, IRQ, FIQ disabled
    
   _InitRSTC();    
}

execUserReset()
{
    Reset();
    
    Remap_RAM();

    __writeMemory32(0xD3,0x98,"Register");                          // CPSR = SVC mode, ARM, IRQ, FIQ disabled
    __writeMemory32(0x00000000,0xB4,"Register");
    
__emulatorSpeed(0);                 // Set JTAG speed to full speed
    
}

__var tmp;
Remap_RAM()
{
    tmp = __readMemory32(0x00200000, "Memory");                     // read from RAM area
    __writeMemory32(~tmp, 0x00200000, "Memory");                    // alter RAM area
    if( ~tmp != __readMemory32(0x00000000, "Memory") )              // check if altering mirrored to remap area
    {
        __writeMemory32(0x00000001, 0xFFFFFF00,"Memory");
    }
    __writeMemory32(tmp, 0x00200000 ,"Memory");                     // restore RAM data
    __message " remap ";
}


Reset()
{
    __message "execUserReset()";
    __emulatorSpeed(30000);             // Set JTAG speed to 30kHz to make a hardware reset
    
    __writeMemory32(0xA5000004, 0xFFFFFD00, "Memory");              // reset the peripherals    
    
    _InitPLL();                         // Allow to debug at JTAG Full Speed
    __emulatorSpeed(0);

}


2.
Дописал ещё в device.h
#elif defined(AT91SAM7X256)
#include <ioAT91SAM7X256.h>
и в OS_Target_core.h
| defined(AT91SAM7X256)

Надеюсь ничего больше не забыл, нето ведь всё равно скомпилится -) -(

Сейчас вроде всё работает.
Сергей Борщ
Цитата(LessNik @ Jan 9 2008, 17:36) *
Принципиальных различий вроде нет, но возникли некоторые проблемы:
1. Вылазила ошибка Memory access timed out @ 00003F00 -> JTAG speed too high при попытке выполнить Reset.
Вроде на последних версиях иара с adaptive clocking уже не слетает. Аналогичные вашим действия у меня вроде как делались в Reset(), правда там они были сделаны с проверкой на наличие JLink, если у вас другой отладчик - надо просто выкинуть проверки.
Цитата(LessNik @ Jan 9 2008, 17:36) *
Дописал ещё в device.h
и в OS_Target_core.h
Это тоже уже дописано в той версии, которая лежит в репозитории. Попробуйте ее - там много улучшений, и она же будет включена в ближайший релиз.
LessNik
Цитата
Это тоже уже дописано в той версии, которая лежит в репозитории. Попробуйте ее - там много улучшений, и она же будет включена в ближайший релиз.


Этот репозиторий на ftp электроникса? У меня нет к нему доступа. Может можно ещё откуда-нибудь скачать. Если можно, дайте прямую ссылку.
dxp
Цитата(LessNik @ Jan 10 2008, 11:33) *
Этот репозиторий на ftp электроникса? У меня нет к нему доступа. Может можно ещё откуда-нибудь скачать. Если можно, дайте прямую ссылку.

Нет, имеется в виду репозиторий на sourceforge.net. http://scmrtos.svn.sourceforge.net/viewvc/scmrtos/
LessNik
Цитата(dxp @ Jan 10 2008, 10:07) *
Нет, имеется в виду репозиторий на sourceforge.net. http://scmrtos.svn.sourceforge.net/viewvc/scmrtos/


Спасибо. Скачал. Скомпилил и возникла ошибка.
Дописал в Target_AT91SAM7.h
#define OS_INTERRUPT __arm __irq
и всё скомпилилось, но мой пример перестал работать стабильно(чип почему-то перезагружается).
Сергей Борщ
Цитата(LessNik @ Jan 10 2008, 13:46) *
Спасибо. Скачал. Скомпилил и возникла ошибка.
Дописал в Target_AT91SAM7.h
#define OS_INTERRUPT __arm __irq
и всё скомпилилось, но мой пример перестал работать стабильно(чип почему-то перезагружается).
Насчет #define проверю. По поводу перезагрузки - посмотрите, сколько стека выделяется для scmRTOS_IDLE_PROCESS_STACK_SIZE в файле scmRTOS_config.h Раньше там выделялось только то, что хочет пользователь для своих нужд и "в недрах" к этому числу добавлялось 17 * sizeof(TStackItem). Теперь надо полный размер указывать в scmRTOS_config.h, т.е. минимум 17 * sizeof(TStackItem)


Цитата(LessNik @ Jan 10 2008, 13:46) *
Дописал в Target_AT91SAM7.h
#define OS_INTERRUPT __arm __irq
Но оно там есть, в самом начале:
Код
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
    #define OS_INTERRUPT __arm
#else
    #define OS_INTERRUPT __arm __irq
#endif
LessNik
Цитата(Сергей Борщ @ Jan 10 2008, 15:36) *
Насчет #define проверю. По поводу перезагрузки - посмотрите, сколько стека выделяется для scmRTOS_IDLE_PROCESS_STACK_SIZE в файле scmRTOS_config.h Раньше там выделялось только то, что хочет пользователь для своих нужд и "в недрах" к этому числу добавлялось 17 * sizeof(TStackItem). Теперь надо полный размер указывать в scmRTOS_config.h, т.е. минимум 17 * sizeof(TStackItem)
Но оно там есть, в самом начале:
Код
#if scmRTOS_CONTEXT_SWITCH_SCHEME == 0
    #define OS_INTERRUPT __arm
#else
    #define OS_INTERRUPT __arm __irq
#endif


Да, действительно есть, я просто файл не скопировал (svn воспользовать не получается, перекрыта на работе).Скачивал файлы в ручную по приведенной dxp ссылке

Сейчас гоняю приведенный пример 1-EventFlag. Там же не нужно ничего исправлять, кроме пина и порта светодиода?
Поведение такое же. Чип перезагружается. Может я что-то недозаменил снова, но что-то сомневаюсь.


Для этого примера
#define scmRTOS_IDLE_PROCESS_STACK_SIZE 17 * sizeof(TStackItem)

Мой пример (всего 1 процесс, ожидающий событие Timer_Ovf ( Timer_Ovf.Wait(); ) и раз в секунду в прерывании от ТС0 сигнализируется событие ( Timer_Ovf.SignalISR(); ) ) отваливался после команды
Timer_Ovf.SignalISR(), выполнив ещё что-то. Т.е.:
Код
..........
  if (TimerCounter0)
  {
      TimerCounter0--;
      if (!TimerCounter0)
      {
         TimerCounter0=50000;
         Timer_Ovf.SignalISR();  // доходит до этой строчки, затем доходит до строки " выход из
//  прерывания" и где-то там чип перегружается. Если события не происходит, то всё работает.
      }
  }
    AT91C_BASE_AIC->AIC_EOICR = 0;

} // выход из прерывания.


Что удивительно, примеры с предыдущими исходниками ОС работают стабильно. laughing.gif
Сергей Борщ
Цитата(LessNik @ Jan 11 2008, 12:03) *
Что удивительно, примеры с предыдущими исходниками ОС работают стабильно. laughing.gif
Буду копать. Я примеры из последней правки проверял, вроде все работали. Попробую еще раз скачать все из репа "на чистый лист". Я писал себе файлик с изменениями, которые вносились в процессе правки, но он, к сожалению, дома. Постараюсь вечерком его найти и запостить сюда. Могу выслать почтой выкачанные из репа примеры.

P.S. Проверил первый пример - слил из репа, скомпилил, залил - работает и из ОЗУ и из флеша. Тестировал на SAM7S64.
LessNik
Цитата(Сергей Борщ @ Jan 11 2008, 14:20) *
Буду копать. Я примеры из последней правки проверял, вроде все работали. Попробую еще раз скачать все из репа "на чистый лист". Я писал себе файлик с изменениями, которые вносились в процессе правки, но он, к сожалению, дома. Постараюсь вечерком его найти и запостить сюда. Могу выслать почтой выкачанные из репа примеры.

P.S. Проверил первый пример - слил из репа, скомпилил, залил - работает и из ОЗУ и из флеша. Тестировал на SAM7S64.


a14.gif

Ну вот теперь совсем другое дело! Работает! biggrin.gif

Спасибо. Буду дальше разбираться

P.S. Видимо нето прикручивал laughing.gif
Waso
Пересаживаюсь с FreeRTOS на scmRTOS. Проц AT91SAM7X256. Поправил код программы, скомпилил. При загрузке J-link выдал такой перл:
Код
Loaded macro file: \scm\config\AT91SAM7_FLASH.mac
JTAG speed is set to: 32 kHz
Write memory error @ address 0xFFFFFC20, word access: Core error.
Error in \scm\config\AT91SAM7_FLASH.mac at line 53, col 20: Operation error.
Error while calling macro execUserPreload.
Failed to load debugee: \scm\Exe\slon.d79
Подставил загрузочный макрос (.mac - файл) от фри - заработало. В этих макросах я пока не разобрался, такчто в чем конкретно проблема сказать не могу, но она есть.

И еще. Как подсчитать необходимый размер стека для процесса? Вроде это суммарный размер всех процовых регистров плюс какоето число байт на каждый уровень вложенности функций? От кол-ва используемых ОЗУ-шных переменных зависеть не должно... Или как? Почему спрашиваю - пока не увеличил размер стека для одного из процессов - прога частенько выскакивала на Data Abort Vector. Теперь работает. Покачто. Хочется быть уверенным что она не слетит.

И еще один глюк проявился - перестает срабатывать прерывание. Прерывание от EMAC. Других и нет.
На всякий случай приложил исходник.
Вообще прога занимается выбросом в порт данных, принятых через изернет.
Сергей Борщ
Цитата(Waso @ Jun 18 2008, 11:41) *
Код
Loaded macro file: \scm\config Write memory error @ address 0xFFFFFC20, word access: Core error.
Ошибка в отладчике? По этому адресу находится CKGR_MOR, который 32-битный и 32 бита в него и пишутся. Или он таким образом сообщает о какой-то другой ошибке, например, с вашим кварцем и указанными в .mac парамертами pll получается слишком высокая частота и ядро сбоит. Проверьте строчку
Код
                                                                    // Assuming 18.432 MHz osc
    __writeMemory32(0x00190605, 0xFFFFFC2C,"Memory");               // *26/5 set LOCK after 6 SCLK
Хотя она находится уже после строки, в которой возникает ошибка. Можете попробовать закомментировать проблемную строку.
Цитата(Waso @ Jun 18 2008, 11:41) *
И еще. Как подсчитать необходимый размер стека для процесса? Вроде это суммарный размер всех процовых регистров плюс какоето число байт на каждый уровень вложенности функций?
Да. Контекст занимает 17 слов, ну и сколько еще компилятор использует. Проще всего остановить программу и посмотреть содержимое стека отладчиком.
Waso
C макросом я пока париться не стал.
А со стеком вот что прикрутил:
Код
        template<TPriority pr, word stack_size>
        class process : public TBaseProcess
        {
        public:
            INLINE process() : TBaseProcess(&Stack[stack_size/sizeof(TStackItem)], pr, (void (*)())Exec) { }
            OS_PROCESS static void Exec();
dword Used_Stack_Size() {return (dword)(StackPointer - Stack);};
Код
        private:
            TStackItem Stack[stack_size/sizeof(TStackItem)];
        };
Потом в IdleProcessUserHook() использовал:
Код
    debug_printf("EMAC stack %d  ",DataShower_Proc.Used_Stack_Size());
    debug_printf("DBG stack %d  ",DBG_Output_Proc.Used_Stack_Size());
Как я понимаю, когда выполняется идл-процесс, окружение остальных процессов находится в их стеках и это какраз подходящее время чтобы узнать использованный размер. Поправте если не прав. А вообсче работает. yeah.gif
Как насчет прикрутить нечто подобное в исходник? smile.gif

И еще одно пожелание - ИМХО, удобнее задавать (дефайнить) тип используемого процессора прямо в файле device.h. Или вынести в конфиг.аш А лазить по настройкам проекта для этого - ИМХО неудобно.
Сергей Борщ
Цитата(Waso @ Jun 19 2008, 10:31) *
Как я понимаю, когда выполняется идл-процесс, окружение остальных процессов находится в их стеках и это какраз подходящее время чтобы узнать использованный размер. Поправте если не прав. А вообсче работает.
Да. Но если между переключениями контекста процесс разместил на стеке локальную переменную (пусть будет массив smile.gif ) и успел ее уничтожить до следующего переключения, то занимаемая этой переменной память учтена не будет. Один из возможных вариантов отлова такой ситуации - просматривать стек от вершины и искать первое ненулевое слово. Или в конструкторе процесса заполнить стек какой-то константой и искать первое слово, не равное этой константе.
Цитата(Waso @ Jun 19 2008, 10:31) *
И еще одно пожелание - ИМХО, удобнее задавать (дефайнить) тип используемого процессора прямо в файле device.h. Или вынести в конфиг.аш А лазить по настройкам проекта для этого - ИМХО неудобно.
Есть такое. Вот в EWAVR сделано грамотно - выбор типа процессора в настройках проекта заставляет оболочку подставлять соответствующий символ в командную строку компилятора и ассемблера и по этому символу подставляется нужный ioXXX.h в io.h. Здесь было реализовано то же самое, но вручную. При сборке с помощью make или scons это не представляет проблемы. Локализовать это определение в одно место вместо двух (ассемблер, компилятор) - мысль неплохая, надо ее подумать.
Waso
Скажите, а у вас стек ниспадающий чтоле? 0_о Заполнил константой - смотрю - он от начала ею заполнен и только в конце появляются какието данные. Почему так решили сделать?
Цитата
Локализовать это определение в одно место вместо двух (ассемблер, компилятор)
Там получается не два места, а по два на каждую конфигурацию (RAM, Flash и тп)...
Сергей Борщ
Цитата(Waso @ Jun 20 2008, 11:28) *
Скажите, а у вас стек ниспадающий чтоле?
??? Это не у нас, это в архитектуре ARM так сделано. См. описание команд push и pop в THUMB режиме.
Waso
Ясно. Незнал, простите. Вобщем теперь реализация такая:
Цитата("OS_Target_cpp.cpp")
TBaseProcess::TBaseProcess(TStackItem* Stack, word Stack_Size, TPriority pr, void (*exec)())
: StackPointer(Stack), StackSize(Stack_Size), Priority(pr) , Timeout(0)
{
Kernel.RegisterProcess(this);

#ifdef DEDUG_STACK
//---------------------------------------------------------------
// Fill Stack area with some value to be able later to define stack usage
for (StackPointer-=(StackSize/sizeof(TStackItem)); StackPointer < Stack; *(StackPointer++) = STACK_FILL_CONST);
#endif //DEBUG_STACK

//---------------------------------------------------------------
// Prepare Process Stack Frame

*(--StackPointer) = (dword)exec; // return from interrupt address

StackPointer -= 14; // emulate "push R0-R12, LR"
#if __CPU_MODE__ == 1
*(--StackPointer) = 0x003F; // SR value: system mode, FIQ & IRQ enabled, THUMB
#else
*(--StackPointer) = 0x001F; // SR value: system mode, FIQ & IRQ enabled, ARM
#endif
}
Цитата("OS_Kernel.h")
template<TPriority pr, word stack_size>
class process : public TBaseProcess
{
public:
INLINE process():TBaseProcess(&Stack[stack_size/sizeof(TStackItem)], stack_size, pr, (void (*)())Exec){}
#ifdef DEDUG_STACK
word Used_Stack_Size();
#endif //DEDUG_STACK

OS_PROCESS static void Exec();

private:
TStackItem Stack[stack_size/sizeof(TStackItem)];
};

template<TPriority pr, word stack_size>
word process<pr,stack_size>::Used_Stack_Size()
{
TStackItem* Idx = Stack;
while(*(Idx++) == STACK_FILL_CONST);
return ((Stack + (StackSize/sizeof(TStackItem))) - Idx)*sizeof(TStackItem);
}
Цитата("commdefs.h")
#define STACK_FILL_CONST 0xFFF7FFFF
#define DEDUG_STACK
ну и добавлена константа const word StackSize; в описание класса TBaseProcess.
Из корыстно-альтруистических соображений хочу попросить включить это или нечто подобное в последующие версии, чтоп самому не править после каждого обновления, да и людям, уверен, пригодится. rolleyes.gif

Выражаю благодарность авторам за сей продукт. Действительно легкая и красивая операционка!
Waso
После ручного сброса или сьема/подачи питания перестает работать шедулер. Циклится здесь:
Код
        do
         {
             EnableContextSwitch();
             DUMMY_INSTR();
             DisableContextSwitch();
         }
         while(!IsContextSwitchDone());
Как исправить?
Сергей Борщ
Цитата(Waso @ Jun 23 2008, 11:43) *
После ручного сброса или сьема/подачи питания перестает работать шедулер.
И после передергивания питания тоже? Обычно прерывания перестают вызываться после сброса в отладчике - поскольку сброс в отладчике сбрасывает только ядро но не контроллер прерываний. В .mac сделан сброс всей периферии. Если вы используете другой .mac - то вполне возможно, что контроллер прерываний не сбрасывается.


Цитата(Waso @ Jun 23 2008, 11:43) *
После ручного сброса или сьема/подачи питания перестает работать шедулер.
И после передергивания питания тоже? Обычно прерывания перестают вызываться после сброса в отладчике - поскольку сброс в отладчике сбрасывает только ядро но не контроллер прерываний. В .mac сделан сброс всей периферии. Если вы используете другой .mac - то вполне возможно, что контроллер прерываний не сбрасывается.
Waso
Дописал в инициализацию
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SYS);
Все ок.
Сергей Борщ
Цитата(Waso @ Jun 23 2008, 14:14) *
Дописал в инициализацию
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SYS);
Все ок.
Хм.
SAM7S, SAM7SE:
Цитата
Note: 1. Setting SYSIRQ and ADC bits in the clock set/clear registers of the PMC has no effect. The System Controller is continuously clocked. The ADC clock is automatically started for the first conversion. In Sleep Mode the ADC clock is automatically stopped after each conversion.
SAM7X:
Цитата
Note: 1. Setting SYSC and ADC bits in the clock set/clear registers of the PMC has no effect. The System Controller and ADC are continuously clocked.
В описании PMC_PCER бит (1 << AT91C_ID_SYS) также отсутствует. Значит дело было в чем-то другом. Ищите. "Призовая игра!" wink.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.