Jump to content

    
Sign in to follow this  
ashr

scmRTOS + CortexM3 + printf

Recommended Posts

Э, нет, Антоха, так просто не получится - посмотри на другие два процесса - они тоже печатью занимаются :)

Точно? С printf? С плавучкой (я про это не говорил, но это важно)?

Share this post


Link to post
Share on other sites
Точно? С printf? С плавучкой (я про это не говорил, но это важно)?

Да, с vsnprintf(), без плавучки.

 

Считаешь, что именно плавучка вызывает сбой?

Share this post


Link to post
Share on other sites

Да, плавучка. Я не помню, где я про это читал, помню только, что именно плавучка особенно требовательна к выравниванию стека.

Собственно, благодаря этому смутному воспоминанию мы и нашли решение:)

ЗЫ. Попробуй, это ж несложно:)

Share this post


Link to post
Share on other sites

Я тоже наступил на эти шикарные грабли. :biggrin:

Недавно добавил в свой printf поддержку 64-битных целых (signed/unsigned long long которые). Проверил, отладил - все работает. И даже пару месяцев нормально поработало. А потом - хрясь, и все, мусор вместо 64-битных лезть начал. И не сразу докопался я, что va_arg(list, long long) неверно из стека 64-битные вынимает. Добавил выравнивание стека в порт RTOS (TNKernel, не SCM, но это неважно) при инициализации задачи - и все снова работает. Да, грабли просто шикарные, и бьют больно.

 

Share this post


Link to post
Share on other sites

Принимаю эстафету в беге по граблям.

 

Не могу найти причину hardfault'а в ScmRTOS после вызова sprintf. В hardfault падает из ContextRestore, на инструкции bx lr c 0xfffffffd в lr.

 

ScmRTOS 3.10, arm-kgp-eabi-x86_32-20111129 (с yagarto аналогично).

 

Оч. расчитываю на вашу помощь.

Share this post


Link to post
Share on other sites
В hardfault падает из ContextRestore, на инструкции bx lr c 0xfffffffd в lr.
По симптомам очень похоже на порчу сохраненного на стеке контекста процесса. Хватает ли стека тому процессу, который вызывает sprintf? Хватает ли буфера, в который пишет sprintf?

Share this post


Link to post
Share on other sites

РРРР!) Прошу прощения за поднятие старой темы... Может быть какой-нить дефайн добавим в OS_Kernel.h? Чтобы при компиляции оси под армы (под ARM7TDMI точно) стек задач выравнивался на 8. А то я уж чуть не поседел, когда несколько дней думал, почему vsprintf не печатает плавучку... Выравнивание на 8 рулит!!!

 

