Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Несколько вопросов начинающего
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Страницы: 1, 2, 3
MiklPolikov
Такой вопрос :

Система виснет, потому что какая-то задача берёт семафор, и не отдаёт.
Какие есть способы узнать, где именно семафор не отдан ?
Неужели никаких простых нет, и "всё плохо" ?
juvf
ну у фриртоса вроде нет таких служебных функций. но так такое вроде на раз-два можно поймать.
заведи глобальную переменную 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(....);


ohmjke
Тут был мой вопрос, ответ на который я сразу же сам нашёл laughing.gif
Halfback
Всем доброго времени суток.
Есть такая проблема - если в кратце - то при пеердаче структуры в очереди теряются элементы.
Если по-конкретнне то есть вот такая структура:
Код
    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
проблема оказалась в определении очереди (привет 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));
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.