3.14 0 29 января, 2007 Опубликовано 29 января, 2007 · Жалоба Решил подправить пример freertos на lpc2129 под кейл-ом на сабжевый чип. Втставил в родной startup.s часть касаюшуюся настроек тактирования, успешно пересобрал. Запускаю дебагер, дебагер впадает в вечный цикл с ошибкой выбора инструкции по адресу 0xC ?! Причем в оригинале, как полагается, после сброса в PC грузится 0х40. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
3.14 0 29 января, 2007 Опубликовано 29 января, 2007 · Жалоба Вобщем, не понял почему в данном случае у симулятора крыша едет ... если переключить чип (на 2129) при тех же исходниках то стартап оживает ... Далее, главное в железе запускается. Ну как и следовало ожидать, ничего сходу не вышло, стал выяснять на каком месте встает. Успешно проходят функции: prvSetupHardware(); vStartIntegerMathTasks( tskIDLE_PRIORITY ); vAltStartComTestTasks( mainCOM_TEST_PRIORITY, mainCOM_TEST_BAUD_RATE, mainCOM_TEST_LED ); vStartLEDFlashTasks( mainLED_TASK_PRIORITY ); vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartDynamicPriorityTasks(); xTaskCreate( vErrorChecks, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); Далее входит в vTaskStartScheduler() в которой выполняется настройка таймера а после выполняется vPortISRStartFirstTask(). Так вот в это самой vPortISRStartFirstTask выполняется только один макрос (portRESTORE_CONTEXT()): #define portRESTORE_CONTEXT() \ { \ extern volatile unsigned portLONG ulCriticalNesting; \ extern volatile void * volatile pxCurrentTCB; \ \ __asm{ LDR R1, =pxCurrentTCB };/* Set the LR to the task stack. The location was ... */ \ __asm{ LDR R0, [R1] }; /* ... stored in pxCurrentTCB. */ \ __asm{ LDR LR, [R0] }; \ \ __asm{ LDR R0, =ulCriticalNesting }; /* The critical nesting depth is the first item on ... */ \ __asm{ LDMFD LR!, {R1 } } /* ... the stack. Load it into the ulCriticalNesting var. */ \ __asm{ STR R1, [R0] } \ \ __asm{ LDMFD LR!, {R0} }; /* Get the SPSR from the stack. */ \ __asm{ MSR SPSR_CXSF, R0 }; \ \ __asm{ LDMFD LR, {R0-R14}^ }; /* Restore all system mode registers for the task. */ \ __asm{ NOP }; \ \ __asm{ LDR LR, [LR, #+60] }; /* Restore the return address. */ \ \ /* And return - correcting the offset in the LR to obtain ... */ \ __asm{ SUBS PC, LR, #4 }; /* ... the correct address. */ \ } Где то здесь все и встает :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alex03 0 29 января, 2007 Опубликовано 29 января, 2007 · Жалоба Решил подправить пример freertos на lpc2129 под кейл-ом на сабжевый чип. Втставил в родной startup.s часть касаюшуюся настроек тактирования, успешно пересобрал. Запускаю дебагер, дебагер впадает в вечный цикл с ошибкой выбора инструкции по адресу 0xC ?! Причем в оригинале, как полагается, после сброса в PC грузится 0х40. Так поди ж, в том же дебагере при этом можно поглядеть регистры. Например r14_abt, и локализовать место. Можно тут почитать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
3.14 0 29 января, 2007 Опубликовано 29 января, 2007 · Жалоба Похоже что то с вычислением адреса возврата в portRESTORE_CONTEXT() макросе, если закоментарить последнюю строчку (__asm{ SUBS PC, LR, #4 }), то он завершается без зависонов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
3.14 0 30 января, 2007 Опубликовано 30 января, 2007 · Жалоба Похоже что собака зарылась в настройках контроллера прерываний. Для начала я во freertos-ном обработчике прерывания вставил дрыгание IO пина, увидеть который так и не смог. Потом создал свой обработчик таймера, в котором только пин IO дергается, обработчик не выполняется. Дальше пошли варианты ... екперименты ... безрезультатно, обрабочики прерываний не вызываются (пробовал еще I2C). Функции инициализации VIC и инсталляции обработчиков перетащил из своих рабочих примеров. Странно, но в самой rtos я не нашел инициализации VIC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
3.14 0 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба Блин, уперся обеими рогами. Никак немогу заставить работать прерывания. Все облазил, даже доку прочитал :), не помогло. Гляньте плиз на стартап, может что заметите. В main-е после инициализации железа ставлю вечный цикл. // *** Startup Code (executed after Reset) *** // Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs Mode_USR EQU 0x10 Mode_FIQ EQU 0x11 Mode_IRQ EQU 0x12 Mode_SVC EQU 0x13 Mode_ABT EQU 0x17 Mode_UND EQU 0x1B Mode_SYS EQU 0x1F I_Bit EQU 0x80 /* when I bit is set, IRQ is disabled */ F_Bit EQU 0x40 /* when F bit is set, FIQ is disabled */ /* // <h> Stack Configuration (Stack Sizes in Bytes) // <o0> Undefined Mode <0x0-0xFFFFFFFF> // <o1> Supervisor Mode <0x0-0xFFFFFFFF> // <o2> Abort Mode <0x0-0xFFFFFFFF> // <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF> // <o4> Interrupt Mode <0x0-0xFFFFFFFF> // <o5> User/System Mode <0x0-0xFFFFFFFF> // </h> */ UND_Stack_Size EQU 0x00000008 SVC_Stack_Size EQU 0x00000100; ABT_Stack_Size EQU 0x00000008 FIQ_Stack_Size EQU 0x00000100 IRQ_Stack_Size EQU 0x00000300 USR_Stack_Size EQU 0x00000200 AREA STACK, DATA, READWRITE, ALIGN=2 DS (USR_Stack_Size+3)&~3 ; Stack for User/System Mode DS (IRQ_Stack_Size+3)&~3 ; Stack for Interrupt Mode DS (FIQ_Stack_Size+3)&~3 ; Stack for Fast Interrupt Mode DS (ABT_Stack_Size+3)&~3 ; Stack for Abort Mode DS (SVC_Stack_Size+3)&~3 ; Stack for Supervisor Mode DS (UND_Stack_Size+3)&~3 ; Stack for Undefined Mode Top_Stack: // Starupt Code must be linked first at Address at which it expects to run. AREA STARTUPCODE, CODE, AT CODE_BASE // READONLY, ALIGN=4 PUBLIC __startup EXTERN CODE32 (?C?INIT) __startup PROC CODE32 // Pre-defined interrupt handlers that may be directly // overwritten by C interrupt functions EXTERN CODE32 (Undef_Handler?A) EXTERN CODE32 (vPortYieldProcessor?A) EXTERN CODE32 (PAbt_Handler?A) EXTERN CODE32 (DAbt_Handler?A) EXTERN CODE32 (IRQ_Handler?A) EXTERN CODE32 (FIQ_Handler?A) // Exception Vectors // Mapped to Address 0. // Absolute addressing mode must be used. Vectors: LDR PC,Reset_Addr LDR PC,Undef_Addr LDR PC,SWI_Addr LDR PC,PAbt_Addr LDR PC,DAbt_Addr ; NOP /* Reserved Vector */ DD 0xB9205F80 ; LDR PC,IRQ_Addr ; LDR PC,[PC, #-0x0FF0] /* Vector from VicVectAddr */ LDR PC,[PC, #-0x0120] /* Vector from VicVectAddr */ LDR PC,FIQ_Addr Reset_Addr: DD Reset_Handler Undef_Addr: DD Undef_Handler?A SWI_Addr: DD vPortYieldProcessor?A PAbt_Addr: DD PAbt_Handler?A DAbt_Addr: DD DAbt_Handler?A DD 0xB9205F80 /* Reserved Address */ IRQ_Addr: DD IRQ_Handler?A FIQ_Addr: DD FIQ_Handler?A Reset_Handler: // Setup Stack for each mode LDR R0, =Top_Stack // Enter Undefined Instruction Mode and set its Stack Pointer MSR CPSR_c, #Mode_UND|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #UND_Stack_Size // Enter Abort Mode and set its Stack Pointer MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #ABT_Stack_Size // Enter FIQ Mode and set its Stack Pointer MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #FIQ_Stack_Size // Enter IRQ Mode and set its Stack Pointer MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #IRQ_Stack_Size // Enter Supervisor Mode and set its Stack Pointer MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit MOV SP, R0 SUB R0, R0, #SVC_Stack_Size // Enter S Mode and set its Stack Pointer MSR CPSR_c, #Mode_SYS MOV SP, R0 // Start in supervisor mode MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit // Enter the C code LDR R0,=?C?INIT TST R0,#1 ; Bit-0 set: INIT is Thumb LDREQ LR,=exit?A ; ARM Mode LDRNE LR,=exit?T ; Thumb Mode BX R0 ENDP PUBLIC exit?A exit?A PROC CODE32 B exit?A ENDP PUBLIC exit?T exit?T PROC CODE16 exit: B exit?T ENDP END А-а-а вот она зараза-а ... Пока стартап форматировал обратил внимание на I_Bit, и то что он устанавливается во всех режимах, как думаете насколько корректно убрать его из юзерского режима? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба Пока стартап форматировал обратил внимание на I_Bit, и то что он устанавливается во всех режимах, как думаете насколько корректно убрать его из юзерского режима?Подумайте сами логично - Reset_Handler выполняется при старте процессора. Если вы уберете I_Bit, вы тем самым разрешите прерывания IRQ. То, что разрешение прерываний происходит до настройки VIC может и не приведет ни к чему плохому, но я бы не рискнул. Но кроме этого в обработчиках прерываний могут вызываться сервисы ОС, а в этот момент ОС еще не проинициализирована. Вот тут точно ничего хорошего не получится. если закоментарить последнюю строчку (__asm{ SUBS PC, LR, #4 }), то он завершается без зависонов. Вообще-то это ARMовский аналог reti. Интересно, если оно не висло, то куда же его уносило? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба Пока стартап форматировал обратил внимание на I_Bit, и то что он устанавливается во всех режимах, как думаете насколько корректно убрать его из юзерского режима?Подумайте сами логично - Reset_Handler выполняется при старте процессора. Если вы уберете I_Bit, вы тем самым разрешите прерывания IRQ. То, что разрешение прерываний происходит до настройки VIC может и не приведет ни к чему плохому, но я бы не рискнул. Но кроме этого в обработчиках прерываний могут вызываться сервисы ОС, а в этот момент ОС еще не проинициализирована. Вот тут точно ничего хорошего не получится. если закоментарить последнюю строчку (__asm{ SUBS PC, LR, #4 }), то он завершается без зависонов. Вообще-то это ARMовский аналог reti. Интересно, если оно не висло, то куда же его уносило? позволю себе поделиться опытом, не уверен, правда, что это тот случай, к тому же, по причине не очень хорошего владения армовским ассемблером, в деталях ситуации мне разобраться не удалось. и тем не менее - когда я занимался запуском FreeRTOS на STR710, параллельно начиная изучать АРМы, у меня возникала ситуация, подобная описанной. правда, зависание происходило во время засгрузки стартапа, до входа в main() - во всяком случае, в отладчике я туда не попадал. поскльку я на тот момент вообще никак не разбирался в процессоре, пошел наиболее легким путем, а именно, попытался адаптировать готовый проект (из примеров к FreeRTOS). как выяснилось, если заменить 71x_init.s и 71x_vect.s из комплекта ИАР на cstartup.s79 и vect.s79 из примера, после некоторой адаптации система начинает стартовать нормально. собственно, на тот момент я этим и ограничился. а недавно, когда взялся делать bootload для своего проекта, попутно пришлось более детально разбираться в алгоритме запуска АРМ. в частности, мне пришлось снова вернуться к упомянутым ассемблерным файлам - ибо после пуска процесора бутлоадер работал нормально, но после перехода на точку запуска программы снова возникла упомянутая ситуация. я поступил просто - перекинул в проект бутлоадера проверенные стартап-файлы. и все опять стало нормально. ну естественно, разобрало меня любопытство - и вот что я обнаружил при сравнении кода: в 71x_init.s по окончании инициализации проект переводится в режим пользователя MSR CPSR_c, #Mode_USR ; Change to User mode, Enable IRQ and FIQ LDR SP, =SFE(CSTACK) & 0xFFFFFFF8 ; Initialize USR stack pointer в то время, как в моем cstartup.s79 - в режим супервизора /* We want to start in supervisor mode. Operation will switch to system mode when the first task starts. */ msr CPSR_c, #Mode_SVC|I_Bit|F_Bit кроме того, немного по-разному инициализируются стеки, впрочем, тут моих знаний не хватило. если интересно, могу показать работающий код инициализации Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
3.14 0 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба Вроде сдвинулся с мертвой точки, оказалось все дело в объявлении вектора обработчика прерывания для таймера, сейчас вроде работает. Все кастрации инициализации VIC я вернул на место, всвязи с чем возникает вопрос, а где тогда правильнее инициализировать железо работающее на прерываниях? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба Вроде сдвинулся с мертвой точки, оказалось все дело в объявлении вектора обработчика прерывания для таймера, сейчас вроде работает. Все кастрации инициализации VIC я вернул на место, всвязи с чем возникает вопрос, а где тогда правильнее инициализировать железо работающее на прерываниях? на мой вкус, по-хорошему, все надо делать после входа в main(). и инициализировать железо, и разрешать прерывания. дело стартапа - инициализация памяти Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
3.14 0 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба а вот у freertos другие вкусы ... да ладно ... думаю после старта какой-нибудь из задач наверное точно можно VIC-жаждущее железо инить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 1 февраля, 2007 Опубликовано 1 февраля, 2007 (изменено) · Жалоба а вот у freertos другие вкусы ... да ладно ... думаю после старта какой-нибудь из задач наверное точно можно VIC-жаждущее железо инить. ну я ваще-то все иничу перед стартом многозадачности, после входа в main(). вроде никаких проблем. так что насчет вкусов FreeRTOS я немного недопонял. а вот зависание, по-моему, происходит из-за разрешения прерывания до инициализации системы - у меня это было так, во всяком случае Изменено 1 февраля, 2007 пользователем sergik_vrn Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
3.14 0 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergik_vrn 0 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет. а, ну это разумеется, да. что, кстати, неудобно - приходится инициализацию делать уже в многозадачном режиме, то есть через задницу Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 1 февраля, 2007 Опубликовано 1 февраля, 2007 · Жалоба а вот у freertos другие вкусы ... Что-то странное глаголите :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться