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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Порт Cortex-R4, Попытка реализации
Legath
сообщение Jan 19 2017, 15:22
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 30-12-10
Из: Рязань
Пользователь №: 61 958



Всем доброго дня.
Пытаюсь сделать порт для Cortex R4F (чип RM46L852). Компилятор gcc 5.4.1.

Использую схему с программным прерыванием. Но возникает проблема в реализации функции os_start
По примеру порта ARM7
сделал ассемблерный файл со следующий содержимым (подсматривал в других ОСРВ)

Код
        .set SYS_MODE,    0x1f
        .set SVC_MODE,    0x13
        .set IRQ_MODE,    0x12
        .set STUB,    0x00


        .global context_restore

context_restore:     // os_start() passes New_SP in R0
    CPS        #SYS_MODE
    LDR        R1, [R0]
    LDR        SP, [R1]



    /* Restore the floating point context, if any. */
    POPNE     {R0}
    VPOPNE    {D0-D15}
    VMSRNE  FPSCR, R0


    /* Restore all system mode registers other than the SP (which is already
    being used). */
    POP        {R0-R12, R14}

    /* Return to the task code, loading CPSR on the way. */
    RFEIA    sp!


в отладчике штатно дохожу до строки
Код
LDR        R1, [R0]

и при ее выполнении процессор улетает в dabort handler. Это означает что инструкция обратилась к данным с которыми проблема.
Подскажите пожалуйста в какую сторону начать поиски. у меня подозрение что я что то неверно делаю с заготовкой стека.


Код
void TBaseProcess::init_stack_frame( stack_item_t * Stack
                                   , void (*exec)()
                                #if scmRTOS_DEBUG_ENABLE == 1
                                   , stack_item_t * StackBegin
                                #endif
                                   )
{
        *Stack = ( stack_item_t ) NULL;
        Stack--;
        *Stack = ( stack_item_t ) NULL;
        Stack--;
        *Stack = ( stack_item_t ) NULL;
        Stack--;
        *Stack = ( stack_item_t ) 0x1f;;

        if((uintptr_t)exec & (0x01UL))  {
               *Stack = *Stack | 0x20;
           }
        Stack--;
        *Stack = reinterpret_cast<stack_item_t>(exec);;
        Stack--;
        *Stack = ( stack_item_t ) 0;    /* R14 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R12 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R11 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R10 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R9 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R8 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R7 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R6 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R5 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R4 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R3 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R2 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R1 */
        Stack--;
        *Stack = ( stack_item_t ) 0; /* R0 */
        Stack--;
        *Stack = ( uint32_t ) 0;
        Stack--;
        *Stack = ( stack_item_t ) 0;

}


Это точно не MPU, я его отключал.


ADD:

в этот момент в R0 содержится значение 0xea006068 , память по этому адресу просмотреть нельзя.

Прошу сильно не пинать. Процессор для меня новый.

Сообщение отредактировал Legath - Jan 19 2017, 16:32
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 20 2017, 06:18
Сообщение #2


Гуру
******

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



QUOTE (Legath @ Jan 19 2017, 17:22) *
Пытаюсь сделать порт для Cortex R4F (чип RM46L852). Компилятор gcc 5.4.1.
Там есть общий порт для Mx (x=0, 3, 4) под gcc, его нельзя доработать? И добавить ваш процессор в него... Или они настолько радикально разные? Я просто с Rx не сталкивался никогда.

CODE
        *Stack = ( stack_item_t ) NULL;
        Stack--;
        *Stack = ( stack_item_t ) NULL;
        Stack--;
        *Stack = ( stack_item_t ) NULL;
        Stack--;
        *Stack = ( stack_item_t ) 0x1f;;

        if((uintptr_t)exec & (0x01UL))  {
               *Stack = *Stack | 0x20;
           }
        Stack--;
        *Stack = reinterpret_cast<stack_item_t>(exec);;
А можно ссылку на доку, в которой описан порядок сохранения регистров на стек у R4F? Понятно PSR, адрес возврата, а что это за три нуля над ними? Комментариев в этих строках явно не хватает.
QUOTE (Legath @ Jan 19 2017, 17:22) *
в этот момент в R0 содержится значение 0xea006068 , память по этому адресу просмотреть нельзя.
Надо искать, откуда это значение туда попадает. Там должен быть указатель на стековый кадр самого приоритетного процесса.


--------------------
На любой вопрос даю любой ответ
"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
Legath
сообщение Jan 20 2017, 08:49
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 30-12-10
Из: Рязань
Пользователь №: 61 958



