Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Lpc2000+RTOS+sprintf (Не работает sprintf)
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
mihask
Уважаемые сограждане подскажите пожалуйста, если кто знает smile.gif,
почему после выхода из sprintf программа переходит на вектор сбоя данных DAbt_Handler.
Так происходит только если я пытаюсь вывести в строку переменную float, если int то все нормально.
Почему такое может быть?

Процессор -LPC2103
Операционка - RTL- Keil
Компилятор-RealView

Структура программы следующая:
Есть три задачи каждая из которых активизируется периодически
при помощи конструкции:
Код
    os_itv_set (5);
        for(;;)
           {
             os_itv_wait ();
               }

это значит что каждая задача запускается каждые 50 млс (время для каждой задачи разное).
sprintf выполняется только в одной из задач.
Alex B._
а стек задачи не переполняется случайно?
mihask
Цитата(Alex B._ @ Feb 6 2007, 13:15) *
а стек задачи не переполняется случайно?


Стек задачи со sprintf я выделил отдeльно от остальных задач
Код
static U32 stk2[256];
- т.е. 1024 байта, выделял и 2K
Не помогает smile.gif
mihask
Добавлю еще, что если я отключаю одну из задач (причем я сделал ее пустой), то тоже
все нормально(sprintf работает с float).
zltigo
Цитата(mihask @ Feb 6 2007, 09:19) *
Стек задачи со sprintf я выделил отдeльно от остальных задач

Что значит "отдельно"? Точнее как "не отдельно" (если вытесняющие задачи) можно.

Цитата
Код
static U32 stk2[256];
- т.е. 1024 байта, выделял и 2K
Не помогает smile.gif

Осталось убедиться, что размер памяти линкеру указан правильный ( 8K всего у 2103 ) соответствующий данному чипу, иначе "выделить" то можно. А при попытке воспользоваться sad.gif.....
mihask
Цитата(zltigo @ Feb 6 2007, 15:07) *
Цитата(mihask @ Feb 6 2007, 09:19) *

Стек задачи со sprintf я выделил отдeльно от остальных задач

Что значит "отдельно"? Точнее как "не отдельно" (если вытесняющие задачи) можно.

Цитата
Код
static U32 stk2[256];
- т.е. 1024 байта, выделял и 2K
Не помогает smile.gif

Осталось убедиться, что размер памяти линкеру указан правильный ( 8K всего у 2103 ) соответствующий данному чипу, иначе "выделить" то можно. А при попытке воспользоваться sad.gif.....


В Кейловской операционке стандартным способом (через конфигуратор ОС) можно выделить
только одинаковый размер стека для каждой задачи. А через специальную функцию(при создании задачи) можно выделить стек другого размера для отдельной задачи.

Размер памяти линкеру выделен правильный, потому что, если превышаем размер стека (при его настройке), то после перелинковки он матерится что 8К превышено.

А вы использовали sprintf c float c какой нибудь осью ? Никаких там хитростей нет , кроме стека?
zltigo
Цитата(mihask @ Feb 6 2007, 11:25) *
А вы использовали sprintf c float c какой нибудь осью ? Никаких там хитростей нет , кроме стека?

Естественно использовал. Да какие там хитрости sad.gif - не хитрее memcpy().
Цитата
В Кейловской операционке стандартным способом (через конфигуратор ОС) можно выделить

Я бы назвал способ через какой-либо "конфигуратор" извращенным, а не стандарнтым smile.gif
Alex03
Цитата(mihask @ Feb 6 2007, 12:12) *
...почему после выхода из sprintf ... если я пытаюсь вывести в строку переменную float...

Процессор -LPC2103
Операционка - RTL- Keil
Компилятор-RealView

А Вы уверены что в Вашей среде (компилятор/библиотеки/настройки) можно в хххprintf() передавать float вместо double?
zltigo
Цитата(Alex03 @ Feb 6 2007, 11:41) *
А Вы уверены что в Вашей среде (компилятор/библиотеки/настройки) можно в хххprintf() передавать float вместо double?

Тем не менее это не может являться причиной вылета.
mihask
Цитата(Alex03 @ Feb 6 2007, 15:41) *
Цитата(mihask @ Feb 6 2007, 12:12) *
...почему после выхода из sprintf ... если я пытаюсь вывести в строку переменную float...

Процессор -LPC2103
Операционка - RTL- Keil
Компилятор-RealView

А Вы уверены что в Вашей среде (компилятор/библиотеки/настройки) можно в хххprintf() передавать float вместо double?


Дело в том что если я отключаю одну(пустую) из трех задач, то float он у меня замечательно выводит.

Цитата(zltigo @ Feb 6 2007, 15:33) *
Цитата(mihask @ Feb 6 2007, 11:25) *

В Кейловской операционке стандартным способом (через конфигуратор ОС) можно выделить

Я бы назвал способ через какой-либо "конфигуратор" извращенным, а не стандарнтым smile.gif


