Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: sprintf
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
sergey sva
Где можно посмотреть исходник sprintf, библиотечная работает, только с целыми значениями, а если нужно %f зависает все ,где искать причину не знаю?
Dog Pawlowa
Цитата(sergey sva @ Apr 15 2010, 20:52) *
Где можно посмотреть исходник sprintf, библиотечная работает, только с целыми значениями, а если нужно %f зависает все ,где искать причину не знаю?

ЧТо за компилятор, что за среда, какие настройки библиотеки?
Подсказка - по умолчанию, для экономии программной памяти, в библиотеках часто предусматривается вывод только целых значений.
baralgin
Или нехватка стэка.
sergey sva
>ЧТо за компилятор, что за среда, какие настройки библиотеки?
>Подсказка - по умолчанию, для экономии программной памяти, в библиотеках часто предусматривается вывод только целых значений.

Компилятор Gcc yagarto eclipse код из макефайла:
Что где нужно изменить , что бы выводил с точкой?, собирать с нужными ключами?

<code>ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
CPFLAGS = $(MCFLAGS) $(OPT) -mthumb-interwork -mlong-calls -ffunction-sections -DNDEBUG -Wall -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS)
LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR)
LDFLAGS_ROM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_ROM) -Wl,-Map=$(PROJECT)_rom.map,--cref,--no-warn-mismatch $(LIBDIR)
</code>

<code>



heapsize 5000байт
Вот мап. Heap вроде не маленький
.heap 0x00207e50 0x1388
0x00207e50 _heap = .
0x00001388 . = HEAP_SIZE
*fill* 0x00207e50 0x1388 00
0x002091d8 . = ALIGN (0x4)
0x002091d8 _eheap = .
sergey sva
Вот что говорит на -target-help , может нужно еще добавить какие опции?, камень at91sam7x. в скрипте стек выровнен aling(8).

The following options are target specific:
-mabi= Specify an ABI
-mabort-on-noreturn Generate a call to abort if a noreturn function
returns
-mapcs-float Pass FP arguments in FP registers
-mapcs-frame Generate APCS conformant stack frames
-mapcs-reentrant Generate re-entrant, PIC code
-march= Specify the name of the target architecture
-mbig-endian Assume target CPU is configured as big endian
-mcallee-super-interworking Thumb: Assume non-static functions may be called
from ARM code
-mcaller-super-interworking Thumb: Assume function pointers may go to non-
Thumb aware code
-mcirrus-fix-invalid-insns Cirrus: Place NOPs to avoid invalid instruction
combinations
-mcpu= Specify the name of the target CPU
-mfix-cortex-m3-ldrd Avoid overlapping destination and address
registers on LDRD instructions that may trigger
Cortex-M3 errata.
-mfloat-abi= Specify if floating point hardware should be used
-mfpu= Specify the name of the target floating point
hardware/format
-mhard-float Alias for -mfloat-abi=hard
-mlittle-endian Assume target CPU is configured as little endian
-mlong-calls Generate call insns as indirect calls, if
necessary
-mpic-register= Specify the register to be used for PIC addressing

-mpoke-function-name Store function names in object code
-msched-prolog Permit scheduling of a function's prologue
sequence
-msingle-pic-base Do not load the PIC register in function prologues

-msoft-float Alias for -mfloat-abi=soft
-mstructure-size-boundary= Specify the minimum bit alignment of structures
-mthumb Compile for the Thumb not the ARM
-mthumb-interwork Support calls between Thumb and ARM instruction
sets
-mtp= Specify how to access the thread pointer
-mtpcs-frame Thumb: Generate (non-leaf) stack frames even if
not needed
-mtpcs-leaf-frame Thumb: Generate (leaf) stack frames even if not
needed
-mtune= Tune code for the given processor
-mvectorize-with-neon-quad Use Neon quad-word (rather than double-word)
registers for vectorization
-mword-relocations Only generate absolute relocations on word sized
values.
-mwords-little-endian Assume big endian bytes, little endian words

