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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Получение свободного объема кучи, В ходе работы. CrossWorks 1.7.13
YChebisheva
сообщение Mar 24 2009, 09:14
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070



Есть ли какие-нить макросы, чтобы в ходе работы можно было знать, к примеру, адрес начала, конца и сколько осталось свободного места в куче?
Go to the top of the page
 
+Quote Post
etoja
сообщение Mar 24 2009, 09:33
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



Цитата(YChebisheva @ Mar 24 2009, 12:14) *
Есть ли какие-нить макросы, чтобы в ходе работы можно было знать, к примеру, адрес начала, конца и сколько осталось свободного места в куче?


Адрес начала кучи вам даст функция malloc, например:

char *p;
p = malloc(1); // просим выделить 1 байт из кучи

Размер кучи вы задаёте в свойствах проекта: Linker->Heap Size.
Go to the top of the page
 
+Quote Post
FormatCft
сообщение Mar 24 2009, 09:42
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145



Цитата(etoja @ Mar 24 2009, 14:33) *
Адрес начала кучи вам даст функция malloc, например:

char *p;
p = malloc(1); // просим выделить 1 байт из кучи

Размер кучи вы задаёте в свойствах проекта: Linker->Heap Size.


Вы уверены, что вновь выделяемый кусок будет именно в конце?


(из любопытства)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 24 2009, 09:45
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(YChebisheva @ Mar 24 2009, 12:14) *
и сколько осталось свободного места в куче?

Я оборачивал malloc/calloc/realloc/free в свои функции, в которых отслеживал задаваемый в параметрах размер. Типа того:

Код
static size_t mem_avail = 1024;// здесь размер кучи

void *malloc_prim(size_t size)
{
void *p;
p = malloc(size);
if(p!=NULL) mem_avail -=size;
return p;
}
#define malloc(sz) malloc_prim(sz)


УПС: порядок имеет значения #define после всей работы с настоящими malloc итд.
Go to the top of the page
 
+Quote Post
FormatCft
сообщение Mar 24 2009, 09:51
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145



Цитата(YChebisheva @ Mar 24 2009, 14:14) *
Есть ли какие-нить макросы, чтобы в ходе работы можно было знать, к примеру, адрес начала, конца и сколько осталось свободного места в куче?

Лучше ипользовать какой-нибудь открытый аллокатор.

Можно взять "монументальный" TLSF. В составе есть get_used_size.


Ну а если со стандартным, то можно написать так:

1) Разметка всего хипа опред числом.

2) При маллоке портим значение выделяемой области. Меняем на др чилсло.

3) При осовбождении востанавливаем число.

4) При вычислении считаем количество "испорченных".

Этот метод позовляет вычислить с достаточной степенью точности +\- 10 километров (шутка).
Go to the top of the page
 
+Quote Post
klen
сообщение Mar 24 2009, 09:56
Сообщение #6


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



я использую FreeRTOS, там есть три реализации maloc/free, я взял одну из них и добавил в нее все что мне нада, в том числе и функцию возвращающуую остаток кучи, могу исходник кинуть если хотите
Go to the top of the page
 
+Quote Post
FormatCft
сообщение Mar 24 2009, 10:05
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145



Цитата(klen @ Mar 24 2009, 14:56) *
я использую FreeRTOS, там есть три реализации maloc/free, я взял одну из них и добавил в нее все что мне нада, в том числе и функцию возвращающуую остаток кучи, могу исходник кинуть если хотите

Из всех 3х реализаций ровно ноль нормальных (Исключительно ИМХО).

По-моему при создании фриртоса ставилась основная цель: сделать добротный движок, но не было цели сделать номальный аллокатор.


Потому как хороших открытых и закрытых (в средах разработки) аллокаторов довольно много. Выбирайте на любой вкус.
Go to the top of the page
 
+Quote Post
klen
сообщение Mar 24 2009, 10:12
Сообщение #8


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Цитата(FormatCft @ Mar 24 2009, 13:05) *
Из всех 3х реализаций ровно ноль нормальных (Исключительно ИМХО).

По-моему при создании фриртоса ставилась основная цель: сделать добротный движок, но не было цели сделать номальный аллокатор.


Потому как хороших открытых и закрытых (в средах разработки) аллокаторов довольно много. Выбирайте на любой вкус.


"хороший" - это критерий из разряда "женщина более приятная"
мне достаточно выделения блока, освобождения блока, дефрагментация методом склейки соседних освобожденных блоков, и запрос на оставшийся размер хипа. пока хватет. если говорить о "хороших и разных" то их большинство на малюсенкий lpc2101 или ченить подобное просто не влезет с их мега-хеш-таблицами и тд, плавали - знаем. Все от задачи зависит.