Цитата(Сергей Борщ @ Jan 20 2017, 09:18) *
Там есть общий порт для Mx (x=0, 3, 4) под gcc, его нельзя доработать? И добавить ваш процессор в него... Или они настолько радикально разные? Я просто с Rx не сталкивался никогда.


cortex r ближе к arm7 чем к cortex-m. у R нет global interrupt controller, и ассемблер отличается.
Цитата(Сергей Борщ @ Jan 20 2017, 09:18) *
Надо искать, откуда это значение туда попадает. Там должен быть указатель на стековый кадр самого приоритетного процесса.


я это понимаю и, по идее, Kernel.ProcessTable должна в кострукторе заполняться.

меня еще скрипт линковки смущает
Код
  VECTORS(rx)     : ORIGIN = 0x00000000, LENGTH = 0x00000020
  FLASH  (rx)     : ORIGIN = 0x00000020, LENGTH = 0x0013FFE0
  CPU_STACK (rw)  : ORIGIN = 0x08000000, LENGTH = 0x00001500 /* Stack is configured in sys_core.asm */
  RAM (xrw)       : ORIGIN = 0x08001500, LENGTH = 0x0002EB00
  MEMORY_B1 (rx)  : ORIGIN = 0x60000000, LENGTH = 0K

CPU_STACK отдельно идет


Сообщение отредактировал Legath - Jan 20 2017, 08:54
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 20 2017, 09:21
Сообщение #4


Гуру
******

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



QUOTE (Legath @ Jan 20 2017, 10:49) *
cortex r ближе к arm7 чем к cortex-m. у R нет global interrupt controller, и ассемблер отличается.
Понятно. Тогда да, отдельный порт.

QUOTE (Legath @ Jan 20 2017, 10:49) *
я это понимаю и, по идее, Kernel.ProcessTable должна в кострукторе заполняться.
А конструкторы глобальных объектов вообще вызываются? У множества распроняемого в интернете и в "библиотеках" начального кода запуск конструкторов просто не реализован.

QUOTE (Legath @ Jan 20 2017, 10:49) *
меня еще скрипт линковки смущает
Смущает, что стек в отдельной области (region)? А что говорит описание про эту область? Это случайно не аналог Core-coupled memory в M4? тогда размещать в ней стек было бы логично. А в нашем случае логично будет разместить в ней объекты самых высокоприоритетных процессов (сколько влезет), их стеки окажутся в этой же области. Надо завести секцию в этой области и дальше в исходнике помещать в нее объекты:
CODE
__attribute__((section(".ccm_mem")))
proc1_type Proc1("Highest priority proc");
Но это уже косметика, для начала надо запустить все остальное.

Перечитал еще раз. Кажется понял - область одна, но в скрипте автор зачем-то окусил от нее кусок для стека. Ему виднее, зачем он так сделал. Ваш процессор переключает аппаратно стек при входе в прерывания?


--------------------
На любой вопрос даю любой ответ
"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
Legath
сообщение Jan 20 2017, 11:30
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 30-12-10
Из: Рязань
Пользователь №: 61 958



Цитата(Сергей Борщ @ Jan 20 2017, 12:21) *
Кажется понял - область одна, но в скрипте автор зачем-то окусил от нее кусок для стека. Ему виднее, зачем он так сделал.


Это дефолтный скрипт из HalCoGen (аналог CubeMX для процессоров TI). Я просто не нашел другого способа получить инициализацию. Но теперь более менее понятно что можно вернуть область RAM в единую.
Порт Free RTOS от TI еще больше ее дробит. Там ядро (шедулер? ) лежит в своем сегменте

Код
KRAM (xrw)      : ORIGIN = 0x08000800, LENGTH = 0x00000800


Цитата(Сергей Борщ @ Jan 20 2017, 12:21) *
А конструкторы глобальных объектов вообще вызываются? У множества распроняемого в интернете и в "библиотеках" начального кода запуск конструкторов просто не реализован.


Подозреваю что не вызываются. S/W BP ниразу не сработал внутри TKernel::register_process.


Цитата(Сергей Борщ @ Jan 20 2017, 12:21) *
Ваш процессор переключает аппаратно стек при входе в прерывания?


Чтобы ответить на этот вопрос мне не хватает знаний на данный момент . В документации я нашел

Software normally uses register R13 as a Stack Pointer (SP). The SRS and RFE instructions use Register R13


И для каждого из режимов процессора R13 имеет свой суффикс(в вашем порте arm7 я видел подобное)