Known ARM CPUs (for use with the -mcpu= and -mtune= options):
cortex-m1, cortex-m3, cortex-r4f, cortex-r4, cortex-a9, cortex-a8,
arm1156t2-s, mpcore, mpcorenovfp, arm1176jzf-s, arm1176jz-s, arm1136jf-s,
arm1136j-s, arm1026ej-s, arm926ej-s, iwmmxt2, iwmmxt, xscale, arm1022e,
arm1020e, arm10e, arm968e-s, arm966e-s, arm946e-s, arm9e, arm1020t,
arm10tdmi, ep9312, arm940t, arm922t, arm920t, arm920, arm9tdmi, arm9,
arm740t, arm720t, arm710t, arm7tdmi-s, arm7tdmi, strongarm1110,
strongarm1100, strongarm110, strongarm, arm810, arm8, arm7dmi, arm7dm,
arm7m, arm7500fe, arm7500, arm7100, arm710c, arm720, arm710, arm700i,
arm700, arm70, arm7di, arm7d, arm7, arm620, arm610, arm600, arm60, arm6,
arm3, arm250, arm2

Known ARM architectures (for use with the -march= option):
iwmmxt2, iwmmxt, ep9312, armv7-m, armv7-r, armv7-a, armv7, armv6-m, armv6t2,

armv6zk, armv6z, armv6k, armv6j, armv6, armv5te, armv5e, armv5t, armv5,
armv4t, armv4, armv3m, armv3, armv2a, armv2
ARM-specific assembler options:
-k generate PIC code
-mthumb assemble Thumb code
-mthumb-interwork support ARM/Thumb interworking
-mapcs-32 code uses 32-bit program counter
-mapcs-26 code uses 26-bit program counter
-mapcs-float floating point args are in fp regs
-mapcs-reentrant re-entrant code
-matpcs code is ATPCS conformant
-mbig-endian assemble for big-endian
-mlittle-endian assemble for little-endian
-mapcs-frame use frame pointer
-mapcs-stack-check use stack size checking
-mno-warn-deprecated do not warn on use of deprecated feature
-mcpu=<cpu name> assemble for CPU <cpu name>
-march=<arch name> assemble for architecture <arch name>
-mfpu=<fpu name> assemble for FPU architecture <fpu name>
-mfloat-abi=<abi> assemble for floating point ABI <abi>
-meabi=<ver> assemble for eabi version <ver>
-mimplicit-it=<mode> controls implicit insertion of IT instructions
-EB assemble code for a big-endian cpu
-EL assemble code for a little-endian cpu
--fix-v4bx Allow BX in ARMv4 code

Linker options
==============

Use "-Wl,OPTION" to pass "OPTION" to the linker.

armelf:
--build-id[=STYLE] Generate build ID note
-Bgroup Selects group name lookup rules for DSO
--disable-new-dtags Disable new dynamic tags
--enable-new-dtags Enable new dynamic tags
--eh-frame-hdr Create .eh_frame_hdr section
--hash-style=STYLE Set hash style to sysv, gnu or both
-z combreloc Merge dynamic relocs into one section and sort
-z defs Report unresolved symbols in object files.
-z execstack Mark executable as requiring executable stack
-z initfirst Mark DSO to be initialized first at runtime
-z interpose Mark object to interpose all DSOs but executable
-z lazy Mark object lazy runtime binding (default)
-z loadfltr Mark object requiring immediate process
-z muldefs Allow multiple definitions
-z nocombreloc Don't merge dynamic relocs into one section
-z nocopyreloc Don't create copy relocs
-z nodefaultlib Mark object not to use default search paths
-z nodelete Mark DSO non-deletable at runtime
-z nodlopen Mark DSO not available to dlopen
-z nodump Mark DSO not available to dldump
-z noexecstack Mark executable as not requiring executable stack
-z now Mark object non-lazy runtime binding
-z origin Mark object requiring immediate $ORIGIN
processing at runtime
-z max-page-size=SIZE Set maximum page size to SIZE
-z common-page-size=SIZE Set common page size to SIZE
-z KEYWORD Ignored for Solaris compatibility
--thumb-entry=<sym> Set the entry point to be Thumb symbol <sym>
--be8 Output BE8 format image
--target1=rel Interpret R_ARM_TARGET1 as R_ARM_REL32
--target1=abs Interpret R_ARM_TARGET1 as R_ARM_ABS32
--target2=<type> Specify definition of R_ARM_TARGET2
--fix-v4bx Rewrite BX rn as MOV pc, rn for ARMv4
--fix-v4bx-interworking Rewrite BX rn branch to ARMv4 interworking veneer
--use-blx Enable use of BLX instructions
--vfp11-denorm-fix Specify how to fix VFP11 denorm erratum
--no-enum-size-warning Don't warn about objects with incompatible
enum sizes
--no-wchar-size-warning Don't warn about objects with incompatible
wchar_t sizes
--pic-veneer Always generate PIC interworking veneers
--stub-group-size=N Maximum size of a group of input sections that can be
handled by one stub section. A negative value
locates all stubs after their branches (with a
group size of -N), while a positive value allows
two groups of input sections, one before, and one
after each stub section. Values of +/-1 indicate
the linker should choose suitable defaults.
--[no-]fix-cortex-a8 Disable/enable Cortex-A8 Thumb-2 branch erratum fi
x