поповоду фриртоса полностью согласен - не барское дело аллокатор писать smile.gif вед он и нужен в подразумераймых системах обычно только от скуки программиста, или от его кривости рук. За все время не помню задачу чтоб без malloc/free можно было выполнить задачу, обычно наоборот требуют чтоб такого "разгильдяйства" как maloc/free небыло maniac.gif
Go to the top of the page
 
+Quote Post
YChebisheva
сообщение Mar 24 2009, 12:07
Сообщение #9


Участник
*

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070



Парни, у меня не стоит задача, оптимизировать работу с памятью.
Если я смотрю map-файл:

.heap 0x40002458 0x400
0x40002458 __heap_start__ = .
*(.heap)
0x40002858 . = (((__heap_start__ + __HEAPSIZE__) MAX_K .) ALIGN 0x4)
*fill* 0x40002458 0x400 00
0x40002858 __heap_end__ = (__heap_start__ + SIZEOF (.heap))
0x00000001 . = ASSERT (((__heap_end__ >= __SRAM_segment_start__) && (__heap_end__ <= (__SRAM_segment_start__ + 0x4000))), error: .heap is too large to fit in SRAM memory segment)
0x40002858 __stack_load_start__ = (__heap_end__ ALIGN 0x4)

Получается, что у меня куча начинается с 0x40002458. Объем 1 Кб. Его размер я могу поменять. Память выделяет с конца кучи к началу.
Но сразу после инициализации, я делаю так:
Код
system_init();
spi0_mem_init();
ctl_global_interrupts_enable();    
UART0Initialize(38400, InterruptCom0);
char *s = (char*) malloc(1);
printf("     %p      ", s);
free(s);

Адрес s мне показывается - 284с. А конец кучи - 2858. Вроде как 13 байт. Но почему не 16? Ведь если следом запросить, к примеру 5 байт из кучи, адрес будет - 283с.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 24 2009, 12:24
Сообщение #10


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(YChebisheva @ Mar 24 2009, 15:07) *
Если я смотрю map-файл:
0x40002858 __heap_end__ = (__heap_start__ + SIZEOF (.heap))


Если линкер поставляет Вам (компилеру)  __heap_end__ , то зачем эти пассы:

Код
char *s = (char*) malloc(1);



если можно просто s=__heap_end__;
Go to the top of the page
 
+Quote Post
YChebisheva
сообщение Mar 24 2009, 12:39
Сообщение #11


Участник
*

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070



Цитата(_Pasha @ Mar 24 2009, 15:24) *
Если линкер поставляет Вам (компилеру)  __heap_end__ , то зачем эти пассы:
Код
char *s = (char*) malloc(1);

если можно просто s=__heap_end__;

В том то и беда, что на все эти попытки, имеем одно:
Цитата
'__heap_end__' undeclared (first use in this function
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 24 2009, 13:04
Сообщение #12


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(YChebisheva @ Mar 24 2009, 15:39) *
В том то и беда

Даже как extern void* __heap_end__; ?
Go to the top of the page
 
+Quote Post
YChebisheva
сообщение Mar 24 2009, 13:14
Сообщение #13


Участник
*

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070



_Pasha, левые адреса возвращает:

printf("%p", __heap_end__);
6f2cbea3
sad.gif
Go to the top of the page
 
+Quote Post
FormatCft
сообщение Mar 24 2009, 14:01
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 331
Регистрация: 22-07-08
Из: Р О С С И Я
Пользователь №: 39 145



Цитата(YChebisheva @ Mar 24 2009, 18:14) *
_Pasha, левые адреса возвращает:

printf("%p", __heap_end__);
6f2cbea3
sad.gif

Описал так:

extern void * __heap_start__;
extern void * __heap_end__;



volatile void * heap_start = &__heap_start__;
volatile void * heap_end = &__heap_end__;
Всё отлично.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Mar 24 2009, 14:02
Сообщение #15


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Это я глупость сморозил, должно быть так:

Код
extern char __heap_end__;

int main(void)

{

//фигли-мигли

void * s = (void *) &(__heap_end__);

}
Go to the top of the page
 
+Quote Post
YChebisheva
сообщение Mar 25 2009, 08:49
Сообщение #16


Участник
*

Группа: Новичок
Сообщений: 21
Регистрация: 9-01-09
Пользователь №: 43 070



Спасибо. Всё работает
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 31st July 2025 - 09:05
Рейтинг@Mail.ru


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