З.Ы. У меня 4-я версия, там еще ничего не выравнивается(

Share this post


Link to post
Share on other sites
З.Ы. У меня 4-я версия, там еще ничего не выравнивается(

Как это не выравнивается? Может быть, вы имели в виду 3-ю версию? Так и там исправлено (по крайней мере в 3.11/GCC - точно).

Вот же (tags/3.11/CortexM3/GCC/scmRTOS/CortexM3/OS_Target_cpp.cpp):

TBaseProcess::TBaseProcess(TStackItem* Stack, TPriority pr, void (*exec)())

: StackPointer((TStackItem*)((unsigned int)Stack & 0xFFFFFFF8))

Если у вас IAR, то поправьте по аналогии.

Share this post


Link to post
Share on other sites

Я имел в виду под ARM7TDMI... Принтф у меня не работала, пока я не закомментировал то, что было, и не добавил то, что ниже комментария... Версия 4.00

        class process : public TBaseProcess
        {
        public:
            INLINE_PROCESS_CTOR process();

            OS_PROCESS static void exec();
            
        #if scmRTOS_PROCESS_RESTART_ENABLE == 1
            INLINE void terminate();
        #endif
            

        private:
            //stack_item_t Stack[stack_size/sizeof(stack_item_t)];
            __attribute__ ((aligned (8))) stack_item_t Stack[stack_size/sizeof(stack_item_t)];

Share this post


Link to post
Share on other sites
Я имел в виду под ARM7TDMI...

А тема про CortexM3 :)

Тут такое дело. Дефайн не поможет в общем случае. Потому что выравнивать нужно не начальную вершину стека, а его вершину после сохранения начального контекста. У ARM7 и у Cortex-M3 контекст 16 слов, поэтому можно выравнивать и так и так. А вот с Cortex-M4F такой фокус уже не прокатит, там 17 слов. Поэтому выравнивать надо не централизованно, а в порте. Лучше - так, как я сделал в порте для Cortex-M4F.

Принтф у меня не работала, пока я не закомментировал то, что было, и не добавил то, что ниже комментария...

Не, так точно не надо. Надо как-то вот так (в OS_Target_cpp.cpp):

void TBaseProcess::init_stack_frame( stack_item_t * Stack
                                   , void (*exec)()
                                #if scmRTOS_DEBUG_ENABLE == 1
                                   , stack_item_t * StackBegin
                                #endif
                                   )
{
    StackPointer = (stack_item_t*)((uintptr_t)Stack & 0xFFFFFFF8);
    *(--StackPointer) = (stack_item_t)exec;    // return from interrupt address
    StackPointer -= 14;                        // emulate "push R0-R12", "push LR"
    if((uintptr_t)exec & (1 << 0))      // if exec is THUMB-mode code
        *(--StackPointer) =   0x003F;          // SR value: system mode, FIQ & IRQ enabled, THUMB mode
    else
        *(--StackPointer) =   0x001F;          // SR value: system mode, FIQ & IRQ enabled, ARM mode

#if scmRTOS_DEBUG_ENABLE == 1
...

Попробуйте, и, если всё нормально, то я внесу правку в репозиторий.

Share this post


Link to post
Share on other sites
А тема про CortexM3 :)

Попробуйте, и, если всё нормально, то я внесу правку в репозиторий.

Про кортекс не заметил, был увлечен ARM7 :rolleyes:

 

Поправки внес. Все запустилось и работает прекрасно. Надеюсь, что если пошло, то вылетов на этой почве уже не будет.

 

Спасибо! :rolleyes:

Share this post


Link to post
Share on other sites

Исправил в репозитории.

 

Попутно вскрылся интересный факт - я правил с старом репозитории, а в новом изменения пока не появились. Выходит, это два разных репозитория, и они синхронизируются. Надо тогда поаккуратнее быть...

 

Share this post


Link to post
Share on other sites
Исправил

Что-то не так... Сейчас снова одни нули вместо плавучки выводятся. Причем если вернуть определение стека так, как я первоначально сделал - то работает. Как Вы предложили - нет :crying: Неужели я в прошлый раз как-то компильнул проект не так :maniac: Оперативы у меня 32 метра, дефицита не наблюдается. malloc() столь необходимая (иногда?) printf - работает.

 

Пока думаю, куда копать...

 

Для очистки совести сделал

make clean && make all

для двух вариантов...

 

Вывод 1 (плохой)

#ai6di2
ADC0: 0x81 129 0.00
ADC1: 0x80 128 0.00
ADC2: 0x80 128 0.00
ADC3: 0x80 128 0.00
ADC4: 0x7f 127 0.00
ADC5: 0x7b 123 0.00

 

Вывод 2 (хороший)

#ai6di2
ADC0: 0x81 129 2.52
ADC1: 0x80 128 2.50
ADC2: 0x80 128 2.50
ADC3: 0x80 128 2.50
ADC4: 0x7f 127 2.48
ADC5: 0x7b 123 2.40

 

Сама функция работает (текст, hex, dec)

 

AHTOXA, а почему не стоит делать правку в кернел.h? Ведь это логично, там мы выравниваем стек именно процессов? Более того, Вы сами предложили этот вариант в первых постах) Нэ понимает моя)))

 

З.Ы. Блин, в map-файле от GCC без поллитра не разберешься...

 

Пошел мой разбор полетов:

1. По-сути при создании процесса мы попадаем в функцию

init_stack_frame

, которая инициализиует стэк. И уже там "готовится" указатель, выровненный пока не понятным для меня ( к сожалению опыта мало) образом. Т.е. что там, что тут - вроде без разницы...

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this