С такими параметрами собираю: все собирается без ошибок и предупреждений, работает, пока в sprintf(buf"%f" fldat); %f , после этого устройство запускается как доходит до
этой функции,зависает. Свою сделать мне такая универсальная как библиотечная не нужна, где бы посмотреть какой там алгоритм, что бы не изобретать велосипед.

ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
CPFLAGS = $(MCFLAGS) $(OPT) -mthumb-interwork -mlong-calls -ffunction-sections -DNDEBUG -Wall -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS)
LDFLAGS_RAM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_RAM) -Wl,-Map=$(PROJECT)_ram.map,--cref,--no-warn-mismatch $(LIBDIR)
LDFLAGS_ROM = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT_ROM) -Wl,-Map=$(PROJECT)_rom.map,--cref,--no-warn-mismatch $(LIBDIR)
# -g -gdwarf-2
# Generate dependency information
CPFLAGS += -MD -MP -MF .dep/$(@F).d
Аматер
У меня тоже висло все из за printf %f в keil. Помогло увеличение стека. Но потом чтобы за зря слишком много памяти не расходовать стал обходится без printf %f
MrYuran
printf() обычно имеет несколько "градаций" функционала, которые определяются заданными ключами при компиляции.
Почитайте документацию на библиотеки
Цитата
heapsize 5000байт

Хип и стек - вообще-то не одно и то же, скорее даже совершенно параллельные вещи, так что проверьте ещё и стек
sergey sva
Цитата
Хип и стек - вообще-то не одно и то же, скорее даже совершенно параллельные вещи, так что проверьте ещё и стек

Понимаю, в стек сохраняются содержимое регистров , регистра указателя, режим ядра.
В heap выделяется память для malloc. Или я что то не правильно понимаю?

Вот так настроено в скрипте, сколько нужно для того чтобы работал sprintf?

C_STACK_SIZE = 20000;
IRQ_STACK_SIZE = 10000;
FIQ_STACK_SIZE = 10;
SVC_STACK_SIZE = 10;
ABT_STACK_SIZE = 10;
UND_STACK_SIZE = 10;
HEAP_SIZE = 5000;

heap Расположен после стека, может наооборот сделать, как правильнее?

Код
    .stack : {
        __stack_start__ = .;
        . = ALIGN(4);
        . += IRQ_STACK_SIZE;
        . = ALIGN (4);
        __irq_stack_top__ = .;
        . = ALIGN(4);
        . += FIQ_STACK_SIZE;
        . = ALIGN (4);
        __fiq_stack_top__ = .;
        . = ALIGN(4);
        . += SVC_STACK_SIZE;
        . = ALIGN (4);
        __svc_stack_top__ = .;
        . = ALIGN(4);
        . += ABT_STACK_SIZE;
        . = ALIGN (4);
        __abt_stack_top__ = .;
        . = ALIGN(4);
        . += UND_STACK_SIZE;
        . = ALIGN (4);
        __und_stack_top__ = .;
        . = ALIGN(4);
        . += C_STACK_SIZE;
        . = ALIGN (4);
        __c_stack_top__ = .;
        . = ALIGN(4);
        __stack_end__ = .;
        . = ALIGN(4);
    } >RAM    
     . = ALIGN(8);
    _end = .;
    . = ALIGN(4);
    __end = .;
    . = ALIGN(4);
    PROVIDE(end = .);
    . = ALIGN(8);


     .heap : {
                 _heap = .;
                 . = ALIGN(4);
                 . = HEAP_SIZE;
                 . = ALIGN(4);
                _eheap = .;
                 . = ALIGN(4);
         }>RAM
sergeeff
Навскидку - все правильно. Совет - на IRQ_STACK_SIZE = 10000 - не многовато ли? Какие такие локальные массивы и структуры используются в прерываниях? HEAP_SIZE = 5000 - не слишком много.
sergey sva
Цитата
Навскидку - все правильно. Совет - на IRQ_STACK_SIZE = 10000 - не многовато ли? Какие такие локальные массивы и структуры используются в прерываниях? HEAP_SIZE = 5000 - не слишком много

Не знаю сколько использует HEAP_SIZE sprintf , да и для irq 500 байт хватит, Увеличил когда возникли проблемы с sprintf,
Проблемы похоже у многих с этим sprintf возникали из за не выровненного стека, маленького стека, вот и прибавил все.
Как узнать с какими ключами собран gcc ?, какой ключ отвечает за работу "градаций" функционала printf?
AHTOXA
А у вас вообще malloc() работает?
sergey sva
Странно получается не работает, а sprintf с целыми числами и строками работает.
Код
        dynamic_array = malloc(100 * sizeof(float));

        if(!dynamic_array)
        {sprintf(&BufLcdBot[0],"%s","malloc ne rabotaet");
            LCD_Print(&BufLcdBot[0],24,0x40, FLAGCSRTYPE_CSRNO_BLINKNO);
        }else{
            sprintf(&BufLcdBot[0],"%s","malloc rabotaet");
                        LCD_Print(&BufLcdBot[0],24,0x40, FLAGCSRTYPE_CSRNO_BLINKNO);

        }


        free(dynamic_array);
        dynamic_array = NULL;

Вот функция sbrk может она неправильный адрес возвращает, как проверить,уже не знаю ?
Код
caddr_t _sbrk(int incr)
{
    caddr_t prevHeap;
    caddr_t nextHeap;

    if (heap == NULL)
    { // first allocation
        heap = (caddr_t) & _heap;
    }

    prevHeap = heap;

    // Always return data aligned on a 8 byte boundary
    nextHeap = (caddr_t) (((unsigned int) (heap + incr) + 7) & ~7);

    // Check enough space and there is no collision with stack coming the other way
    // if stack is above start of heap
    if (nextHeap >= (caddr_t) & _eheap)
    {
        errno = ENOMEM;
        return NULL; // error - no more memory
    }
    else
    {
        heap = nextHeap;
        return (caddr_t) prevHeap;
    }
}



Нажмите для просмотра прикрепленного файла
AHTOXA
Цитата(sergey sva @ Apr 16 2010, 14:26) *
Код
     .heap : {
                 _heap = .;
                 . = ALIGN(4);
                 . = HEAP_SIZE;
                 . = ALIGN(4);
                _eheap = .;
                 . = ALIGN(4);
         }>RAM


Попробуйте заменить строчку
Код
         . = HEAP_SIZE;

на
Код
         . += HEAP_SIZE;
Сергей Борщ
Цитата(sergey sva @ Apr 16 2010, 10:26) *
heap Расположен после стека, может наооборот сделать, как правильнее?
Буквально вчера применил printf и sprintf. Голый yagarto 20091223. Сналала выругался на отсутствие _sbrk. Спросил гуглю, гугля посоветовал вот такое: http://embdev.net/topic/129753. sprintf заработал, но мама дорогая! Он добавил 40 килограммов кода, откусил около кило ОЗУ, подтянул динамическое распределение памяти и прочее. sscanf в AT91SAM7S64 уже не влез - он позвал с собой lseek и кучу других функций. Нахрена в sscanf lseek? Сижу, чешу репу - есть ли более легковесный вариант библиотеки или придется свой vsprintf подцеплять?
sonycman
В кейле для кортексов юзаю vsprintf постоянно.
Полновесный вариант весит около 8 килобайт, урезанный _vsprintf без поддержки плавучки 5 кило.

Что то сомневаюсь, что эта функция пользуется malloc и кучей, ей стёка что ли мало?
Сергей Борщ
Цитата(sonycman @ Apr 16 2010, 15:31) *
В кейле для кортексов юзаю vsprintf постоянно.
Вот и я в ИАРе пользовал с удовольствием. Тоже было ~8 кило и ни в чем себе не отказывал. Понятия не имею, зачем ему динамическое выделение памяти. Тут пишут что-то про thread-safe и прочие навороты.
AHTOXA
Цитата(Сергей Борщ @ Apr 16 2010, 19:19) *
Сижу, чешу репу - есть ли более легковесный вариант библиотеки или придется свой vsprintf подцеплять?

