LINUX.ORG.RU

C const. Memory error.

 , ,


1

4

Хой,

Программирую одну библиотеку ГУЯ для армовских микроконтроллеров. Компиллятор arm-none-eabi-gcc.

Итак трабл. Чтобы хранить шрифты я использую массив данных, хранящийся в ROM'e, т.е. const. Типа так: http://pastebin.com/raw/TujVYfmW

По-идее он const и проблем с рамой быть не должно. Ноооо... они есть. Когда этот файл добавлен полностью, то программа крашиться на одном маллоке, что впринципи странно, но когда я удаляю половину массива, оставляя только англ символы, то всё внезапно начинает работать! Я менял размер и хипа, и стака по-разному - и ваще ничего не меняется. Рамы ещё дохера используется только 50кб из 96кб. Флэши тоже. Всего прожка выходит в 130кб из 512кб.

Норм массив:

$ objdump -x MakiseTest401re.elf | grep Arial
00000000 l    df *ABS*	00000000 Arial24.c
08007f90 l     O .rodata	000001c0 ArialBold_24_OffsetTable
08008150 l     O .rodata	00002700 ArialBold_24_SymbolTable
0800a850 l     O .rodata	000000e0 ArialBold_24_WidthTable
0800a930 g     O .rodata	00000018 F_Arial24

Обрезанный:
$ objdump -x MakiseTest401re.elf | grep Arial
00000000 l    df *ABS*	00000000 Arial24.c
08007ea0 l     O .rodata	000001c0 ArialBold_24_OffsetTable
08008e28 l     O .rodata	000000e0 ArialBold_24_WidthTable
08008f08 g     O .rodata	00000018 F_Arial24
08008060 g     O .rodata	00000dc8 ArialBold_24_SymbolTable

Вроде всё норм. Как и должно быть. Функции отрисовки тоже работают отлично.

Мб кто-нить знает в чём проблема? Мб чё-нить глупое упустил?

★★★★

Может знаковость char виновата?

mittorn ★★★★★
()

Рекомендую выводить шрифты сразу на экран и не пихать в память

mittorn ★★★★★
()

Микроконтроллеры - это секс там где ты его совсем не ожидаешь.

Вообще для stm32 справедливо вот что -

declaring them const does not force the compiler to put it in FLASH

Что значит что конст просто гарантирует что твои данные не будут созданы в рандомном месте и не должны создавать лишней фрагментации.Но они будут жрать память, да. Рекомендую проверить свой шрифт на чистом проекте где точно не будет ничего влиять на его работу. А так особо ничего посоветовать кроме этого не могу, писал только под xtensa lx106 и avr.

Solexid
()

С чего ты взял, что массив виноват? Смотри, как у тебя в ld-скрипте память распределена. Ну и как malloc работает.

А вообще, не понимаю: на кой черт тебе malloc на микроконтроллере? Что за прикол такой?

anonymous
()
Ответ на: комментарий от anonymous

Я в том сообщении совершил пару очепяток, я хотел сказать что const может и не положить в ром, но так как я мудак, то получилось что получилось. Вообще так как опыт с сексом с stm32 и арм у меня нет, то суждение строилось на гуглинге особенностей работы с const и компиляторов для арм.

Solexid
()

Проверь куда линкер тебе распихивает стек, кучу и rodata.

Dark_SavanT ★★★★★
()
Ответ на: комментарий от someoneelsenotme

Если памяти с запасом, приличный аллокатор и не требуется жёсткий реалтайм - то ничего особо страшного.

Dark_SavanT ★★★★★
()

А вообще, если хочешь чтобы у тебя что-то лежало именно там где надо, то лучше класть в отдельную секцию. Компилятор может и в RAM положить.

Dark_SavanT ★★★★★
()
Ответ на: комментарий от Dark_SavanT

Всего прожка выходит в 130кб из 512кб.

512 кб у него памяти. Покажи приличный аллокатор, который не начнет жрать 2^X после пары аллокаций.

someoneelsenotme
()

