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

 
 
7 страниц V  « < 5 6 7  
Reply to this topicStart new topic
> Несколько вопросов начинающего
DASM
сообщение Jul 17 2014, 17:13
Сообщение #91


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Если бы я знал «как надо» то не сидел бы тут… увы я знаю только как не надо. Сколько у меня было этих «плавающих» указателей, сколько геммора с потоками (не надо говорить, что все просто, одна инверсия приоритетов чего стоит. В итоге над основной идеей подумать времени мало.
Go to the top of the page
 
+Quote Post
Lagman
сообщение Jul 17 2014, 19:11
Сообщение #92


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



ключевые слова malloc, free и их реализация в порте FreeRTOS для нужного процессора. http://microsin.ru/content/view/1308/44/
Go to the top of the page
 
+Quote Post
DASM
сообщение Jul 17 2014, 19:26
Сообщение #93


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Кому они ключевые ? Да хоть new, хоть malloc - суть одна - любой залетевший дятел разрушит все. Посмотрите примеры программ на Java - там нет этого дебилизма. С++ позволит даже такое *(int *)0x40001234 = 0; На Яве вам никто не позволит пользоваться указателями, оных и нету, и никто не позволит приводить типы с уменьшением точности. С++ - это очень старый язык, он неплох для своих лет, но уже 2014 на дворе. Тот же ассемблер завуалированный.
Go to the top of the page
 
+Quote Post
juvf
сообщение Jul 17 2014, 19:30
Сообщение #94


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

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(MiklPolikov @ Jul 17 2014, 19:17) *
Помогите пожалуйста разобраться с vPortFree.
Вот допустим, я удаляю задачу.
Что делать дальше ?
Во первых вы должны понимать что такое динамическое выделение памяти и для чего оно нужно. как работает стек и куча. В 2-х словах не объяснить.

Цитата
Нужно передать в vPortFree в качестве параметра хендлер этой задачи
ненужно.

вы знаете как работают функции malloc() и free()? Для чего они нужны? Как работают операторы new и delete? Если знаете, то не должно возникнуть вопросов по vPortFree. vPortFree - работает аналогично. Если не знаете или плохо знаете, лучше не заморачивайтесь и работайте на стеке, т.е. без vPortFree pvPortMalloc, иначе выстрел в ногу гарантирован. Зачем вам динамическая память? Если нужны динамические задачи - делайте динамические задачи. Но зачем в динамических задачах использовать динамическую память?

Цитата
Можно ли перед этим, прямо внутри задачи, запустить vPortFree ?
И как после этого задача продолжит работать , т.е. выполнит два последних действия
v_Task_Handle=NULL;
vTaskDelete(NULL);


Ещё раз....
1) выделяем в КУЧЕ 100 байт
void *p = pvPortMalloc( 100 );

2)создадим задачу и передаем в неё в качестве параметра указатель на выделенный блок памяти в куче.
xTaskCreate( myTask, "Leningrad", 30, p, 5, NULL ); - создали задачу myTask, присвоили ей имя Leningrad, размер стека 30( байт или чего-то там, см доки, для стм32 вроде 30*4), приоритет задачи 5. Вот здесь выделяется для нужд задачи 120 байт (30*4) - это стек задачи. Это от дельная память от блока в 100 байт.

3)внутри задачи удаляем задачу vTaskDelete(). Задача остановиться и прекратит работать. Но 120 байт стека и 100 байт в куче не освободятся.

4)Происходит вызов idle. idle высвобождает 120 байт стека задачи.

Но 100 байт выделеных с помощью pvPortMalloc ни кто не зачистит. Более того ни кто не знает - нужно ли эту память зачищать? может далее по алгоримту ваша программа будет работать так

5)создадим другую задачу и передадим в неё в качестве параметра указатель на выделенный блок памяти в куче. В этом блоке нужная информация
xTaskCreate( yourTask, "Moskow", 50, p, 4, NULL ); и более того может быть 100 байт использоваться сразу в 10 задачах. одну задачу удалили- но остальные задачи пользуют эту память.