Ссылаюсь на документацию от ARM


тестовый код main.cpp
Код
#include "sys_common.h"
#include "gio.h"

#include <scmRTOS.h>


typedef OS::process<OS::pr0, 300> TProc0;
typedef OS::process<OS::pr1, 300> TProc1;

TProc0 Proc0;
TProc1 Proc1;

int main(void)
{
    OS::run();
    while(1){

    }
    return 0;
}


namespace OS
{
    template <>
    OS_PROCESS void TProc0::exec()
    {
        for(;;)
        {   for (int i=0;i<10;i++)
            {

            }
            sleep(10);
        }
    }

    template <>
    OS_PROCESS void TProc1::exec()
    {
        for(;;)
        {
            for (int i=0;i<10;i++)
            {

            }
            sleep(10);

        }
    }
}




Сообщение отредактировал Legath - Jan 20 2017, 11:39
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 20 2017, 11:45
Сообщение #6


Гуру
******

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



QUOTE (Legath @ Jan 20 2017, 13:30) *
Подозреваю что не вызываются. S/W BP ниразу не сработал внутри TKernel::register_process.
Тогда в коде инициализации после обнуления .bss и копирования .data надо надо добавить что-нибудь вроде
CODE
    /* Call constructors */
    void(* const *ctor)();
    for( ctor = __ctors_start; ctor < __ctors_end; )
        (*ctor++)();
Или гляньте у Антона в примерах к кортексам - там у него более современно, с использованием init_array сделано.
QUOTE (Legath @ Jan 20 2017, 13:30) *
И для каждого из режимов процессора R13 имеет свой суффикс
А, ну значит для прерываний отдельный стек. Я использовал под него тот же стек, который работет до запуска ОС.


--------------------
На любой вопрос даю любой ответ
"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
Legath
сообщение Jan 20 2017, 16:55
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 30-12-10
Из: Рязань
Пользователь №: 61 958



Добавил в линковку
Код
  /* The program code and other data goes into RAM */
  .text :
  {

        __ctors_start = .;
        KEEP(SORT(*)(.init_array))  /* eabi uses .init_array for static constructor lists */
        __ctors_end = .;

        __dtors_start = .;
        __dtors_end = .;

    . = ALIGN(4);
    *(.text)           /* .text sections (code) */
    *(.text*)          /* .text* sections (code) */
    *(.glue_7)         /* glue arm to thumb code */
    *(.glue_7t)        /* glue thumb to arm code */
    *(.eh_frame)

    KEEP (*(.init))
    KEEP (*(.fini))

    . = ALIGN(4);
    _etext = .;        /* define a global symbols at end of code */
  } >FLASH



и перед вызовом main в аналоге reset handler
Код
        extern uint32 __ctors_start, __ctors_end;
    void(* const *ctor)();
    for( ctor = __ctors_start; ctor < __ctors_end; )
            (*ctor++)();


Все равно очень далеко указывает R0 указывает. Видимо я еще что то не учел.

Сообщение отредактировал Legath - Jan 20 2017, 16:56
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 20 2017, 18:24
Сообщение #8


Гуру
******

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



QUOTE (Legath @ Jan 20 2017, 13:30) *
тестовый код main.cpp
for(;;) в main() не нужен - OS::run() - это путь в один конец, возврата из нее нет. for (int i=0;i<10;i++) в процессах тоже лишнее - любой вменяемый компилятор этот цикл выкинет при самой минимальной оптимизации.
QUOTE (Legath @ Jan 20 2017, 18:55) *
Все равно очень далеко указывает R0 указывает. Видимо я еще что то не учел.

Так и есть. Чудес ведь не бывает wink.gif



--------------------
На любой вопрос даю любой ответ
"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
AHTOXA
сообщение Jan 20 2017, 18:56
Сообщение #9


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

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



Цитата(Legath @ Jan 20 2017, 21:55) *
и перед вызовом main в аналоге reset handler
Код
        extern uint32 __ctors_start, __ctors_end;
    void(* const *ctor)();
    for( ctor = __ctors_start; ctor < __ctors_end; )
            (*ctor++)();

По-моему, здесь надо писать &__ctors_start и &__ctors_end.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 20 2017, 20:42
Сообщение #10


Гуру
******

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



да, точно. У меня-то они объявлены как
CODE
extern void(* const __ctors_start__[])();
extern void(* const __ctors_end__[])();
странно, что компилятор не выругался на несоответсвие типов.


--------------------
На любой вопрос даю любой ответ
"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
Legath
сообщение Jan 20 2017, 20:55
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 30-12-10
Из: Рязань
Пользователь №: 61 958