Не там помоему все чисто smile.gif "конфигуратор" встроен в Keil, прицеплен к настраиваевому файлу и
я тут же могу посмотреть какие константы изменились после моего вмешательства smile.gif
AlexandrY
Хе..Хе, это грабли библиотеки RealView.
Помогает только опция: --min_array_alignment=8
Иначе в библиотеки работы с float происходит непредусмотренное смещение стека, но не всегда, а только при определенном расположении стека.
Поэтому легкая перекомпоновка кода может приводить к разному поведению sprintf.
А операционка влияет на это тем образом, что стеки задач и соответственно переменные в них распологаются юзером не так как это сделал бы компилер знай он, что там будет распологаться float.
Alex03
Цитата(zltigo @ Feb 6 2007, 15:01) *
Тем не менее это не может являться причиной вылета.

Зависит.
1. От реализации этого самого sprintf (точнее внутренностей типа vsprintf). Обработка нечисел и т.д.
2. От самой "форматной" строки (в которой, например '*’ потенциально опасна).

Цитата(mihask @ Feb 6 2007, 15:11) *
Цитата(Alex03 @ Feb 6 2007, 15:41) *
А Вы уверены что в Вашей среде (компилятор/библиотеки/настройки) можно в хххprintf() передавать float вместо double?
Дело в том что если я отключаю одну(пустую) из трех задач, то float он у меня замечательно выводит.

Глюк он на то и глюк, очень часто проявляет себя при совсем левых действиях.
Почитайте доку на вашу sprintf, и если там написано double, то надо обязательно передавать double!
Ну или хоть попробуйте принудительно преобразовать в double.
AlexandrY
Т.е. еще уточнение. Сказанное относится к случаю если стеки задач определены статически как массивы.
Но если использовать для стеков динамическое выделение памяти, то нужно внимательно изучить менеджер динамической памяти.
Помочь может, например, менеджер блоков памяти фиксированной длины, который идет c uCOS.

Цитата(AlexandrY @ Feb 6 2007, 14:53) *
Хе..Хе, это грабли библиотеки RealView.
Помогает только опция: --min_array_alignment=8
Иначе в библиотеки работы с float происходит непредусмотренное смещение стека, но не всегда, а только при определенном расположении стека.
Поэтому легкая перекомпоновка кода может приводить к разному поведению sprintf.
А операционка влияет на это тем образом, что стеки задач и соответственно переменные в них распологаются юзером не так как это сделал бы компилер знай он, что там будет распологаться float.
zltigo
Цитата(AlexandrY @ Feb 6 2007, 12:23) *
Хе..Хе, это грабли библиотеки RealView.
Помогает только опция: --min_array_alignment=8

Обалдеть sad.gif Ничего не понимаю - ну ладно, выделили мы стек выровненный на 8. Ну и что? Это никак не гарантирует, что при вызове printf() указатель останется выровненным. Что-то здесь очень темное, если это так.
mihask
Цитата(AlexandrY @ Feb 6 2007, 16:23) *
Хе..Хе, это грабли библиотеки RealView.
Помогает только опция: --min_array_alignment=8
Иначе в библиотеки работы с float происходит непредусмотренное смещение стека, но не всегда, а только при определенном расположении стека.
Поэтому легкая перекомпоновка кода может приводить к разному поведению sprintf.
А операционка влияет на это тем образом, что стеки задач и соответственно переменные в них распологаются юзером не так как это сделал бы компилер знай он, что там будет распологаться float.


Большое спасибо всем кто помогал , особено AlexandrY ! Похоже все дело в --min_array_alignment=8. Боюсь кричать ура smile.gif, но помоему ... smile.gif З А Р А Б О Т А Л А smile.gif. Щас попроверяю ишо. Если это обман зрения, буду плакать ишо smile.gif

2AlexandrY А вы во многих проектах использовали RTOS+ RealView+sprintf+float?
AlexandrY
Компилер с самого начала придерживается выравнивания стека по границе 8.
Я когда пишу ассемблерные модули под RTOS, то тоже всегда ставлю директиву PRESERVE8
Поэтому в течении выполнения программы выравнивание на 8-мь всегда сохраняется.
А вот начинается оно с того как будет размещен стек задачи.
Ясно, что и сохранять в контексте RTOS надо тоже четное число 32-х битных регистров.
Просто где-то в функции __printf есть явное отсекание 3-х младших бит адреса переменной типа float.
Сейчас это место не вспомню, но отладчик легко покажет.


Цитата(zltigo @ Feb 6 2007, 15:10) *
Цитата(AlexandrY @ Feb 6 2007, 12:23) *

Хе..Хе, это грабли библиотеки RealView.
Помогает только опция: --min_array_alignment=8

Обалдеть sad.gif Ничего не понимаю - ну ладно, выделили мы стек выровненный на 8. Ну и что? Это никак не гарантирует, что при вызове printf() указатель останется выровненным. Что-то здесь очень темное, если это так.
zltigo
Цитата(AlexandrY @ Feb 6 2007, 14:29) *
Ясно, что и сохранять в контексте RTOS надо тоже четное число 32-х битных регистров.

Бесспорно. Но кто запретит мне в задаче завести нечетное количество локальных переменных?
И что тогда , будет при вызове printf() если:
Цитата
Просто где-то в функции __printf есть явное отсекание 3-х младших бит адреса переменной типа float.

Видимо min_array_alignment еще какие-то побочные эффекты имеет sad.gif.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.