Jump to content

    

MiG-3

Участник
  • Content Count

    19
  • Joined

  • Last visited

Everything posted by MiG-3


  1. Здравствуйте! Не сталкивался ли кто со следующей проблемой: проект под EWARM 6.21 target STM32F207. Не генерится код обработчиков прерывания, т.е. при уходе в прерывание проц. упирается в соответствующий вектор и там висит. Смотрим инфу по компиляции - ф-ции обработчики не имеют кода, размера и т.д., т.е. их нет. Это происходит, если в настройках проекта указать тип языка C++. Если ставим язык С, то эти функции появляются в коде и в них передаеться управлении при соответствующем событии. Вопрос: как при использовании С++ тогда определять вектора прерывания? Где какую галку кликнуть в пректе?
  2. Добрый день, коллеги! Никто не сталкивался с такой проблемой: не могу заставить после завершения отладки (Terminate) продолжить исполнение программы в микроконтроллере (он похоже в halt остается). Пробовал разные галки, залез и в команды JlinkGbdServer, но что-то решения не найду. Например в IAR, CCS - кристалл всегда продолжает работу.
  3. FreeRTOS Heap_x.c

    Спасибо за ответ! Цитата(Непомнящий Евгений @ Dec 8 2014, 16:11) Не понял что значит "для оси выделяется динамическая память"? configTOTAL_HEAP_SIZE задает объем памяти, доступный через pvPortMalloc. Память с его помощью выделяет сама ОС, и он же может использоваться в пользовательском коде... Есть массив размера configTOTAL_HEAP_SIZE, из него память и выделяется. Да это-то понятно. Но вот откуда выделяется память вопрос был. Меня интересивало, где выделяется этот массив, размером configTOTAL_HEAP_SIZE. Он входит в размер heap, который указан в настройках линковщика или за пределами этого размера. Ну грубо говоря, если heap = 20000 байт, а configTOTAL_HEAP_SIZE = 10000 байт. Я занимаю в ОЗУ 20000байт или 30000байт. Я тут попробовал - вроде получается, что куча ОСИ выделяется в общей куче. Остальное ясно - спасибо.
  4. 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. Если память выделяется динамически на этапе старта - инита оси, стеков и пр., а в дальнейшем изменения задач, мутексов и динамически выделяемых данных не предвидится, то есть ли смысл париться альтернативным кодом аллокаторов?
  5. Добрый день, коллеги!!! Кто-то зареген на AltiumLive. Не качнете и не поделитесь библиотечкой EFM32 MCU families ?
  6. Спасибо за ответы! Разбираюсь потихоньку. К сожалению нет ясной методики расчета контура, где по шагам было расписано на основе исходных данных получение параметров контура. Но вроде как ясно, что собственную частоту контура с ПИ-фильтром определяет требуемое быстродействие контура, демпфированием задаемся (типа 0.707 классика). А вот как совместить ФАПЧ с частотной подстройкой? что будет частотным детектором? Где инфу копнуть? PS частота сети не всегда стабильна, есть девайсы типа дизельгенераторов.
  7. Цитата(Михаил_K @ Sep 17 2013, 16:13) Все зависит от того, что вы хотите получить. Какое время переходного процесса. Какая начальная расстройка по частоте. Чисто теоретически у ФАПЧ с интегратором в цепи обратной связи бесконечная полоса захвата, но вот практически так не получается. Да и время захвата пропорционально квадрату начальной расстройки. Надо захватить синус входной сети 50Гц, расстройка может быть в пределах 44-56 Гц, быстродействие 2-3 периода синуса, т.е. 0.04-0.06 с. Ясно, что повышение быстродействия приведет к расширению полосы пропускания фильтра петли ФАПЧ и увеличению влияния шумов. Т.е. для реализации такой задачи достаточно ПИ-фильтра в ОС петли? Если да, то ради чего и как стоит усложнять структуру ФАПЧ? И можно, Михаил, обратиться в личку по некоторым вопросам?
  8. Коллеги! А если стоит задача подстроить и фазу и частоту генератора синуса под входной опорный синусоидальный сигнал, то достаточно ли только петли ФАПЧ с фильтром второго порядка. Или все таки надо строить двухконтурную систему по частоте и по фазе? Все, включая генератор, детектор и фильтры, будет внутри контроллера, только опорный придет извне через АЦП. Кто практически такое реализовывал, может есть что подсказать?
  9. Цитата(SmarTrunk @ Jul 16 2013, 17:24) Может, еще лучше почитать книжки по ФАПЧ, которых сейчас много интересных, особенно, если читаете по английски. Там обычно объясняются и нюансы петлевых фильтров, и фильтрующие свойства ФАПЧ. Привет! А ссылками, которые считаете дельными, не поделитесь? Лучше и на русские тексты тоже :-)
  10. Огромное СПАСИБО!!!
  11. Добрый день! Возникла проблемка, которую пока не могу решить. Может кто-то с такой сталкивался. Пока код не буду постить. Делаю прием данных из UARTa в оброботчике прерывания. По приему всего пакета отдаю из обработчика двоичный семафор в задачу. В задаче принимаю семафор с ограниченным ожиданием. Все работает нормально, но через какое-то время (1 час, 12 часов, сутки - по разному) происходит зависон задачи. Из отладки выяснил, что этот двоичный семафор не ждет ни прием семафора, ни отдачи, его длинна 1 элемент. Т.е., как я понимаю, он уже получил из обработчика прерывания семафор, но отдавать в задачу не хочет (даже по таймауту задача не продолжается). Что это??? Как это??? Т.е. вроде все класически, но...
  12. Цитата(ViKo @ Apr 9 2013, 12:45) FreeRTOS не использую. Но - зачем ограниченное ожидание? Если семафора нет, нечего делать в задаче. Поставьте бесконечное ожидание. Проблема решилась - именно приоритет прерывания, если из него есть вызовы функции API оси. Теперь почему не бесконечное ожидание семафора. Тут просто в коде задачи не хватает строчек для WDT. Т.е. задача переодически должна говорить, что она не зависла.
  13. Спасибо! Похоже это и есть косячок. Еще вчера занялся этим вопросом. Приоритет установил 7-ку (для 3-битного поля). Тестю! Еще раз спасибо!
  14. Цитата(demiurg_spb @ Apr 8 2013, 13:12) Хорошо что на си пишете... Какой компилятор используете? Барьер в обработчике нужен для того, чтобы не залететь в него повторно и так бесконечно из-за того, что, например, флаг запроса на прерывание физически не успевает очиститься до выхода из обработчика. Ну а в контексте семафоров... не могу дать вам развёрнутого ответа, не использую free-rtos. Использую IAR для армов. Понял, спасибо за совет, и это попробуем.
  15. Вот коллега не поверите - даже не знаю. Специально такую команду я в обработчик от 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 ); }
  16. Добрый день, коллеги! На схеме общая земля разбита на несколько типа DGND, AGND и т.д. Как в Альтиуме обыграть эту ситуацию без ругани :-) Сейчас создал в схематике элемент с двумя пинами, и каждый законектил на свою землю. Потом есть соответственно на PCB библиотечный элемент с этими двумя пинами и перемычкой между ними (все в слое топ). Соответственно редактор ругается на непозволительно близкое расположение цепей. Кто как такое обыгрывал у себя в проектах? Заранее спасибо за советы!
  17. Спасибо, Сергей, помогло. А я вот глядя на примеры в стандартной библиотеки периферии от ST и не стал этого делать, а зря. Теперь найти осталось, что он при старте лезет один раз в это прерывание, хотя события еще нет подходящего
  18. С твердотельными CAD плохо знаком. Примитивами альтиума набросал ноги и цилиндр, но не очень красиво, когда вокруг "правильные" корпуса. Кто-то сможет изоброзить сие чудо? http://www.platan.ru/cgi-bin/qwery.pl/id=7...amp;group=10608 На этой же странице ссылка на pdf с размерами, серия SD