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

 
 
> Динамическое размещение буфера в функции, Если размер изначально неизвестен...
KnightIgor
сообщение Dec 27 2012, 10:40
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725



Привет всем.

Бывает, что на этапе компиляции размер требуемого буфера внутри функции точно неизвестен. В этом случае используют либо динамическое размещение памяти (malloc), что тянет за собой всю поддержку этого хозяйства, либо "забивается" локальная переменная типа массив с заведомо достаточным размером. Однако его может не хватить при определенных условиях. Пример из собственного опыта: пишем код, который при работе (runtime) должен модифицировать отдельные константы во flash микроконтроллера. В этом случае очевидно нужен буфер на размер страницы flash, чтобы считать ее туда, модифицировать необходимые области и снова скинуть целиком во flash. А теперь представим, что код без перетрансляции (пусть он в библиотеке) должен работать на дериватах микроконтроллера с различным размером страницы flash (например 512 и 2K).

У меня возникла идея (наверняка не оригинальная) размещать буфер динамически не в heap, а в локальном стеке. Для этого я написал следующие функции:
CODE
// ---------------------------------------------------------------------------
//
// The pair __alloc_sp() and __dealloc_sp() implements a runtime allocation
// of memory block within a function. The desired size of the memory buffer
// (in bytes) is given by 'size' parameter of __alloc_sp() that returns
// then a pointer to the allocated buffer.
//
// Afterwards, __dealloc_sp() releases the memory.
//
// The memory is obviously placed in the local stack.
//
// The idea behind is to provide a possibility to use buffers with the sizes
// that may be undefined at compilation time.
//
static __inline __asm
void * __alloc_sp(uint32_t size)
{
; align to 32-bit word
add r0, r0, #3
bic r0, r0, #3

; prepare the return value
sub r0, sp, r0

; save the entry stack pointer for __dealloc_sp()
str sp, [r0, #-4]

; move the stack down to the new position to point
; onto its own saved value!
mov sp, r0
sub sp, sp, #4
bx lr
}

static __inline __asm
long __dealloc_sp(void)
{
pop {r0}
mov sp, r0
bx lr
}

Код под KEIL, возможно под GCC какие-то ключевые слова будут выглядеть иначе.

Пример использования (абстрактный код):
Код
unsigned char flash_the_stuff(void *pvar, int size)
{
    int bufsize = GetMCUFlashPageSize();
    ...
    {
        unsigned char *buffer = __alloc_sp(bufsize);
        ...
        memcpy(buffer, pvar, size);
        ...
        __dealloc_sp();
    }
    return result;
}

Ваше мнение, уважаемые коллеги?

Сообщение отредактировал IgorKossak - Dec 27 2012, 17:48
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 07:55
Рейтинг@Mail.ru


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