У kgp и codesourcery чуть поменьше выходит - около 33кsmile.gif
Я так понимаю, что более-менее полный printf есть только в avr-gcc, далее везде либо неполный (как в msp-gcc), либо уже совсем взрослый, как в arm-овских вариантах. Видимо считается, что уже можно себе позволить.
Кстати, _Pasha грозился newlib с нуля переписать smile.gif
smac
Цитата(sergey sva @ Apr 15 2010, 21:52) *
Где можно посмотреть исходник sprintf..

Я так понимаю, в Вашем случае исходник в newlib нужно искать, правда геморное это дело с теми исходниками разбираться (имхо конечно, наверняка есть и более геморные исходники). Если будете разбираться, пользуйтесь возможностью препроцессирования исходников (имеется ввиду GCC-шный ключ -E ).
ReAl
У avr-gcc, насколько я помню, поначалу тоже с malloc был. На стеке выделялся только буфер для преобразований целых чисел, а для плавающих форматов буфер длиннее и его по malloc выделяли.
Сергей Борщ
Цитата(sergey sva @ Apr 15 2010, 19:52) *
Где можно посмотреть исходник sprintf,
Вот тут есть несколько: http://menie.org/georges/embedded/index.html

В приложении тот, что я сейчас использую. На плавающей точке не проверял, но она там есть. Где взял - не помню. Помню, что допиливал - они умудрились в процессе вывода портить форматную строку. Сейчас использую его на ARM, поскольку int у него совпадает с long int, то поддержку ключа l закомментировал.
sergey sva
Хотел попробовать kgp но что то он у меня не идет пишет
Цитата
make all
make: *** No rule to make target `all'. Stop.

Похоже на то что какой то путь не указал в path, проделал так скачал kgp_arm_eabi_20100226 распаковал на C:\
после добавил две переменные в path C:\kgp_arm_eabi_20100226\arm-kgp-eabi\bin\;C:\kgp_arm_eabi_20100226\bin\
после в eclipse ->project->properties->settings->GNUarfParser указал C:\kgp_arm_eabi_20100226\bin\arm-kgp-eabi-addr2line
И C:\kgp_arm_eabi_20100226\bin\arm-kgp-eabi-c++filt
deskovery options Default. Может что то пропустил?

Из командной строки работает, Не пойму почему из eclipse не работает.
smac
Цитата(sergey sva @ Apr 17 2010, 19:54) *
Из командной строки работает, Не пойму почему из eclipse не работает.

При компиляции проекта эклипс наверняка вызывает
Код
make all <filename>
, а цели all в <filename> (по-умолчанию Makefile) нету. Разберитесь с проектом эклипса - мейкфайл у Вас подключен извне или эклипсом генерируется?
PS Наверняка с терминами у меня как всегда беда, поправьте кому не лень пожалуйста.
AHTOXA
Цитата(sergey sva @ Apr 17 2010, 21:54) *
Хотел попробовать kgp но что то он у меня не идет

Хм. Из-за одной небольшой проблемы сразу менять компилятор? Оригинально.
Вы читали моё сообщение номер 13? Исправили?
sergeeff
Я чего-то вообще не пойму в сыр-бор. Исходников sprintf в inet'e - пруд пруди. Что не найти подходящий? Выкинуть из библиотеки тот, что не нравится (или не работает), и добавить туда свою функцию. Dietlib можно поглядеть для начала, она компактно написана.
sergey sva
>Хм. Из-за одной небольшой проблемы сразу менять компилятор? Оригинально.
>Вы читали моё сообщение номер 13? Исправили?
Да спасибо сам сразу и не заметил, исправил. Функциия malloc работает, только sprintf все же не работает с float. Тут в инете нашел инструкцию к avr -gcc там написано(Для ARM думаю тоже самое будет) там написано для того чтобы работал полный Printf нужно подключить библиотеку -u,vfprintf -lprintf_flt -lm если добавляю эту строчку , то пишет что -lprintf_flt
не найден. Компилятор менять не собираюсь просто попробовать, может понравится. smile.gif

>Я чего-то вообще не пойму в сыр-бор. Исходников sprintf в inet'e - пруд пруди. Что не найти подходящий? Выкинуть из библиотеки тот, что не нравится (или не работает), и добавить >туда свою функцию. Dietlib можно поглядеть для начала, она компактно написа
Не знаю как добавить эту библиотеку, скачал detlibs-0.32 в этой папке много всяких файлов папок с исходниками есть makefile, ее нужно собрать ?
а потом то что получится положить в папку ,,yagarto/lib? не разу так не делал, потом заменить файлы stdio.h на файлы из detlib-0.32 ?
sergeeff
Цитата(sergey sva @ Apr 18 2010, 18:24) *
Не знаю как добавить эту библиотеку, скачал detlibs-0.32 в этой папке много всяких файлов папок с исходниками есть makefile, ее нужно собрать ?
а потом то что получится положить в папку ,,yagarto/lib? не разу так не делал, потом заменить файлы stdio.h на файлы из detlib-0.32 ?


Елы-палы. На кой вам всю библиотеку подключать! Вроде по русски написал. Поясняю по пунктам:

1. Сохранить оригинал вашей стандартной библиотеки, чтобы можно все вернуть на место.

2. Функцию sprintf выкинуть(удалить, стереть) из копии вашей библиотеки средствами вашего библиотекаря/линкера, чтобы не возникало конфликта имен функций.

3. Из DietLib (к примеру, я не утвердаю, что это лучший вариант, но и не худший) взять исходный текст sprintf (он ведь на стандартном С написан, не японскими иероглифами). Почитать его за чашкой кофе, не пролив кофе на клавиатуру.

4. Посмотреть (изучить) - он вам годится или нет. Может она (функция sprintf) использует еще какие-то функции из DietLib. Их найти и добавить в тот же модуль, где и sprintf.

5. Скомпилировать этот вариант sprintf с вашим проектом.

6. Поглядеть на экран (не забыв одеть очки, если они вам необходимы) и если терминал используется для отладки и посмотреть что и в каком виде выводится.

7. Понравится функциональность этого варианта sprintf (скорость, размер и пр.) - добавите ее к вашей стандартной библиотеке.

Все! Это что, фантастически трудная задача? Максимум - полчаса работы. Дебаты идут больше недели.
sergey sva
Спасибо, теперь работает float и строки и целые числа, и места много не занимает smile.gif smile.gif
Может кому пригодится Нажмите для просмотра прикрепленного файла
_Макс
Как указать вывод float с предшествующими пробелами до указанной минимальной ширины? Пробовал "%5f" либо "%а5" не получается. Float вообще в IAR не выводит, после обработки в массиве пусто, Int получается но как задать ширину понять не могу. Курил http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/ но безрезультатно.
defunct
Цитата(ReAl @ Apr 17 2010, 14:14) *
На стеке выделялся только буфер для преобразований целых чисел, а для плавающих форматов буфер длиннее и его по malloc выделяли.

Вначале писали извращенцы, асболютно не представляющие что такое МК. Потом за дело взялись нормальные люди и сделали правильно.
Я все никак не могу взять в толк почему некоторые делают маленький стек, и большой heap, а потом в коде начинают появляться воистину дебильные и тормозные конструции типа:

Код
foo()
{
    U8 *buf = (U8 *)malloc(256);
    /*
        malloc при поиске подходящего блока проходит километровую цепочку heap descriptor'ов.
        процесс прохода дескрипторов необходимо защитить локом либо другим sync примитивом,
        для обеспечения атомарности доступа,
        а значит прерывания могут быть запрещены на ОЧЕНЬ ДОЛГО.
    */
    ...



    free( buf );
    /*
        проходит через процесс объединения текущего блока со свободными,
        хоть этот процесс и быстрее чем выделение,
        но всяко медленнее чем одна команда "SUB SP, 256"
      
        в этом процессе требуется обеспечить атомарность при обращении к heap дескрипторам,
        а значит прерывания и здесь могут быть запрещены на относительно длительное время
    */
}


что мешает млин heap уменьшить на 256 байт, а стек на те же 256 байт увеличить? Чтобы было просто

Код
foo()
{
    buf[ 256 ];  // память выделена мгновенно

    // и освобождена автоматически
}
rezident
Цитата(defunct @ Jun 16 2010, 06:04) *
Я все никак не могу взять в толк почему некоторые делают маленький стек, и большой heap

ИМХО потому, что у кучи есть менеджер, а стек он неконтролируемый. Наползание стека на данные это одна из самых трудновылавливаемых ошибок при программировании МК.
defunct
Цитата(rezident @ Jun 16 2010, 03:54) *
Наползание стека на данные это одна из самых трудновылавливаемых ошибок при программировании МК.

Дык возникает она потому что
Цитата
делают маленький стек

В отличие от Heap'а и его проблем фрагментации, для стека где фрагментация впринципе невозможна (по природе LIFO) - объем можно оценить еще до run-time.
Помножить это число на два, и будет щастье. Если посчитать заранее тяжело - заполнение стек памяти патерном, прогон программы с последующим дампом памяти для оценки использования стека в run-time тоже никто не отменял.

Много ли толку от менеджера, когда в heap нет блока требуемого объема и менеджер возвращает NULL? А "гениальный программист" привыкший, что на PC память есть всегда, даже не соизволит проверить что вернул этот malloc, и сразу начинает туда что-то писать?
demiurg_spb
Цитата(defunct @ Jun 16 2010, 07:12) *
А "гениальный программист" привыкший, что на PC память есть всегда, даже не соизволит проверить что вернул этот malloc, и сразу начинает туда что-то писать?
Да, да. Я читал где-то что по современным веяниям проверять на NULL malloc и иже с ним - моветон.
Причём и с аргументациеё всё вроде как чики-поки... Но всё это естественно в контексте ПО под ПК.
rezident
defunct, было бы хорошо, если все было бы так просто. Только в топике речь шла вроде про embedded-программирование, где априори ОЗУ маловато, мало или совсем мало. laughing.gif
defunct
Цитата(rezident @ Jun 16 2010, 22:54) *
defunct, было бы хорошо, если все было бы так просто. Только в топике речь шла вроде про embedded-программирование, где априори ОЗУ маловато, мало или совсем мало. laughing.gif

Дык, куда уж проще, чем совсем без heap'а, когда ОЗУ априори маловато, мало или совсем мало ;>
Heap на мой взгляд, имеет хоть какой-то маломальский смысл когда в наличии есть хотя бы 32KB ОЗУ, и то только для объектов с большИм и очень большИм временем жизни.
MrYuran
Цитата(sergey sva @ Apr 19 2010, 00:27) *
Спасибо, теперь работает float и строки и целые числа, и места много не занимает smile.gif smile.gif
Может кому пригодится Нажмите для просмотра прикрепленного файла

Интересно, и как же флоат выводится, если там вот что:
Код
case 'f':
    
    break;

Вчера коллега пыхтел весь день.
Пытался в mspgcc полномерный флоат вывести.
Попробовал ваш вариант, потом от Сергея Борща, потом ещё что-то...
Я ещё глянул было в avr-libc, но там своя специфика, макросы доступа к флеши на асме написаны.
Хотя конечно можно переопределить..
В конце концов установили из закромов IAR и начали потрошить его либы

Цитата(_Макс @ Jun 16 2010, 02:41) *
Float вообще в IAR не выводит, после обработки в массиве пусто

Там есть "переключатель скоростей", поищите галочку в настройках.
По умолчанию printf обрезанный.
skripach
IAR float32 без проблем.
fox1
Добрый день ! Кто нибудь использует sprintf с выводом float с MSPGCC ???
В IARе все работает ...
Но не в MSPGCC .......

потрошу либы IARа .....
Код огромный ....
Куча definов .....
И все равно на выходе нули .... хотя и в формате ......
demiurg_spb
Включите в makefile поддержку расширенной printf.
Примерно так:
Код
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB = $(PRINTF_LIB_FLOAT)
MATH_LIB = -lm

fox1
Цитата(demiurg_spb @ Jul 7 2010, 18:24) *
Включите в makefile поддержку расширенной printf.
Примерно так:
Код
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB = $(PRINTF_LIB_FLOAT)
MATH_LIB = -lm


Не поможет ....
В исходниках нет поддержки sprintf для float ....

http://mspgcc.bzr.sf.net/bzr/mspgcc/mspgcc...tf.c?remember=3

ch=='f' нет .....
demiurg_spb
Понятно.
Тогда поищите по форуму.
Недавно тут кто-то искал/предлагал подходящие Вам исходники, было вроде как в ветке про ARM, точно не помню.
Wano
Малость не в тему. Смотрю человек работает с текстовым LCD. МЭЛТ я не использовал, но пробовал 3 других типа от разных производителей. Стандартная либа в codevision-е рано или поздно повисала. Писал сам. Через пару годиков в Keil-е использовал их примерчик, аналогичная проблема. Неясно почему , но через некоторое время(минуты-часы) busy флага можно ждать пока свет закончится. Может шум, может ещё чего, спасает реинит. А когда sprintf идёт прям перед выводом на экран, всегда кажется, что косяк в sprintf - экран же работает (так было у меня на avr-е).

p.s. Сейчас ,наверно, посыпятся сообщения типа : да у меня годами работает и ничего и тд...
fox1
Ну вобщем ... взломался printf с float от IARа ... даже работает с mspgcc ... полный набор ... тяжеловат конечно ...
жаль получился не совместим со стандартным printf от mspgcc ...
koluna
Столкнулся с определенными проблемами, используя маленький и слабенький процессор.
Немного поковырялся, обобщил результаты и решил вставить свои 5 копеек sm.gif

При сборке проекта (процессор STM32F100C4), содержащего вызов стандартной библиотечной функции sprintf() линковка не удается по двум причинам:
- Отсутствуют некоторые системные функции (ошибка ”undefined reference to `_sbrk'” или ей подобные).
- Код не помещается во FLASH.

