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

Goofy

Свой
  • Постов

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

  • Посещение

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


  1. В том то и дело, что статическое.

     

    Требуется контроллером включать питание измерительного прибора, измерения которого как раз и обрабатывает контроллер.

     

    Как тогда вообще реализовать коммутирующую цепь?

    P-канальным mosfet"ом ?

    Или реле поляризационное посоветуете ?

     

    У меня есть РПС32, страшные такие и больше. Не хочу их ставить пока что.

  2. Процессор не выходил из supervisor режима (стек для всех тасков инициализировался так). Сделано было по непониманию, когда процессор валился от taskYield, который по ещё более глубокому недопаниманию вызывался напрямую, а не с вектора SWI

  3. Прилагающаяся к FreeRTOS процедура восстановление контекста

    ; Set the LR to the task stack.                                     
        LDR        R1, =pxCurrentTCB
        LDR        R0, [R1]
        LDR        LR, [R0]
    
    ; The critical nesting depth is the first item on the stack.     
    ; Load it into the ulCriticalNesting variable.                     
        LDR        R0, =ulCriticalNesting
        LDMFD    LR!, {R1}
        STR        R1, [R0]
    
    ; Get the SPSR from the stack.                                     
        LDMFD    LR!, {R0}
        MSR        SPSR_cxsf, R0
    
    ; Restore all system mode registers for the task.                 
        LDMFD    LR, {R0-R14}^
        NOP
    
    
    ; Restore the return address.                                     
        LDR        LR, [LR, #+60]
    
    ; And return - correcting the offset in the LR to obtain the     
    ; correct address.                                                 
        SUBS    PC, LR, #4

     

    При отладке JTAGом после выполнения команды LDMFD LR, {R0-R14}^ регистр SP не восстанавливается. Управление передаётся нормально, но фактически задачи пользуют один стек :cranky:

    аналогично при сохранении контекста, не хочет писать сбойное значение SP по адресу currentTCB

     

    процессор изначальной в супервизор, ARM режиме

     

    что упустил в настройках?

    Процедура вышла из под автора ОС. Либо стоит не верить глазам и JTAGу... Но факт что более менее ёмкая задача систему валит в data_abort

  4. Переделал демо скрипт кейла под свою конфигурацию:

     

    FUNC void Setup (void) {
    
      _WDWORD(0xFFFFF804, 0xFFFF0000);      // PIOC_PDR: Enable Peripheral Mode  
    
      _WDWORD(0xFFFFEF1C, 0x00010002);      // EBI_CSA:  CSA1 support for SDRAM
    
      _WDWORD(0xFFFFEA08, 0x852372F9);      // Init SDRAM
      _sleep_(10);                          // Wait for 10 ms
      _WDWORD(0xFFFFEA00, 0x00000002);
      _WDWORD(0x20000000, 0x00000000);
      _sleep_(10);                          // Wait for 10 ms
      _WDWORD(0xFFFFEA00, 0x00000004);
      _WDWORD(0x20000004, 0x00000001);
      _WDWORD(0xFFFFEA00, 0x00000004);
      _WDWORD(0x20000008, 0x00000002);
      _WDWORD(0xFFFFEA00, 0x00000004);
      _WDWORD(0x2000000C, 0x00000003);
      _WDWORD(0xFFFFEA00, 0x00000004);
      _WDWORD(0x20000010, 0x00000004);
      _WDWORD(0xFFFFEA00, 0x00000004);
      _WDWORD(0x20000014, 0x00000005);
      _WDWORD(0xFFFFEA00, 0x00000004);
      _WDWORD(0x20000018, 0x00000006);
      _WDWORD(0xFFFFEA00, 0x00000004);
      _WDWORD(0x2000001C, 0x00000007);
      _WDWORD(0xFFFFEA00, 0x00000004);
      _WDWORD(0x20000020, 0x00000008);
      _WDWORD(0xFFFFEA00, 0x00000003);
      _WDWORD(0x20000024, 0xCAFEDEDE);
    
      _WDWORD(0xFFFFEA04, 0x000000BB);      // Refresh for SDRAM (at 18.432 MHz)
    
      _WDWORD(0xFFFFEA00, 0x00000000);
      _WDWORD(0x20000000, 0x00000000);
    
      // <o> Program Entry Point
      PC = 0x20000000;
    }
        _sleep_(100);
    
    // Switching from Slow Clock to Main Oscillator for faster Download
    _WDWORD(0xFFFFFC20, 0x00000601);        // PMC_MOR:  Enable Main Oscillator
    _sleep_(10);                            // Wait for stable Main Oscillator
    _WDWORD(0xFFFFFC30, 0x00000001);        // PMC_MCKR: Switch to Main Oscillator
    
    _WDWORD(0xFFFFFD44, 0x00008000);        // WDT_MR:   Disable Watchdog
    
    Setup();                                // Init, and setup for Running
    
    LOAD payload_controller.axf INCREMENTAL   // Download

     

    Если компилировать голое while(1); в теле main ( размер образа программы ~1.5k ), то всё выполняется так как и должно.

    Когда же компилирую (FreeRTOS, размер образа ~11k)

        xTaskCreate(tskIdle, "Aux", 200, NULL, tskIDLE_PRIORITY + 1, NULL );
        xTaskCreate(tskTask1, "Comm", 200, NULL, tskIDLE_PRIORITY + 2, NULL );
        vTaskStartScheduler();

    то выполнение до main() (и этих строчек соответственно ) даже не доходит, а обнаруживается в районе 0x00100000

    При этом проходит инициализация переферии (асмовский конфигурационнй файл, что генерит кейл), передаётся управление к __main, далее подготовка кучи и стека (помоему)

    и потом (однозначно из кода написанного не мной) , достоверно точку ухода проследить не удалось покапрограмма перескакивает налево в район 0x00100000

     

     

     

    Собрано так:

     

    LR_IROM1 0x20000000 0x00010000  {  ; load region size_region
      ER_IROM1 0x20000000 0x00010000  {; load address = execution address
       *.o (RESET, +First)
       *(InRoot$$Sections)
       .ANY (+RO)
      }
      RW_IRAM1 0x20010000 0x00020000  {; RW data
       .ANY (+RW +ZI)
      }
    }

     

    На неправильную настройку клока и памяти не грешу (ведь минимальный код то всё - таки в SDRAM работает)

     

    Чем может объясняться подобное поведение процессора ?

  5. Первый опыт программирования указанного процессора

     

    Пользуюсь платой от стартеркита (http://starterkit.ru/new/index.php?name=Pages&op=page&pid=15, по факту впаян sam9260)

    Стер с него линукс. Ставиться задача отлаживать одинокий софт максимально удобно, т.е. загрузкой JTAGом в SDRAM.

    Среда Keil, отладчик JetLink5.

     

    Рассуждения сейчас неполные, но изложу что есть:

     

    Чтобы грузить приложение JTAGом в SDRAM требуется его инициализировать, например из датафлэша.

    После загружаем образ JTAGом из кейла, при этом процессор все ещё будет бегать в инициализаторе из int.RAM (в финальном устройстве он разумеется будет передавать управление сам, а сейчас ему просто нечего грузить). Сейчас для передачи управления ничего умнее прописывания в PC адреса не вижу. ( лучше из командной строки дебагера при старте? сходу не получилось )

     

    Как поступать с ремапом? Инициализатор запустился с нулевого адреса, всё ок. Основная программа вышеуказанным способом с "нуля" не запустится, придётся линковать при отладке по месту.

     

    Как малой кровью построить отладку описанным халявным образом?

    Что в изучении процессора на этом этапе упустил?

  6. Передумал что то выкладывать, ибо порт сделан под урезанную версию процессора. Оно конечно пашет... Но в корне криво, тк OS Extesions актель ещё не оформил в своём релизе процессора и прерывания пока идут через единственный вектор.

    Тем не менее, если найдуться "эстэты" вроде меня, обращайтесь

  7. Изучаю на стартер ките от Actel данный процессор. Хочется ОС

    Документация у процессора не самая однозначная...

    Пишут, что когда случается прерывание (входит в спискок эксепшинов), процессор автоматически записывает в стек R0-R3, R12, LR, PC (для вовзрата), xPSR. ( Вроде как недо-сохранение контекста... Они предполагают что иные регистры в обработчике не должны использоваться? )

    По завершению эксепшина обещает из стека эти регистры восстановить.

     

    Возврат из эксепшина обеспечит компилятор?

    глядя на код в отладчике, не похоже. Не увидел там ображения к статус регистру. Может плохо глядел ...

     

    Статус регистр в документе CortexM1_HB.pdf (его даже ARM суёт как основной источник) не расписан, можно только предполагать как управляется режим процессора. Или я, опять же, плохо искал?

     

    Портирую FreeRTOS, среда Actel SoftConsole (судя по всему это подточенный Eclipse)

     

    Пока у меня явное недопонимание устройства, хотелось бы на экспериментах время сэкономить

  8. Переписываю интерфейсную программу устройства (свзяь через RS-232) под .NET

    В С++ сборке описан компонент, построенный на общих с устройством кодах протокола обмена (написанных на Си ).

    Кроме этого протокола существует ещё ряд общих интерфейсных алгоритмов. Поэтому крайне желательно их не переписывать.

    Так вот...

    При разборе принятых байтов процессинг протокола, когда получит соответствующий пакет вызывает присвоенный данному типа пакета обработчик (через указатель на обработчик). В данном обработчике происходит передача параметров пришедшего сообщения и вызов события компонента.

     

    При прохождении сообщения событие вызывается от лица null, то есть в Sender попадает null. При дебаге в этот момент this == null... Как это можно обойти\исправить, в чём искать затык?

     

    An unhandled exception of type 'System.NullReferenceException' occurred in comm_dll.dll
    
    Additional information: В экземпляре объекта не задана ссылка на объект.

     

    В .net совсем недавно, можно сказать почти никак

  9. Постановка вопроса с простыми "не" совершенное непонятна. Принципиально задачи с точки зрения системы все одинаковы по "сложности".

     

    Процессор сваливается в дАборт когда работает процесс, где имеется процедура с длительными (в маштабах периода цикла системы) вычислениями: плавающая запятая, тригонометрия, матричные операции. Признаки переполнения стека отсутствуют. Там нет даже никаких обращений к переферии, математика одна.

     

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

     

    Этот один не считается, ему всё можно и вроде не создаёт проблем... :)

     

    Как один из вариантов.

     

    По поводу "очередей".

    Тк пока я просто перестраиваю уже имеющуюся систему, то IPC пока идёт у меня напрямую через глобальные переменные. Не касаясь адекватности обработки данных, насколько безопасен такой подход?

     

    Поможет, если эти функции написаны праввильно в Вашем порте. В штатных, если мне память не изменяет, это работает на __disable/enable_interrupt, что дубово, но (если опять-таки обеспечена компенсация документированных багов работы с CPSR в части запрета прерываний)обеспечивает непрерываемость критической секции.

     

    Пока что в обрамлении критической секции у меня только отключение\включение прерываний. А можно по-подробнее про дубовость и баги ? :) В том же контексте ликбеза :)

     

    Сейчас я диагностировал у себя две проблемы: неадыкватная работа SPI в силу неясности работы ЧипСелектов (зацикливается в ожидании окончания передачи SPI), падение в датаАборт одной из процедур.

  10. Не имея опыта в портировании и построения системы на RTOS возникает ряд вопросов по безопасности.

    Портировал FreeRTOS на sam7s и кейл. С переключением контекстов вроде как разобрался, простые задачи переключаются, с непростыми пока проблемы.

     

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

     

    Проблема с одновременным доступом решается вроде как queue.

     

    CS ряда чипов на шине SPI работают программным ногодрыганием, все участки обращения по SPI короткие. Обращения может идти в задачах разных приоритетов. Поможет ли тут enter_CRITICAL, exit_CRITICAL от ситуаций когда несколько CS могут оказаться низкими?

     

    Проверял и судя по всему не спасает...

  11. Принципиально важно.

     

    Как это по уму организовать?

    Не входить в юзер мод вообще?

    Беглый взгяд на все порты арм7 говорит что там всё именно так.

    Или я не прав?

     

    Чем грозит такой подход в общем случае? (опять же, если я прав)

  12. Ситуация проясняется

    То что программа перескачила в ту область - чистое совпадение (см значение для R14)

    А вот почему в РС попадает значение этого поля, а не предыдущего ( ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE ) я понять не могу.

     

    portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )
    {
    portSTACK_TYPE *pxOriginalTOS;
    
        pxOriginalTOS = pxTopOfStack;
    
        /* Setup the initial stack of the task.  The stack is set exactly as 
        expected by the portRESTORE_CONTEXT() macro. */
    
        /* First on the stack is the return address - which in this case is the
        start of the task.  The offset is added to make the return address appear
        as it would within an IRQ ISR. */
        *pxTopOfStack = ( portSTACK_TYPE ) pxCode + portINSTRUCTION_SIZE;        
        pxTopOfStack--;
    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x00000000;    /* R14 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) pxOriginalTOS; /* Stack used when task starts goes in R13. */
        pxTopOfStack--;
        *pxTopOfStack = ( portSTACK_TYPE ) 0x12121212;    /* R12 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x11111111;    /* R11 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x10101010;    /* R10 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x09090909;    /* R9 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x08080808;    /* R8 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x07070707;    /* R7 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x06060606;    /* R6 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x05050505;    /* R5 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x04040404;    /* R4 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x03030303;    /* R3 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x02020202;    /* R2 */
        pxTopOfStack--;    
        *pxTopOfStack = ( portSTACK_TYPE ) 0x01010101;    /* R1 */
        pxTopOfStack--;    
    
        /* When the task starts is will expect to find the function parameter in
        R0. */
        *pxTopOfStack = ( portSTACK_TYPE ) pvParameters; /* R0 */
        pxTopOfStack--;
    
    
        *pxTopOfStack = ( portSTACK_TYPE ) portINITIAL_SPSR;
    
    
        *pxTopOfStack = portNO_CRITICAL_SECTION_NESTING;
    
        return pxTopOfStack;
    }

     

    Ответ здесь, но мои знания АСМа не позволяют воспринять.

     

         LDR        R1, =pxCurrentTCB
        LDR        R0, [R1]
        LDR        LR, [R0]
    
    ; The critical nesting depth is the first item on the stack.     
    ; Load it into the ulCriticalNesting variable.                     
        LDR        R0, =ulCriticalNesting
        LDMFD    LR!, {R1}
        STR        R1, [R0]
    
    ; Get the SPSR from the stack.                                     
        LDMFD    LR!, {R0}
        MSR        SPSR_cxsf, R0
    
    ; Restore all system mode registers for the task.                 
        LDMFD    LR, {R0-R14}^
        NOP
    
    ; Restore the return address.                                     
        LDR        LR, [LR, #+60]
    
    ; And return - correcting the offset in the LR to obtain the     
    ; correct address.                                                 
        SUBS    PC, LR, #4

     

    Насколько важно в момент первого "восстановления контекста" ещё незапущенной задачи иметь режим супервизора?

    В моём случае процессор лопатит всё в юзер мод, отсего, как я понимаю

    MSR SPSR_cxsf, R0

    эта команда статус регист не обновляет.

  13. Симулятор может и будет грешить, ибо его основная обязанность - симулировать ядро, а не периферию (как то контроллер прерываний, таймеры и прочую чепуху).

    Угу. А что в AIC_IMR?

     

    0x00000002

    От SYSIRQ еденичка

    как и должно быть, вроде как

  14. В симуляторе, ИМХО. Можете посмотреть в AIC_IPR, кто это прерывание (якобы) держит.

    В асмовский код я практически не вникал ( переносил его с IAR порта ) и пока что вообще мало вникал в низкоуровневый механизм ядра. Поэтому мало вериться что грешить в этом случае будет симулятор, ну это так, на уровне правды жизни :)

     

    Еденички AIC_IPR в мониторе AIC стоят на напротив:

    Fast External Int

    External Int 1

    External Int 2

    что вроде как галочками от юзера и определяется...

    но от их перестановки ничего не меняется

  15. Впервые для себя портирую ОС.

    Так как этой комбинации порта не прилагается, то с горем пополам собрал из имеющихся портов своё.

     

    static void prvSetupTimerInterrupt( void )
    {
    AT91PS_PITC pxPIT = AT91C_BASE_PITC;
    
            extern void ( vPortPreemptiveTick )( void );
        AT91F_AIC_ConfigureIt( AT91C_BASE_AIC, AT91C_ID_SYS, AT91C_AIC_PRIOR_HIGHEST, portINT_LEVEL_SENSITIVE, ( void (*)(void) ) vPortPreemptiveTick );
    
        pxPIT->PITC_PIMR = portPIT_ENABLE | portPIT_INT_ENABLE | portPIT_COUNTER_VALUE;
    
        AT91F_AIC_EnableIt( AT91C_BASE_AIC, AT91C_ID_SYS );
    }

     

    vPortPreemptiveTick
        portSAVE_CONTEXT        ; Save the context of the current task.
    
        LDR R0, =vTaskIncrementTick; Increment the tick count - this may wake a task.
        mov lr, pc
        BX R0
        LDR R0, =vTaskSwitchContext; Select the next task to execute.
        mov lr, pc
        BX R0
    
        LDR    R14, =AT91C_BASE_PITC; Clear the PIT interrupt
        LDR    R0, [R14, #PITC_PIVR ]
    
        LDR R14, =AT91C_BASE_AIC; Mark the End of Interrupt on the AIC
        STR    R14, [R14, #AIC_EOICR]
    
        portRESTORE_CONTEXT        ; Restore the context of the selected task.

     

    Запуск приложения

     

    static void vHW( void *pvParameters )
    {
        ( void ) pvParameters;
    
        for(;; )
        {
            var++;
        }
    }
    
    int main (void)
    {
        xTaskCreate(vHW, "Hi", 512, NULL, tskIDLE_PRIORITY + 1, NULL );
        vTaskStartScheduler();
    }

     

    При запуске в симуляторе Tick вызывается как и следует, всё остальное время выполнение висит на IRQ_Handler. В IdleTask дабагер не видит следов.

    Где искать проблему?

    Заранее спасибо!

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