Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: порт под ADuC702x?
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
a9d
Для сборки использую WinARM.

При сборке вылетает ошибка
Код
OS_Target.h    
OS_INTERRUPT void SystemTimer_ISR();     expected constructor, destructor, or type conversion before 'void'


Код
scmRTOS_defs.h  

#ifndef scmRTOS_CONTEXT_SWITCH_SCHEME
       #error "Error: Config macro scmRTOS_CONTEXT_SWITCH_SCHEME must be defined!"
#endif


Но scmRTOS_CONTEXT_SWITCH_SCHEME ведь определена по дефолту 0.

Как собрать Ос?

Все разобрался. Я с инклудами намутил.
a9d
А каким GCC компилятором собирался порт?

У меня теперь ругается на это:
Код
undefined reference to `_exit'    test_scm2        line 0, external location: exit.c
undefined reference to `_sbrk_r'    test_scm2        line 0, external location: mallocr.c
undefined reference to `ContextRestore'    main.cpp    /test_scm2    line 0
AHTOXA
Это на каком примере так ругается?
a9d
Это ругается на пустом проекте. (WinARM-20060606)

Стандартные примеры не собираются. Там вылетает ошибка

Код
Compiling: ../scmRTOS/Common/OS_Kernel.cpp
Compiling: ../scmRTOS/Common/OS_Services.cpp
Compiling: ../scmRTOS/Common/usrlib.cpp
Compiling: ../scmRTOS/ARM7/OS_Target_cpp.cpp
Compiling: ./Src/main.cpp
Assembling: ../scmRTOS/ARM7/OS_Target_asm.s
Assembling: ./Src/crt.s
Linking: release/1-EventFlag.elf
release/obj/crt.o: In function `ctor_end':
./Src/crt.s:157: undefined reference to `_data_image'
c:/winarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ld.exe: BFD 06060
6 20060606 internal error, aborting at c:/winarms/binutils-060606/bfd/elflink.c
line 6509 in elf_link_output_extsym

c:/winarm/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/ld.exe: Please re
port this bug.

collect2: ld returned 1 exit status
make: *** [release/1-EventFlag.elf] Error 1

AHTOXA
Цитата(a9d @ Sep 13 2010, 11:06) *
(WinARM-20060606)

Староват наверное, компилятор-то.
Возьмите поновее. Или вот этот: Sourcery G++ Lite.
a9d
Поставил Sourcery G++ Lite. Результат стал еще хуже.
Теперь в стандартных примерах ничего не собирается.
Код
Compiling: ../scmRTOS/Common/OS_Kernel.cpp
process_begin: CreateProcess(NULL, arm-elf-gcc -c -mcpu=arm7tdmi -g -gdwarf-2 -M
D -MP -MF release/dep/OS_Kernel.o.d -I../scmRTOS/Common -I../scmRTOS/ARM7 -I./Sr
c -Os -DADUC7020=1 -fomit-frame-pointer -fno-exceptions -fno-rtti -Wall -Wextra
-Wundef -Wcast-align -Wa,-ahlmsdc=release/lst/OS_Kernel.lst -fverbose-asm -ffunc
tion-sections -fdata-sections -Winline -funsigned-bitfields -fshort-enums ../scm
RTOS/Common/OS_Kernel.cpp -o release/obj/OS_Kernel.o, ...) failed.
make (e=2): Не удается найти указанный файл.
make: *** [release/obj/OS_Kernel.o] Error 2



yagarto-bu-2.20.1_gcc-4.5.1-c-c++_nl-1.18.0_gdb-7.1_eabi_20100813 выдает туже самую ошибку, что и Sourcery G++ Lite.
AHTOXA
Дык! Надо же поменять в makefile
Код
TARGET = arm-elf-

на
Код
TARGET = arm-none-eabi-

! Компилер-то иначе называется теперьsmile.gif
a9d
Ура))) Проект собрался. Спасибо.
Капец два дня убил на компиляцию и не заметил эту мелочь.
Сергей Борщ
Цитата(a9d @ Sep 13 2010, 13:29) *
Ура))) Проект собрался.
Но не работает. С переходом на eabi надо в скрипте линкера строчку *(.ctors) заменить на *(.init_array) или просто добавить *(.init_array) перед или после *(.ctors)
a9d
Прошивка ,через бутлоадер, отказывается заливатся. Контроллер ADuC7024.
Вылетает ошибка:
Wrong memory address 0x10000-0x10010
Erase aborted.


В makefile выбрал
LD_SCRIPT= ./Config/ADuC70xx_FLASH.ld
и все завелось.
Но после вызова OS::Run(); управление не передается первому процессу.

Без JTAG туговато. Но с помощью светодиодов определил место где зависает.
Файл OS_Target.h
Код
INLINE inline void OS_Start(TStackItem* sp)
{

    ContextRestore(sp);
}


Не происходит возврат из ContextRestore(sp). Но учитывая атрибут __noreturn__ я могу ошибаться. Скорей всего управление передается какой нибудь функции ОС.
AHTOXA
Цитата(a9d @ Sep 14 2010, 00:42) *
В makefile выбрал
LD_SCRIPT= ./Config/ADuC70xx_FLASH.ld

А вы внесли в ADuC70xx_FLASH.ld изменения, про которые вам сказал Сергей Борщ?

Вот сюда:
Код
        __ctors_start = .;
        *(.ctors)
        __ctors_end = .;

Добавьте после строки *(.ctors)
строку
Код
        KEEP(SORT(*)(.init_array))

a9d
Я немного лохонулся. Строку *(.ctors) я заменил, но чуть ниже была строка KEEP(SORT(*)(.ctors)) которую я не подправил.
После внесения изменений ОС заработала.

Кстати было б неплохо еще в дистрибувах ОС указывать следующую информацию:
- версия компилятора
- MCU на котором работоспособность была испытана
- частота MCU

Нашел небольшую ошибку в примере 1-EventFlag. По умолчанию все входы в контроллерах ADuC702x настроены на вход. Поэтому если не вызвать скрипт DRIVER(LED,OUT);, работать не будет.


Не все так гладко. Когда превышаю размер dec - 3820, бутлоадер сообщает "Error at 0x12c-0x13c. Verify aborted". Код ошибки меняется в зависимости от размера.
a9d
Не знаю, что я сделал но:
Код
    __ctors_start = .;
    *(.ctors)
    *(.init_array)
    KEEP(SORT(*)(.init_array))
     __ctors_end = .;
    
     __dtors_start = .;
     *(.dtors)
     __dtors_end = .;
    KEEP(SORT(*)(.ctors))
    KEEP(SORT(*)(.init_array))
    KEEP(SORT(*)(.dtors))


и все заработало.


Снова поигрался с размером прошивки. На некоторых размерах все та же ошибка вылетает. Со скриптом все таки есть проблема.
a9d
Со скриптом все впорядке. После добавления строк *(.init_array) KEEP(SORT(*)(.init_array)) заработало. Покрайней мере три процесса мигают светодиодами.

Это я жестко облажался. Кабель COM порта долго не использовал и контакты окислились.
AHTOXA
Цитата(a9d @ Sep 14 2010, 21:48) *
три процесса мигают светодиодами.

Поздравляю! smile.gif

2 Сергей Борщ. Почему в скрипте сделано так:
Код
    __ctors_start = .;
    *(.ctors)
    __ctors_end = .;
    KEEP(SORT(*)(.ctors))

? Я обычно пишу:
Код
    __ctors_start = .;
    KEEP(SORT(*)(.ctors))
    __ctors_end = .;

, и всё работает нормально. В чём разница между этими вариантами?
Сергей Борщ
Цитата(AHTOXA @ Sep 14 2010, 20:09) *
Почему в скрипте сделано так:
Потому что скрипт писался на заре освоения GCC. По образу и подобию скриптов WinAVR. Вопрос можно было бы переадресовать им. Я тоже сейчас пишу только строку KEEP(), а портами scmRTOS давно не занимался. Конечно надо найти время и внести в них некоторые улучшения, но пока негде это время найти.
a9d
Делаю под себя шаблон. Возник вопрос.
Зачем нужен Таймер1 и почему TEST_TIMER_RATE=3500 Hz ? Как я понимаю это нужно только для примера( Timer_Ovf.SignalISR(); ) .
Сергей Борщ
Цитата(a9d @ Sep 14 2010, 23:04) *
Как я понимаю это нужно только для примера( Timer_Ovf.SignalISR(); ) .
Да.
a9d
Заметил при использовании channel непонятный момент(в порте под AVR этого не наблюдаю).

У меня есть следующий код

Код
OS::channel<char,200> bufCam;

    template<>
    OS_PROCESS void TProc2::Exec()
    {
        while(1)
        {
            Sleep(100);  //Если слип убрать, то система вешается. Но у этого процесса приоритет ниже. Почему первый
                                                               процесс не может забрать управление??
        }
    }


    template<>
    OS_PROCESS void TProc1::Exec()
    {
        MyUart.setChanel(3);

        char buf;

        while(1)
        {
            MyUart.sendByte(bufCam.get_count());

            Sleep(500);
        }

     }


extern "C" void IRQ_Switch()
{

    char b;

    dword irq = IRQSIG;
    irq &= IRQSTA;
    if(irq & RTOS_TIMER_BIT)
    {
        OS::SystemTimer_ISR();
    }
    else if (irq & UART_BIT)
    {
        b=COMRX;
        bufCam.push(b);
    }

}


Отсылаю разные по длине посылки. Размер их отображается верно.

Вопрос 1: Почему если из TProc2 убрать слип система зависает? У TProc1 приоритет выше и он должен забирать управление в любом случае. Ведь в процессе заглушка нет слипа и система работает.


Меняю код в TProc1

Код
    template<>
    OS_PROCESS void TProc1::Exec()
    {
        MyUart.setChanel(3);

        char buf;

        while(1)
        {
            bufCam.pop(buf);
            MyUart.sendByte(buf);
        }

     }


Если отправляю по одному байту, то отклика нет.
Если отправляю посылку, то возвращается только последний байт. Т.е. отправил "123" вернется "3".

Меня код снова

Код
    template<>
    OS_PROCESS void TProc1::Exec()
    {
        MyUart.setChanel(3);

        char buf;

        while(1)
        {
            bufCam.pop(buf,100);
            MyUart.sendByte(buf);
        }

     }


На выходе вижу равномерно идущие нули. Отправляю один байт, система подвисает и дальше снова начинают идти нули.

Иду дальше

Код
    template<>
    OS_PROCESS void TProc1::Exec()
    {
        MyUart.setChanel(3);

        char buf;

        while(1)
        {
            bufCam.pop(buf,100);
            MyUart.sendByte(bufCam.get_count());
        }

     }


Отправляю посылку. В теории я должен видеть число которое постоянно уменьшается на единицу. В реальности вижу только 0.


Пробовал сделать так

struct TData
{
char a;
};
OS::channel<TData,200> bufCam;

Результат такой же.


ЗЫ:

Так же нужно подредактировать файл pin_macros.h . В нем есть опечатка. Он выглядит так.
Код
#define PM_PINL(port,bit,dummy)     (!(GP##port##DAT & (1 << (bit))))
#define PM_PINH(port,bit,dummy)     (!PM_PINH(port,bit,dummy))


Но должно быть так?
Код
#define PM_PINL(port,bit,dummy)     (!(GP##port##DAT & (1 << (bit))))
#define PM_PINH(port,bit,dummy)     (!PM_PINL(port,bit,dummy))

Иначе не компилится.
Сергей Борщ
QUOTE (a9d @ Mar 8 2011, 00:35) *
У меня есть следующий код
Вы можете выложить сюда архив проекта, чтобы я погонял его под отладчиком?
QUOTE (a9d @ Mar 8 2011, 00:35) *
Так же нужно подредактировать файл pin_macros.h . В нем есть опечатка.
Спасибо. Там еще и в ADUC702x.h попутаны значения _FREE_RUNNING и _PERIODIC для таймеров. Не могу зафиксировать исправление в репозиторий - ствол залочен на время работы над версией 4.00
a9d
Нажмите для просмотра прикрепленного файла
Компилятор "Sourcery G++ Lite"

Емкость канала в 255 объектов актуальна на 8-ми битках. Но в армах этого маловато. У меня пакет полностью не помещается в канал.
Сергей Борщ
Не могу быстро найти свою отладочную платку с ADuC, но на первый взгляд вы забыли завести объект типа OS::TISRW в обработчике прерывания UART. И надо бы перед помещением в канал проверять - есть ли в канале место. Иначе при переполнении канала channel::push() будет пытаться выполнить перепланировку, что для прерывания не имеет смысла:
CODE
    else if (irq & UART_BIT)
    {
        OS::TISRW isrw;
        b=COMRX;
        if(bufCam.get_free_size())
            bufCam.push(b);
    }
Попробуйте, отпишитесь. Если не поможет - буду искать свою платку.
a9d
Результат точно такой же. Проверку на переполнения я не делаю т.к. у меня ее произойти не может.
А если она и произойдет то это уже аварийная ситуация.

TChannel тоже не работает. Симптомы точно такие же.
a9d
Ура заработало))

Цитата
Спасибо. Там еще и в ADUC702x.h попутаны значения _FREE_RUNNING и _PERIODIC для таймеров. Не могу зафиксировать исправление в репозиторий - ствол залочен на время работы над версией 4.00


После этого все заработало.

ЗЫ: Та же процесс 1 стал забирать управление у процесса 2. Даже если во втором процессе нет слипа. Важный бит был.

ЗЗЫ:

Не сработало это
Код
    else if (irq & UART_BIT)
    {
        OS::TISRW isrw;
        b=COMRX;
        if(bufCam.get_free_size())
            bufCam.push(b);
    }


Нормальная настройка таймера сделала задержки такие как они и должны были быть. При проверке использовал старый хекс. Поэтому изменения сразу не заметил.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.