Первая проблема обусловлена тем, что в тулчейнах для встраиваемых систем отсутствуют требуемые системные функции ( https://sourceware.org/newlib/libc.html#Syscalls ), которые необходимы для работы библиотеки newlib (эти функции обеспечиваются полноценной ОС). Их необходимо реализовать самостоятельно или взять готовый вариант ( http://electronix.ru/forum/index.php?showt...mp;#entry651990 ).

Вторая проблема обусловлена нехваткой FLASH памяти выбранного микроконтроллера, ”объемной” реализацией функции sprinft() и всего, что с ней связано. Поэтому оптимальное решение в сложившейся ситуации - поиск менее ”объемного” варианта этой функции.

Протестировал несколько вариантов функций sprintf() от различного производителя sm.gif
Тестирование проводилось с помощью простого приложения, написанного на языке C с использованием библиотеки SPL. Приложение осуществляет циклический вывод форматированной строки через USART микроконтроллера. Результаты тестирования приведены ниже (перечислены не все секции выходного файла). В итоге было установлено, что наиболее ”легкий” вариант реализации функции sprintf() от ChaN.

Функции sprintf() в стандартных библиотеках тулчейнов бывают в нескольких вариантах (или просто разные функции или разные библиотеки, часто с ограниченным функционалом). Часто функции, реализованные в стандартной библиотеке, требуют приличного количества ОЗУ, поэтому при их использовании необходимо обеспечить достаточный объем для стека (кучи).

ПО с использованием стандартной библиотечной функции sprintf().
Чтобы проект собрался пришлось увеличить в скрипте линкера размер региона FLASH до 32 кБ.
.text 27048
.ARM.exidx 8
.data 1436
.bss 80

ПО с использованием стандартной библиотечной функции sniprintf().
Это облегченный вариант sprintf(), работающий только с целыми числами.
.text 12092
.ARM.exidx 8
.text.align 4
.data 1436
.bss 80

ПО без использования форматированного вывода (без каких-либо функций sprintf()).
.text 1604
.text.align 4
.data 20
.bss 16

Реализация от ChaN (целые числа).
http://elm-chan.org/fsw/strf/xprintf.html
.text 2368
.data 20
.bss 28

Реализация от Georges Menie (целые числа).
http://www.menie.org/georges/embedded/index.html
.text 7656
.data 1308
.bss 80

Доработанный вариант от Сергея Борща (оригинал неизвестен)
http://electronix.ru/forum/index.php?showt...mp;#entry746084
.text 7952
.data 24
.bss 16

Вариант от sergey_sva
http://electronix.ru/forum/index.php?s=&am...st&p=746563
.text 13600
.ARM.exidx 8
.data 268
.bss 16

makefile и скрипт линкера использовался из комплекта scmRTOS. Тулчейн - Sourcery CodeBench Lite ARM EABI.

А, с Новым Годом всех! sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.