Если у вас блок в 100 байт использует всего 1 задача и после удаления эти данные ненужны, то руками удалите pvPortFree(). Если удаляете внутри задачи, то перед vTaskDelete()
Код
//полезный код задачи использующий эти 100 байт
pvPortFree(*vParam);//высвобождение памяти выделенной в куче, но не высвобождение памяти стека, т.е. 120 байт продлолжают использоваться
//возможно ещё какойто полезный код, но здесь уже нельзя использовать эти 100 байт
vTaskDelete(NULL);
}
ну вот как-то так.

ps если у вас сценарий, как в последнем моём примере, то зачем вам вообще динамика? пишите в статике, будет вам автоматическая зачистка
Код
void myTask(void *context)
{
uint8_t array[100]; //выделение 100 байт на СТЕКЕ задачи
//полезный код
vTaskDelete(NULL);
}
//создаем задачу
xTaskCreate( myTask, "Leningrad", 30 + 25, 0, 5, NULL );// создали задачу и выделили под стек на 100 байт больше
При таком написании поле удаления задачи idle автоматически зачистит стек задачи? т.е. 120+100 байт, а куча не используется.
Go to the top of the page
 
+Quote Post
DASM
сообщение Jul 17 2014, 19:39
Сообщение #95


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(juvf @ Jul 17 2014, 23:30) *
Более того ни кто не знает - нужно ли эту память зачищать?

