Перейти к содержанию
    

pvPortMalloc & vPortFree

Обращаюсь к гуру с просьбой помочь разобраться.

Ситуация такая. Программа зависает либо в процедуре void vPortFree( void *pv ) в

prvInsertBlockIntoFreeList( ( ( xBlockLink * ) pxLink ) );
,

 

либо в процедуре void *pvPortMalloc( size_t xWantedSize ) в цикле

while( ( pxBlock->xBlockSize < xWantedSize ) && ( pxBlock->pxNextFreeBlock ) )

{

pxPreviousBlock = pxBlock;

pxBlock = pxBlock->pxNextFreeBlock;

}

 

Программа сделана так: в нескольких задачах суется в очередь(элементы очереди - это указатели) ссылка на некую структуру. Эта структура перед занесением в очередь создается с помощью pvPortMalloc.

Если очередь заполнена, то сразу же в этой задаче эта структура освобождает память с помощью vPortFree(void *pv).

Выглядит так,например:

pxTestTaskSend = (xSendCadrStruct*)pvPortMalloc(sizeof(xSendCadrStruct));

if (pxTestTaskSend == (xSendCadrStruct*)NULL) GotoGlobalCycleProcedure();

 

pxTestTaskSend->num = 0xFE;

pxTestTaskSend->ulCnt = 0;

pxTestTaskSend->ulData = (unsigned portCHAR*)pxBufferStat;

xResult = xQueueSendToBack(xSendCadrQueue, (void*)&pxTestTaskSend, 0);

if (xResult == errQUEUE_FULL) vPortFree(pxTestTaskSend);

 

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

xSendCadrStruct *xSendCadr;

 

for (;;){

xQueueReceive(xSendCadrQueue, &xSendCadr, portMAX_DELAY);

/**/

....... разбор структуры ......

switch (xSendCadr->num){

................

};

/**/

vPortFree(xSendCadr)

};

 

Вроде как все должно работать: в одном месте выделяется память, в другом - освобождается...

По вашему, где мог ошибиться?

Подскажите способы/наработки, как быстрее и эффективнее найти причину глюка.

 

PS. В прерываниях не использую void vPortFree( void *pv ) и void *pvPortMalloc( size_t xWantedSize ).

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для отчетности: дело оказалось, похоже, в следующем:

есть одна задача, которая использовала глобальную переменную-указатель на выделенную область памяти для структуры. Но у этой задачи есть клоны, т.е. получалось, что эта глобальная переменная использовалась в нескольких запущенных однородных задачах. В этой задаче происходило :

xSendCadrStruct *pxGazTaskSend;

static portTASK_FUNCTION(vGazRegulationTask, vParameters ){

 

for (;;){

xQueueReceive(pADCGazQueue[ucNumb], &ulData, portMAX_DELAY);

...........

pxGazTaskSend = (xSendCadrStruct*)pvPortMalloc(sizeof(xSendCadrStruct));

if (pxGazTaskSend != (xSendCadrStruct*)NULL){

pxGazTaskSend->num = ucNumb + 0x10; //xGaz->ucAddress

pxGazTaskSend->ulData = (unsigned portCHAR*)data;

pxGazTaskSend->ulCnt = ++xGazLocal->ucCnt;

xResult = xQueueSendToBack(xSendCadrQueue, (void*)&pxGazTaskSend, 0);

if (xResult == errQUEUE_FULL) vPortFree(pxGazTaskSend);

};

};

 

Перенес объявление переменной внутрь задачи, и глюк исчез,по крайней мере, пару часов уже работает, раньше зависало в теч 5 мин.

Траблы, видать, происходили после вызовов либо pvPortMalloc, либо внутри xQueueSendToBack и соответствующих переключений контекста на следующую однородную задачу, которая использовала ту же глобальную переменную.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...