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

kostya-m

Участник
  • Постов

    207
  • Зарегистрирован

  • Посещение

Сообщения, опубликованные kostya-m


  1. Требуется программист с, не обязательно большим, но опытом работы по технологии.

    Работа в офисе требуется, поскольку нужно отлаживаться с реальным железом, включающим не только контроллер.

    Можно и старшекурсник института, достаточно 2-3 дня в неделю присутствия со свободным, но заранее обговоренным графиком.

    З.п. от 40 т.р. с возможностью роста.

    Ближайшая работа: пересобрать готовую сборку FreeRTOS под ту же плату, но новый проект и написать пользовательское приложение, отладить его.

    Телефон для связи: +7 916 675-8835

    Резюме на мыло: [email protected]

  2. Спасибо за мысли. Удалось разобраться. Виновником оказался драйвер SD. Мы сборку FreeRTOS заказывали на стороне и нам сделали зверинец по системным файлам обращения к SD. После того, как были взяты из примера ST STM32F2x7_ETH_LwIP_V1.1.0 комплектом stm322xg_eval_sdio_sd.c и diskio.c, проблема решилась.

  3. Есть проект сервисного устройства, которое ведет логи и считывает настройки через SD карточку.

    Для доступа к логам и настройкам поднят FTP сервер. В общем-то все работает. Но есть один баг, который, хотя и не мешает, но не дает спать спокойно. Проблема возникает при попытке закачать на устройство файл размерами выше нескольких килобайт. Всякие файлы настроек меньше и проходят, а скачать с устройства можно файл любого размера. Но, все равно, мне не нравится, что в ОС осталась такая проблема. Проблема возникает если первые блоки данных FTP сервер еще пишет на SD, а пришло несколько новых пакетов. Тогда портится связанный список и зависание идет в функции vListInsert

    Причем над этим местом есть даже комментарии для таких как я:

    /* *** NOTE ***********************************************************
            If you find your application is crashing here then likely causes are
            listed below.  In addition see http://www.freertos.org/FAQHelp.html for
            more tips, and ensure configASSERT() is defined!
            http://www.freertos.org/a00110.html#configASSERT
    
                1) Stack overflow -
                   see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
                2) Incorrect interrupt priority assignment, especially on Cortex-M
                   parts where numerically high priority values denote low actual
                   interrupt priorities, which can seem counter intuitive.  See
                   http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
                   of configMAX_SYSCALL_INTERRUPT_PRIORITY on
                   http://www.freertos.org/a00110.html
                3) Calling an API function from within a critical section or when
                   the scheduler is suspended, or calling an API function that does
                   not end in "FromISR" from an interrupt.
                4) Using a queue or semaphore before it has been initialised or
                   before the scheduler has been started (are interrupts firing
                   before vTaskStartScheduler() has been called?).
            **********************************************************************/

    1. Переполнения стека нет. Стоит и его контроль и давал значительно больше, его хватает с запасом.

    2. Раздача приоритетов прерываниям кажется наиболее вероятной причиной. Однако сверялся с разными похожими проектами, примерами от ST и демо проектами FreeRTOS. К тому же попробовал разные варианты приоритетов Eternet и SDIO - больше, меньше, одинаковые - результат одинаковый.

    3. Для контроля, ввел дополнительные assert в код, вроде все вызовы делаются в соответствии с правилами. Например такой configASSERT( (uxCriticalNesting || uxSchedulerSuspended || __get_BASEPRI() ) ); для контроля, что в функцию попал внутри критической секции или при остановленном шедулере или при закрытом приоритете прерывания.

    4. Гарантированно не причина.

    Менял исходный код LwIP версий от 1.1.0 до 1.4.0 и RfeeRTOS версий 6.1, 7.1, 7.2 и 8.1 - результат одинаковый. Код ftp сервера по выполнению закачки прост:

       for(;;)
        {
            err = netconn_recv(sess->dconn, &nbuff);
            len = ( nbuff != NULL && nbuff->p != NULL ) ? netbuf_len( nbuff ) : 0;
            if ( !len ) break;
            if ( err == ERR_TIMEOUT )
            {
                debug("[storeFile] timeout");
                break;
            }
            if ( err != ERR_OK )
            {
                debug("[storeFile] data error [%d]", err);
                if ( ERR_IS_FATAL(err) ) break;                // connection closed
                vTaskDelay(500);
                continue;
            }
            buff   = mem_malloc( len );
            if ( buff == NULL )
            {
                debug("[storeFile] error linear buff allocation");
                break;
            }
            netbuf_copy( nbuff, (void *)buff, len );
            netbuf_delete( nbuff );
    
            if ( f_write(fp, buff, len, &wlen) || len != (uint16_t)wlen )
            {
                debug("[storeFile] write error");
                mem_free( buff );
                break;
            }
            mem_free( buff );
        }
    
        f_close(fp);
        mem_free( fp );

    Пните мою мысль что и где еще проверить.

  4. Есть такой пример подключения LwIP http://www.st.com/st-web-ui/static/active/...sw-stm32060.zip

    Открываю его под IAR. Пример, в принципе, работает. Однако, такое впечатление, что вопреки, а не благодаря. Но возможно, я чего-то недопонимаю.

    Поскольку приход и отправка данных по Ethernet асинхронное событие, то логично работать через прерывание. Потому логично увидеть в коде инициализации и включение прерывания:

    main.c

    ...
    int main(void)
    {
    ...
      /* configure Ethernet (GPIOs, clocks, MAC, DMA) */ 
      ETH_BSP_Config();
        
      /* Initilaize the LwIP stack */
      LwIP_Init();
      
      /* Initialize webserver demo */
      http_server_netconn_init();
    
    ....
    }

    Соответственно в stm32f2x7_eth_bsp.c

    ...
    void ETH_BSP_Config(void)
    {
      /* Configure the GPIO ports for ethernet pins */
      ETH_GPIO_Config();
      
      /* Config NVIC for Ethernet */
      ETH_NVIC_Config();
    
      /* Configure the Ethernet MAC/DMA */
      ETH_MACDMA_Config();
    ....
    }
    ...
    void ETH_NVIC_Config(void)
    {
      NVIC_InitTypeDef   NVIC_InitStructure;
    
      /* 2 bit for pre-emption priority, 2 bits for subpriority */
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); 
      
      /* Enable the Ethernet global Interrupt */
      NVIC_InitStructure.NVIC_IRQChannel = ETH_IRQn;
      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);    
    }
    ...

    Вроде как разрешили прерывание по эзернету

    Однако открываю startup_stm32f2xx.s и вижу, что ETH_IRQHandler обслуживается внутренней заглушкой

    Попытки найти альтернативный обработчик прерывания в остальном коде примера не дали результата.

     

    Беру пример FreeRTOS 8.2.0. В нем, к сожалению, нет примера под IAR на STM32 Cortex и LwIP, но есть STM32F107 под GCC. В нем в STM32F10x_Startup.s отчетливо прописано

    .extern xPortPendSVHandler
    .extern xPortSysTickHandler
    .extern vPortSVCHandler
    .extern vMAC_ISR;

    Т.е. обслуживание прерывания есть. Как же пример от ST то работает?

  5. Прошло много времени. Не удалось ли решить проблему?

    У меня на похожем проекте на STM32F207VET+RTL8201 c FreeRTOS 8.2 + LwIP 1.4.0 происходит падучесть или через HardFault или через переполнение стека в контроле при переключении задач (vTaskSwitchContext) у несуществующей задачи. При этом стеки существующих задач в порядке и имеют большой запас по использованной длине. А указатель смотрит на то место, где скоро должна появиться новая задача, но эта область еще не очищена. Процедуру создания задачи проверил, там критическая область корректно определена. Происходит этот бардак при приходе IP пакета. Причем пинг не приводит к падению. Вероятность падения сильно растет с повышением скорости обмена. Т.е. если на ftp сервер лезть руками через утилиту ftp, то живется заметно лучше, чем через ftp клиента в far или проводник.

  6. Я использую два канала I2C. Один в мастере, смотрит на подконтрольные устройства. Он работает бит поллингом и хорошо. А второй смотрит на ARM процессор, который всем рулит. Вот для него и потребовалось.

    В документации приведена такая простая схема его обслуживания, но что-то не достказано. Мастер и слейв по реализации очень сильно отличаются.

  7. Нет ли у кого примера реализации на TMS320C672x I2C в слейве при обработке через прерывание. В фирменной документации SPRU877e есть "Figure 26. Using Interrupts for Slave-Transmitter/Receiver Operation, Repeat Mode (RM = 1)" где разрисована очень простая схема. Но что-то не работает. Чувствую, что у ТИ, как всегда, опущены мелкие важности.

  8. Удалось все сделать, работа обоих контроллеров McASP 0 и 1 через DMAX без применения библиотек. Описаниям из документации все соответствует, примерам - нет.

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

    При этом, я бы не сказал, что скорости и нагрузки так велики, один McASP принимает и отправляет на 48 кГц, а другой принимает и отправляет два потока на 96 кГц.

     

  9. Патч ставить обязательно, без него половина функций не работает. Да и с ним есть кривизна неописуемая. Далеко не все из того, что описано удается запустить. Если нет места на стандартный патч, я где-то то ли в прошлом, то ли в позапрошлом году выкладывал переделанный. Он идентичен исходному, но его можно наложить на рабочие массивы в основной программе, т.к. вызывается один раз, а дальше можно затереть.

    Спасибо, я его заранее скачал, но не применял, что бы понять его надобность. Значит нужен.

    Бит 0 в CSR, GIE = 1

    Бит 1 в IER, NMIE = 1

    Бит 8 в IER, IE8 = 1

    ISTP инициализирован правильным адресом таблицы прерываний

    По адресу ISTP + 8 * 8 * 4 записан правильный ISFP для INT8 с переходом в ISR

    И сама ISR записана по адресу из ISFP.

    Спасибо! GIE не стоял. Теперь принудительно заработало прерывание. Возьмусь за настройку его из dMAX

     

    После постановки патча dMAX перестал давать что до этого жило. Наверно жило не по-првилам.

    Заметил, что когда разрешаю эвенты в DEER, то эти же биты поднимаются в DEDR (запрет на эвенты) . Вроде по описанию они сбрасываются записью в DEER, но этого не происходит. Или это не важно?

    Еще вопрос по DEPR - полярность эвентов. В McASP бит XDATA и RDATA положительные, потому ставлю в DEPR единички - т.е. по поднятию (но и нолики не помогают)

    После инициализации dMAX внутри инициализации McASP0 идет проверка, что заработал dMAX тем, что дожидаюсь, что сбрасывается XDATA

    while( MCASP0->XSTAT.XDATA )
            asm( "    nop 4" ); // Если XDATA сбросился, значит DMA начал работать

    Теперь на этом зависаю. Хотя в DEFR стоит бит 4, который вроде как раз и отвечает за MCASP0TX. Но еще стоит бит 26 "AMUTEIN0 or McASP0 TX INT or McASP0 RX INT (error

    on MCASP0)". Но я обработчик этого дела еще не писал.

     

     

    Запретил прерывания у McASP - снялся бит 26, а 4-й остался, но обслуживания события не происходит. Все не дает мне покоя самовыставляемый бит в DEDR.

     

    Применил фирменный патч - все заработало, и dMAX и прерывания.

    Может я самодельный патч неправильно ставил? Я в начале main после инициализации таблицы прерываний вызывал

    dMaxPatch();

    и программу в буфер пока не засовывал.

  10. INT8? А оно разрешено во всех K регистрах разрешения? Начиная с битов в Event Entry TCC, ATCINT, TCINT и т.д...

    Вроде да. Даже иcискусственно его инициировал - стоит бит в IFR, но прерывание не вызывается

    Но наверно что-то еще упустил.

  11. Непосредственно да, действительно нет прерывания. Есть способ "в обход" (надо же, я не знал, только сейчас прочитал в data manuale, но как в воду глядел!) насетапить ивент энтри в dMAXе, чтобы генерилось прерывание от McASP (см. INT9-INT13 и INT15). Но это только если очень надо.

     

    Если задача просто запустить пример dMAX передачи, то и нужно использовать соответствующий ивент (EVT 5,7,9), а прерывание dMAX пусть устанавливает по завершению передачи.

     

    Спасибо. В общем то, я запустил и прием и передачу. Правда, пока с глюками и без обработки ошибок. И по общему описанию, а не по примеру. Ох тяжело разбирать. Странно, на другие семейства у ТИ гораздо лучше документация, а на 672х просто мрак. На 28х вообще никого не пришлось спрашивать, а тут на форуме ТИ пришлось кучу вопросов позадавать. Да и пока не удается получить прерывание 8-е по завершению. Но тут писали, что может надо патч применить к dMAXу

  12. Не знаю, зачем в примере ипользуется 18 ивент, но он програмно генерится установкой (или сбросом) бита 18 в регистре DETR.

    Вот и я не могу этого понять в примере по McASP, поскольку последний не должен трогать этот бит

  13. Для обслуживания McASP через dMAX в фирменном документе SPRU795D есть пункт 3.6.1 (страница 132)

    При ее изучении, возникли вопросы:

     

    1. Они почему-то используют абстрактный Event#18, хотя на странице 49 есть таблица событий и есть событие 5 - MCASP0RX - как раз предназначенное для обслуживания приема по нулевому каналу, который в примере. Собственно даже непонятно как это 18-е событие вдруг сгенерится.

     

    2. Почему в качестве адреса источника используется базовый адрес McASP0 0x54000000, а не адрес приемного буфера McASP0.RBUF[0] 0x54000280, с которого реально придут первые данные

     

    3. Предположим, что ответ на пункт 2 в том, что dMAX сам разберется из какого буфера читать, но зачем тогда введены инкременты для адреса источника SINDX0,1,2. После чего в на картинке примера вообще чтение из McASP идет по адресам 0х540000000, 0х54000004 и 0х54000008

    spru795d_TMS320C672x_DSP_Dual_Data_Movement_dMAX.pdf

  14. Нашел на гугле пример правильной установки даты и времени

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
    PWR_BackupAccessCmd( ENABLE );
    
    RTC_SetTime( RTC_Format_BIN, &ts );
    RTC_SetDate( RTC_Format_BIN, &ds );
    RTC_WriteBackupRegister(RTC_BKP_DR1, 0xA5A5);
    PWR_BackupAccessCmd( DISABLE );

    С ним все заработало

  15. По поводу снятия защиты, я открываю библиотеку и там

    ErrorStatus RTC_SetTime(uint32_t RTC_Format, RTC_TimeTypeDef* RTC_TimeStruct)
    {
    .......
    /* Disable the write protection for RTC registers */
     RTC->WPR = 0xCA;
     RTC->WPR = 0x53;
    
     /* Set Initialization mode */
     if (RTC_EnterInitMode() == ERROR)
     {
    status = ERROR;
     } 
     else
     {
    /* Set the RTC_TR register */
    RTC->TR = (uint32_t)(tmpreg & RTC_TR_RESERVED_MASK);
    
    /* Exit Initialization mode */
    RTC_ExitInitMode(); 
    
    if(RTC_WaitForSynchro() == ERROR)
    {
      status = ERROR;
    }
    else
    {
      status = SUCCESS;
    }
    
     }
     /* Enable the write protection for RTC registers */
     RTC->WPR = 0xFF; 
    
     return status;
    }

    Защиту снимают в самой функции. Причем дебагер у меня проходит по этому месту. Как раз после этого идет вызов RTC_EnterInitMode, внутри которого и происходит ошибка.

    Сами часы настраиваются в функции, которая при старте ОС проверяет, настроены ли часы и, если надо, их настраивает полностью. Неужели и при назначении даты или времени надо проводить так же полную инициализацию, а не только установку даты и времени?

  16. Что-то у меня ни какими средствами не удается установить дату и время. Причем, если CMOS сброшен, то первичная инициализация проходит и назначается время и дата, но не те, что надо, а так, дефолтные. Потом приходит нужная дата и время, а назначить не удается.

    Процессор SMM32F207. Компилятор GCC в среде CodeBlocks

    ОС в прошивке FreeRTOS

    Дата и время приходят по сети Ethernet, но обрабатываются потом в очереди.

        ts.RTC_Hours     = (uint8_t) tm->hour;
        ts.RTC_Minutes     = (uint8_t) tm->min;
        ts.RTC_Seconds     = (uint8_t) tm->sec;
        ds.RTC_Year     = (uint8_t) (tm->year % 100);
        ds.RTC_Month     = (uint8_t) tm->month;
        ds.RTC_Date     = (uint8_t) tm->day;
        ds.RTC_WeekDay     = (uint8_t) tm->wday;
        portENTER_CRITICAL();
        PWR_BackupAccessCmd( ENABLE );
        // сохраняем дату и время
    
      //RTC_WriteProtectionCmd(DISABLE);
      //RCC_RTCCLKCmd(ENABLE);
      //RTC_WaitForSynchro();
    
        RTC_SetTime( RTC_Format_BIN, &ts );
        RTC_SetDate( RTC_Format_BIN, &ds );
      //RTC_WriteProtectionCmd(ENABLE);
        PWR_BackupAccessCmd( DISABLE );
        portEXIT_CRITICAL();

    Сначала были только функции назначения даты и времени, потом попытки шаманства, в том числе запрета прерываний. Ничего не помогает.

    Отладчик показывает, что доходим до функции RTC_EnterInitMode, там взбодряют RTC->ISR и ждут

    RTC->ISR = (uint32_t)RTC_INIT_MASK;
    
        do
        {
          initstatus = RTC->ISR & RTC_ISR_INITF;
          initcounter++;  
        } while((initcounter != INITMODE_TIMEOUT) && (initstatus == 0x00));

    Но флага INITF так и не дожидаемся.

    Функции чтения даты и времени работают нормально, на экран часто выводится и дата и время. Но вот назначить новое не получается.

    Что не так?

  17. Некая задача послала себя в ожидание вызвав vTaskDelay

    Можно ли сделать так, что бы она была разблокирована раньше времени?

    Судя по графу состояний ее можно сначала отправить в suspend через vTaskSuspend, а потом разбудить через vTaskResume.

    Но попытка такой функции

    void UnblockDisplayTask( void )
    {
      if( !xTaskIsTaskSuspended( DisplayTaskHandle) ) vTaskSuspend( DisplayTaskHandle );
      vTaskResume( DisplayTaskHandle );
    }

    приводит к зависанию на vTaskSuspend

     

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

     

    ----------------------------------------------------

     

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

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