Цитата(Сергей Борщ @ Jan 20 2017, 21:24) *
for(;;) в main() не нужен - OS::run() - это путь в один конец, возврата из нее нет.


Это понятно. Я б не стал пытаться делать порт без базовых знаний bb-offtopic.gif
Цитата(Сергей Борщ @ Jan 20 2017, 21:24) *
for (int i=0;i<10;i++) в процессах тоже лишнее - любой вменяемый компилятор этот цикл выкинет при самой минимальной оптимизации.


-O0 , gcc 5.4.1 оставляет если верить дизассемблеру

Цитата(Сергей Борщ @ Jan 20 2017, 23:42) *
да, точно. У меня-то они объявлены как
Код
extern void(* const __ctors_start__[])();
extern void(* const __ctors_end__[])();
странно, что компилятор не выругался на несоответсвие типов.


Действительно не ругается. Странно что ругается на редекларацию регионов памяти.
Код
/Users/legath/Downloads/gcc-arm-none-eabi-5_4-2016q2/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld:/Users/legath/rm46_temp/source/sys_link.ld:19: warning: redeclaration of memory region `VECTORS'
/Users/legath/Downloads/gcc-arm-none-eabi-5_4-2016q2/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld:/Users/legath/rm46_temp/source/sys_link.ld:20: warning: redeclaration of memory region `FLASH'
/Users/legath/Downloads/gcc-arm-none-eabi-5_4-2016q2/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld:/Users/legath/rm46_temp/source/sys_link.ld:22: warning: redeclaration of memory region `RAM'
/Users/legath/Downloads/gcc-arm-none-eabi-5_4-2016q2/bin/../lib/gcc/arm-none-eabi/5.4.1/../../../../arm-none-eabi/bin/ld:/Users/legath/rm46_temp/source/sys_link.ld:23: warning: redeclaration of memory region `MEMORY_B1'


CPU_STACK я убрал и память одним куском оставил

Сообщение отредактировал Legath - Jan 20 2017, 20:58
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 20 2017, 21:37
Сообщение #12


Гуру
******

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



QUOTE (Legath @ Jan 20 2017, 22:55) *
-O0 , gcc 5.4.1 оставляет если верить дизассемблеру
Ой. Это как раз и есть "без всякой оптимизации. Зачем? Впрочем, это ваше дело.
QUOTE (Legath @ Jan 20 2017, 22:55) *
Действительно не ругается. Странно что ругается на редекларацию регионов памяти.
Выложите весь проект в архиве, попробуем разобраться вместе.


--------------------
На любой вопрос даю любой ответ
"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
Legath
сообщение Jan 20 2017, 21:44
Сообщение #13


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 30-12-10
Из: Рязань
Пользователь №: 61 958



Файлы ccs7 архивировал. код инициализации я вставлял в source/sys_startup.c
Вообще хочется самому разобраться, чтоб понимать до конца как все работает. Поэтому прямо мне решение не сообщайте

Сообщение отредактировал Legath - Jan 20 2017, 21:49
Прикрепленные файлы
Прикрепленный файл  scm_r4.tar.gz ( 278.07 килобайт ) Кол-во скачиваний: 20
 
Go to the top of the page
 
+Quote Post
dxp
сообщение Jan 22 2017, 08:08
Сообщение #14


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (Legath @ Jan 20 2017, 23:55) *
и перед вызовом main в аналоге reset handler
CODE
        extern uint32 __ctors_start, __ctors_end;
    void(* const *ctor)();
    for( ctor = __ctors_start; ctor < __ctors_end; )
            (*ctor++)();


Все равно очень далеко указывает R0 указывает. Видимо я еще что то не учел.

В gcc'шной библиотеке есть специальная функция для прогона ctor loop: ___libc_init_array.

Вообще, стартап к кортексов может быть очень простым.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Legath
сообщение Jan 22 2017, 22:29
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 37
Регистрация: 30-12-10
Из: Рязань
Пользователь №: 61 958



Цитата(dxp @ Jan 22 2017, 11:08) *
В gcc'шной библиотеке есть специальная функция для прогона ctor loop: ___libc_init_array.

Вообще, стартап к кортексов может быть очень простым.


Да там это все safety проверки. На данном этапе проекта если их все закомментировать ничего не изменится. Попробую ___libc_init_array ибо ни один из бряков в конструкторах не сработал снова.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 16th April 2024 - 12:53
Рейтинг@Mail.ru


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