Лучше прикинь сколько тебе памяти всего надо под шрифты и заведи под них отдельную секцию в памяти.

grimwaken
()
Ответ на: комментарий от grimwaken

Что за треш с отступами в сорцах?

	ETS_INTR_LOCK();
	{
		/* If this is the first call to malloc then the heap will require
		initialisation to setup the list of free blocks. */
		if( pxEnd == NULL )
		{
			prvHeapInit();
		}

			if( xWantedSize > 0 )
			{
				xWantedSize = xPortWantedSizeAlign(xWantedSize);
			}

			if( ( xWantedSize > 0 ) && ( xWantedSize < xFreeBytesRemaining ) )
			{

Is very simple and allocated memory from a statically allocated array,

бгг.

someoneelsenotme
()

смотри выравнивание массивов, в первую очередь доступ по uint16_t* и uint32_t* к нечетным адресам

zudwa
()
Ответ на: комментарий от someoneelsenotme

Конечно маллок. Современная ембед разработка мало чем отличается от комповой. Как по задачам, которые ставят разработчику, так и инструментами.

И как прикажете тут прожить без маллока? Когда приборчик, например, должен иметь несколько режимов работы с разными объёмами данных и датчиков. К тому же вот с чем, с чем, а с маллоком проблем у меня никогда не было. Да, этот Фриртосовский хип_4 работает как часы.

SL_RU ★★★★
() автор топика
Ответ на: комментарий от zudwa

В стмках с этим проблем нет - всё происходит хардварно, хоть в 2 раза и дольше по времени.

SL_RU ★★★★
() автор топика
Ответ на: комментарий от SL_RU

И как прикажете тут прожить без маллока? Когда приборчик, например, должен иметь несколько режимов работы с разными объёмами данных и датчиков.

Да тупо заводишь пул для своих данных и в них выделяешь память. Каждому типу данных (данные, обработчики датчиков и т.п.) свой пул. Как в lwip есть массив memp_pools структур memp_desc, и для этого массива функции memp_alloc и memp_free. Хотя по сути получается, что ты пишешь свой аллокатор.

grimwaken
()
Ответ на: комментарий от SL_RU

А причем тут таб вообще если их там нет? Код с гитхаба, табы тут могли повлиять только если они в пределах одного файла разного размера.

someoneelsenotme
()
Ответ на: комментарий от grimwaken

Пардон, но все равно веселые ребята:

void *pvPortRealloc(void *mem, size_t newsize)
{
    if (newsize == 0) {
        vPortFree(mem);
        return NULL;
    }

    void *p;
    p = pvPortMalloc(newsize);
    if (p) {
        /* zero the memory */
        if (mem != NULL) {
            memcpy(p, mem, newsize);
            vPortFree(mem);
        }
    }
    return p;
}

Проверять соседний блок, расширить текущий без реаллокации... Пффф... Можно же тупо выделить ВТОРОЙ МАССИВ ОДНОВРЕМЕННО С ПЕРВЫМ, скопировать и убить первый. Т.е. realloc зафейлится если попытаться расширить блок в половину от занимаемой памяти.

someoneelsenotme
()
Ответ на: комментарий от SL_RU

если они в пределах одного файла разного размера.

Повторяю вопрос - нахрена такие идиотские отступы? Я НЕ про количество пробелов или размер таба. Там НЕ открывается новый блок, а авторы с каждым оператором отодвигают действия все больше за экран.

someoneelsenotme
()
Ответ на: комментарий от someoneelsenotme

ах, увидел.

Ну возможн кто-то недоглядел, а потом отдельный коммит для этого делать лень.

SL_RU ★★★★
() автор топика
Ответ на: комментарий от someoneelsenotme

Т.е. realloc зафейлится если попытаться расширить блок в половину от занимаемой памяти

то тебе маллок в эмбедде не по нраву, то тебе реаллок подавай. нытик

anonymous
()
Ответ на: комментарий от anonymous

Ну если делать обертку над статик массивом то делать нормально, а не этот пиздец.

someoneelsenotme
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.