Если на нее никто не ссылается - сборщик мусора освободит ее. Если среда выполнения поддерживает это. Программист менее всего должен думать КОГДА освободить память. По-сути в нормальной серьезной программе с асинхронными обработчиками он даже и не может этого знать. Отсюда все эти Unhandled exception - а в области MCU - просто hard fault (и то если это Кортекс итп, а обычно просто крик в форуме "виснет, помогите"
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Jul 17 2014, 19:47
Сообщение #96


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(juvf @ Jul 17 2014, 23:30) *
ps если у вас сценарий, как в последнем моём примере, то зачем вам вообще динамика? пишите в статике, будет вам автоматическая зачистка[code]void myTask(void *context)


Видимо я плохо объяснил.
Речь не о памяти, занятой при выполнении задачи. Речь о стеке самой задачи. После удаления задачи память освобождается не сразу, а только в задаче idle . Если я сразу после удаления создаю новую задачу , а программа между этими двумя действиями не попадает в Idle task , то памяти может не хватить. Вопрос : как освободить память менее криво, чем вызывать между удалением и созданием vTaskDeleay ? Ну неужели не предусмотрено простого способа ?


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
juvf
сообщение Jul 17 2014, 20:09
Сообщение #97


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

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(MiklPolikov @ Jul 18 2014, 01:47) *
Видимо я плохо объяснил.
Речь не о памяти, занятой при выполнении задачи. Речь о стеке самой задачи. После удаления задачи память освобождается не сразу, а только в задаче idle . Если я сразу после удаления создаю новую задачу , а программа между этими двумя действиями не попадает в Idle task , то памяти может не хватить. Вопрос : как освободить память менее криво, чем вызывать между удалением и созданием vTaskDeleay? Ну неужели не предусмотрено простого способа ?

хороший вопрос. теоретически можно 100 раз создать задачу и 100 раз удалить, и при этом не разу не попав в idle.
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Jul 17 2014, 20:12
Сообщение #98


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Цитата(juvf @ Jul 18 2014, 00:09) *
хороший вопрос. теоретически можно 100 раз создать задачу и 100 раз удалить, и при этом не разу не попав в idle.

Вы начали меня понимать !


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
Lagman
сообщение Jul 17 2014, 20:36
Сообщение #99


Знающий
****

Группа: Свой
Сообщений: 875
Регистрация: 28-10-05
Пользователь №: 10 245



Цитата(DASM @ Jul 17 2014, 23:26) *
Кому они ключевые ? Да хоть new, хоть malloc - суть одна - любой залетевший дятел разрушит все. Посмотрите примеры программ на Java - там нет этого дебилизма. С++ позволит даже такое *(int *)0x40001234 = 0; На Яве вам никто не позволит пользоваться указателями, оных и нету, и никто не позволит приводить типы с уменьшением точности. С++ - это очень старый язык, он неплох для своих лет, но уже 2014 на дворе. Тот же ассемблер завуалированный.

Пользуйте BASIC и не будете так нервничать sm.gif

Цитата(DASM @ Jul 17 2014, 23:39) *
Программист менее всего должен думать КОГДА освободить память. По-сути в нормальной серьезной программе с асинхронными обработчиками он даже и не может этого знать.

Вот к чему мир катится, программисты превращаются в кодеров, которым не надо будет думать sm.gif и программы с миганием светодиодов для микроконтроллеров будут весить под несколько гигабайт sm.gif
Go to the top of the page
 
+Quote Post
juvf
сообщение Jul 17 2014, 20:40
Сообщение #100


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

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(DASM @ Jul 18 2014, 01:39) *
Если на нее никто не ссылается - сборщик мусора освободит ее. Если среда выполнения поддерживает это. Программист менее всего должен думать КОГДА освободить память. По-сути в нормальной серьезной программе с асинхронными обработчиками он даже и не может этого знать. Отсюда все эти Unhandled exception - а в области MCU - просто hard fault (и то если это Кортекс итп, а обычно просто крик в форуме "виснет, помогите"

в мэтро может и не должен знать. а в реалтайм - не то что должен - ОБЯЗАН знать. Прогер должен занать, что вот в этом месте код исполняется 100 тактов, и что никакие сборщики мусора его не прервут.

так то это очередной вброс говна в вентилятор на тему c++ vs java. а ветка про FreeRTOS. Предлагаю дальнейшее обсуждение языков для мк перенести в более подходящее место и не засорять эту тему.
Go to the top of the page
 
+Quote Post
MiklPolikov
сообщение Jul 31 2014, 13:48
Сообщение #101


Гуру
******

Группа: Свой
Сообщений: 2 015
Регистрация: 23-01-07
Из: Москва
Пользователь №: 24 702



Такой вопрос :

Система виснет, потому что какая-то задача берёт семафор, и не отдаёт.
Какие есть способы узнать, где именно семафор не отдан ?
Неужели никаких простых нет, и "всё плохо" ?


--------------------
Если у Вас нет практического опыта в данной теме- не вступайте в дискуссию и не пишите никаких теоретических рассуждений! Заранее спасибо !
Go to the top of the page
 
+Quote Post
juvf
сообщение Aug 1 2014, 05:47
Сообщение #102


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

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



ну у фриртоса вроде нет таких служебных функций. но так такое вроде на раз-два можно поймать.
заведи глобальную переменную const char* govnoPlace;


и далее...

Код
xSemaphoreTake(....);
govnoPlace = "void myFunk();";
//полезный код
govnoPlace = 0;
xSemaphoreGive(....);


Код
xSemaphoreTake(....);
govnoPlace = "Место, где солнце ни когда не светит";
//полезный код
govnoPlace = 0;
xSemaphoreGive(....);


потом проверяй чему равно govnoPlace, и поймешь в каком месте семафор застревает. Можно красивее сделать, перегрузить функции xSemaphoreTake и xSemaphoreGive и внутри них сделать присвоение к глобальному указателю приоритет текущей задачи, хандлер, имя задачи. А можно к присваивать к глобальной переменной имя файла и номер строки, где произошел захват. Если есть вывод, например в файл или в RS232, то можно сделать так

Код
xSemaphoreTake(....);
printf(stream, "Take semafor from %s file, line %s", __FILE__, __LINE__);
//полезный код
printf(stream, "Give semafor from %s file, line %s", __FILE__, __LINE__);
xSemaphoreGive(....);


Go to the top of the page
 
+Quote Post
ohmjke
сообщение Oct 12 2014, 14:55
Сообщение #103


Частый гость
**

Группа: Участник
Сообщений: 116
Регистрация: 27-01-10
Из: СПб
Пользователь №: 55 094



Тут был мой вопрос, ответ на который я сразу же сам нашёл laughing.gif

Сообщение отредактировал ohmjke - Oct 12 2014, 14:59
Go to the top of the page
 
+Quote Post
Halfback
сообщение Apr 23 2015, 05:21
Сообщение #104


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



Всем доброго времени суток.
Есть такая проблема - если в кратце - то при пеердаче структуры в очереди теряются элементы.
Если по-конкретнне то есть вот такая структура:
Код
    typedef struct {
            unsigned short int LSensor_Num;
            unsigned short int WLevelValueAv;
            unsigned short int TimeStartMeasure;
            unsigned short int DurationMeasureSec;
            } WLevelData;


Очередь инициализирована так:
Код
  osMessageQDef(Level2Storage_Queue, 4, WLevelData);
  Level2Storage_QueueHandle = osMessageCreate(osMessageQ(Level2Storage_Queue), NULL);


Задачи инициализированы так:
Код
osThreadDef(TX_Task, Start_TX_Task, osPriorityNormal, 0, 128);
  RD_TaskHandle = osThreadCreate(osThread(TX_Task), NULL);

  osThreadDef(RX_Task, Start_RX_Task, osPriorityBelowNormal, 0, 128);
  Storage_TaskHandle = osThreadCreate(osThread(RX_Task), NULL);


Есть задача где раз в 6 секунд происходит запись в очередь
Код
void Start_TX_Task(void const * argument)
{
    portTickType xLastWakeTime;
    portBASE_TYPE xStatus;
    
    WLevelData WLevel = {1,111,0,60};
    
    xLastWakeTime = xTaskGetTickCount();
  /* Infinite loop */
  for(;;)
  {
        xStatus = xQueueSendToBack(Level2Storage_QueueHandle,&WLevel,0);
        if(xStatus != pdPASS ) {} // Could not send to the queue
    vTaskDelayUntil(&xLastWakeTime,6000);
  }
}


Есть задача где периодически очередь считывается.
Код
void Start_RX_Task(void const * argument)
{
    portBASE_TYPE xStatus;
    portTickType xLastWakeTime;
    WLevelData WLevel_rx;
    
    xLastWakeTime = xTaskGetTickCount();

  for(;;)   {
        if(uxQueueMessagesWaiting(Level2Storage_QueueHandle)) {
                xStatus=xQueueReceive(Level2Storage_QueueHandle,&WLevel_rx,0);
                }
    vTaskDelayUntil(&xLastWakeTime,130);
  }
}


И в итоге прием происходит, но последние 2 значения (TimeStartMeasure и DurationMeasureSec) в структуре WLevel_rx всегда "0".
Увеличивал кучу на 10кБ. Также увеличивал глубину стека в задачах. Приоритеты менял. Не помогло.
МК: STM32F407VG, клок: 168МГц.
Почему так?

Сообщение отредактировал Halfback - Apr 23 2015, 06:44
Go to the top of the page
 
+Quote Post
Halfback
сообщение Apr 23 2015, 14:50
Сообщение #105


Местный
***

Группа: Участник
Сообщений: 322
Регистрация: 28-05-05
Пользователь №: 5 512



проблема оказалась в определении очереди (привет CubeMX)
Код
osMessageQDef(Level2Storage_Queue, 4, WLevelData);
  Level2Storage_QueueHandle = osMessageCreate(osMessageQ(Level2Storage_Queue), NULL);


если заменить на классику
Код
RDLevel2Storage_QueueHandle = xQueueCreate(4,sizeof(WLevelData));


то структура передаётся без потерь.

а проблема имхо кроется в
Код
#define osMessageQDef(name, queue_sz, type)   \
const osMessageQDef_t os_messageQ_def_##name = \
{ (queue_sz), sizeof (type)  }

osMessageQId osMessageCreate (const osMessageQDef_t *queue_def, osThreadId thread_id)
{
  (void) thread_id;  
  return xQueueCreate(queue_def->queue_sz, (uint32_t) sizeof(queue_def->item_sz));
}
Go to the top of the page
 
+Quote Post

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

 


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


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