Jump to content

    

MiG-3

Участник
  • Content Count

    19
  • Joined

  • Last visited

Community Reputation

0 Обычный

About MiG-3

  • Rank
    Участник
  1. Добрый день, коллеги! Никто не сталкивался с такой проблемой: не могу заставить после завершения отладки (Terminate) продолжить исполнение программы в микроконтроллере (он похоже в halt остается). Пробовал разные галки, залез и в команды JlinkGbdServer, но что-то решения не найду. Например в IAR, CCS - кристалл всегда продолжает работу.
  2. FreeRTOS Heap_x.c

    Спасибо за ответ! Да это-то понятно. Но вот откуда выделяется память вопрос был. Меня интересивало, где выделяется этот массив, размером configTOTAL_HEAP_SIZE. Он входит в размер heap, который указан в настройках линковщика или за пределами этого размера. Ну грубо говоря, если heap = 20000 байт, а configTOTAL_HEAP_SIZE = 10000 байт. Я занимаю в ОЗУ 20000байт или 30000байт. Я тут попробовал - вроде получается, что куча ОСИ выделяется в общей куче. Остальное ясно - спасибо.
  3. FreeRTOS Heap_x.c

    Добрый день, коллеги! Хочется более точно понять как и откуда выделяется память во FreeRTOS и особенности функционирования отдельных выделяльщиков. Проект в IARe, в конфигурации линковщика есть параметр "heap". Так ли я понимаю, что при использовании heap_1.c, heap_2.c, heap_4.c для оси выделяется динамическая память размером "configTOTAL_HEAP_SIZE". Вопрос 1. Откуда она выделяется? Т.е. "configTOTAL_HEAP_SIZE" это часть "heap" или "configTOTAL_HEAP_SIZE" - это память, забираемая плюсом к "heap"? Т.е. сколько мне остается на переменные проекта :-) Вопрос 2. Для heap_3.c размер кучи - это "heap" линковщика? Вопрос 3. В последних версиях FreeRTOS heap_4.c (heap_5.c) имеет все равно проблемы с фрагментацией? Вопрос 4. Если память выделяется динамически на этапе старта - инита оси, стеков и пр., а в дальнейшем изменения задач, мутексов и динамически выделяемых данных не предвидится, то есть ли смысл париться альтернативным кодом аллокаторов?
  4. Спасибо за ответы! Разбираюсь потихоньку. К сожалению нет ясной методики расчета контура, где по шагам было расписано на основе исходных данных получение параметров контура. Но вроде как ясно, что собственную частоту контура с ПИ-фильтром определяет требуемое быстродействие контура, демпфированием задаемся (типа 0.707 классика). А вот как совместить ФАПЧ с частотной подстройкой? что будет частотным детектором? Где инфу копнуть? PS частота сети не всегда стабильна, есть девайсы типа дизельгенераторов.
  5. Надо захватить синус входной сети 50Гц, расстройка может быть в пределах 44-56 Гц, быстродействие 2-3 периода синуса, т.е. 0.04-0.06 с. Ясно, что повышение быстродействия приведет к расширению полосы пропускания фильтра петли ФАПЧ и увеличению влияния шумов. Т.е. для реализации такой задачи достаточно ПИ-фильтра в ОС петли? Если да, то ради чего и как стоит усложнять структуру ФАПЧ? И можно, Михаил, обратиться в личку по некоторым вопросам?
  6. Коллеги! А если стоит задача подстроить и фазу и частоту генератора синуса под входной опорный синусоидальный сигнал, то достаточно ли только петли ФАПЧ с фильтром второго порядка. Или все таки надо строить двухконтурную систему по частоте и по фазе? Все, включая генератор, детектор и фильтры, будет внутри контроллера, только опорный придет извне через АЦП. Кто практически такое реализовывал, может есть что подсказать?
  7. Привет! А ссылками, которые считаете дельными, не поделитесь? Лучше и на русские тексты тоже :-)
  8. Добрый день, коллеги!!! Кто-то зареген на AltiumLive. Не качнете и не поделитесь библиотечкой EFM32 MCU families ?
  9. Проблема решилась - именно приоритет прерывания, если из него есть вызовы функции API оси. Теперь почему не бесконечное ожидание семафора. Тут просто в коде задачи не хватает строчек для WDT. Т.е. задача переодически должна говорить, что она не зависла.
  10. Спасибо! Похоже это и есть косячок. Еще вчера занялся этим вопросом. Приоритет установил 7-ку (для 3-битного поля). Тестю! Еще раз спасибо!
  11. Использую IAR для армов. Понял, спасибо за совет, и это попробуем.
  12. Вот коллега не поверите - даже не знаю. Специально такую команду я в обработчик от UARTa не вставлял. Если не сложно ответьте - как это влияет на взаимодействие обработчика прерывания и семафора? Я пишу на С, стоит глянуть дизассемблер, может компилятор сам это генерит для обработчика? Приведу, чтобы было от чего отталкиваться: Инит-код для UARTa: *************************************************************************** *** Инициализация аппаратных средств для RS-485 **/ void RS485_Setup(void) { /* Конфигурируем GPIO pins для RS-485 */ GPIO_PinModeSet(RS485_TX_PORT, RS485_TX_PIN, gpioModePushPull, 1); GPIO_PinModeSet(RS485_RX_PORT, RS485_RX_PIN, gpioModeInputPull, 1); GPIO_PinModeSet(RS485_CX_PORT, RS485_CX_PIN, gpioModePushPull, 0); // на прием /* Инициализация UART для RS-485, тактирование USART должно быть включено - BaudRate = 19200 baud - Word Length = 9 Bits - One Stop Bit - No parity Don't enable UART upon intialization */ const USART_InitAsync_TypeDef init = { usartDisable, // Disable RX/TX when init completed 0, // Provide information on reference frequency. When set to 0, the reference frequency is 19200, // Baud rate usartOVS16, // Oversampling. Range is 4x, 6x, 8x or 16x usartDatabits9, // Number of data bits. Range is 4 to 10 usartNoParity, // Parity mode usartStopbits1, // Number of stop bits. Range is 0 to 2 false, // Disable majority voting false, // Disable USART Rx via Peripheral Reflex System usartPrsRxCh0 // Select PRS channel if enabled }; USART_InitAsync(RS485_USART, &init); // Инициализируем асинхронный режим /* Вкл автоформирование CS для драйвера RS-485, устанавливаем Multi-processor mode, 9-бит = 1 - адрес устройства */ RS485_USART->CTRL |= USART_CTRL_AUTOCS | USART_CTRL_CSINV | USART_CTRL_MPM | USART_CTRL_MPAB | USART_CTRL_TXDELAY_TRIPLE; /* Enable signals TX, RX, CS */ RS485_USART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CSPEN; // | USART_ROUTE_LOCATION_LOC0 - подразумеваем (т.к. = 0); /* Prepare UART Rx and Tx interrupts */ RS485_USART->IFC = _USART_IF_MASK; // сбрасываем флаги прерывания от UARTa // вкл прерывания RX - на прием и MPAF-адрес мультипроцессорной системы RS485_USART->IEN |= USART_IEN_RXDATAV | USART_IEN_MPAF; NVIC_ClearPendingIRQ(RS485_RX_IRQn); NVIC_EnableIRQ(RS485_RX_IRQn); // Включаем UART на прием с блокировкой RX - работает только прием адресов RS485_USART->CMD = USART_CMD_RXEN | USART_CMD_RXBLOCKEN; } Обработчик прерывания: /** *************************************************************************** *** Обработчик прерывания на прием RS-485 **/ void RS485_RX_IRQHandler(void) { uint8_t rxData; /* Обработка прерывания по адресу */ if (RS485_USART->IF & _USART_IF_MPAF_MASK) { rxData = (uint8_t)(RS485_USART->RXDATA); // Считываем адрес из буфера UART RS485_USART->IFC = USART_IFC_MPAF; // Очистить флаг MPAF interrupt if(rxData == SVO_ADR) // Совпадение с адресом СВО { RX_Counter = 0; RX_Length = PR_POS_TYPE; // Минимум данных до длинны RS485_USART->CMD = USART_CMD_RXBLOCKDIS; // Разблокируем прием RX } else return; } /* Обработка прерывания по приему данных */ if (RS485_USART->IF & _USART_IF_RXDATAV_MASK) { rxData = (uint8_t)(RS485_USART->RXDATA); // Считываем адрес из буфера UART switch (RX_Counter) // На лету декодируем заголовок пакета { case PR_POS_LENGTH: if (rxData >= RS485_RX_BUFFERSIZE) { RS485_USART->CMD = USART_CMD_RXBLOCKEN; return; } RX_Length = rxData; break; case PR_POS_TYPE: // Если не для СВО пакет, останавливаем прием, ждем следующего флага начала пакета if (rxData != SVO_TYPE) { RS485_USART->CMD = USART_CMD_RXBLOCKEN; return; } } } RS485_RX_Buf[RX_Counter] = rxData; RX_Counter++; if (RX_Counter == RX_Length) { RS485_USART->CMD = USART_CMD_RXDIS; // Блокируем прием по RX /* Выдаем двоичный семофор в задачу-обработчик по приему полного пакета */ portBASE_TYPE xHigherPriorityTaskWoken; xHigherPriorityTaskWoken = pdFALSE; xSemaphoreGiveFromISR(xRxSemaphore ,&xHigherPriorityTaskWoken ); if( xHigherPriorityTaskWoken == pdTRUE ) vPortYieldFromISR(); } } Задача: /** *************************************************************************** *** Задача работы с RS-485 **/ void taskRS485_ISR(void * pvParameters) { portBASE_TYPE xStatus; extern xQueueHandle xQueueRelay; // Очередь на реле в модуле Board.с extern uint16_t TermoArray[]; extern tDiscreteInput DiscreteArray[]; extern uint8_t DIPackByte; uint16_t CRC; uint8_t* TxPacket; uint8_t i, ContNum, ReadCount, idx; vSemaphoreCreateBinary(xRxSemaphore); vQueueAddToRegistry(xRxSemaphore, "SEM"); vTaskDelay( TimeoutBeforeStart ); // Пауза для точной идентификации перезагрузки СВО // и прихода паспортного пакета от контроллера for (;; ) { xStatus = xSemaphoreTake(xRxSemaphore, 200); // Ждем приема пакета от ISR по RX if (xStatus == pdPASS) { CRC = GetCRC(RS485_RX_Buf, RS485_RX_Buf[PR_POS_LENGTH]-2); // Проверяем CRC пакета if (CRC == PACK_WORD(RS485_RX_Buf[RS485_RX_Buf[PR_POS_LENGTH]-2], RS485_RX_Buf[RS485_RX_Buf[PR_POS_LENGTH]-1])) { ................................................................................ ......................................................... SendPacket( TxPacket, TxPacket[PR_POS_LENGTH] ); } // Включаем UART на прием с блокировкой RX - работает только прием адресов RS485_USART->CMD = USART_CMD_RXEN | USART_CMD_RXBLOCKEN; } } vTaskDelete( NULL ); }
  13. Добрый день! Возникла проблемка, которую пока не могу решить. Может кто-то с такой сталкивался. Пока код не буду постить. Делаю прием данных из UARTa в оброботчике прерывания. По приему всего пакета отдаю из обработчика двоичный семафор в задачу. В задаче принимаю семафор с ограниченным ожиданием. Все работает нормально, но через какое-то время (1 час, 12 часов, сутки - по разному) происходит зависон задачи. Из отладки выяснил, что этот двоичный семафор не ждет ни прием семафора, ни отдачи, его длинна 1 элемент. Т.е., как я понимаю, он уже получил из обработчика прерывания семафор, но отдавать в задачу не хочет (даже по таймауту задача не продолжается). Что это??? Как это??? Т.е. вроде все класически, но...
  14. Добрый день, коллеги! На схеме общая земля разбита на несколько типа DGND, AGND и т.д. Как в Альтиуме обыграть эту ситуацию без ругани :-) Сейчас создал в схематике элемент с двумя пинами, и каждый законектил на свою землю. Потом есть соответственно на PCB библиотечный элемент с этими двумя пинами и перемычкой между ними (все в слое топ). Соответственно редактор ругается на непозволительно близкое расположение цепей. Кто как такое обыгрывал у себя в проектах? Заранее спасибо за советы!