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

Решил подправить пример freertos на lpc2129 под кейл-ом на сабжевый чип.

Втставил в родной startup.s часть касаюшуюся настроек тактирования, успешно пересобрал.

Запускаю дебагер, дебагер впадает в вечный цикл с ошибкой выбора инструкции по адресу 0xC ?!

Причем в оригинале, как полагается, после сброса в PC грузится 0х40.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вобщем, не понял почему в данном случае у симулятора крыша едет ... если переключить чип (на 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. */ \

}

Где то здесь все и встает :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Решил подправить пример freertos на lpc2129 под кейл-ом на сабжевый чип.

Втставил в родной startup.s часть касаюшуюся настроек тактирования, успешно пересобрал.

Запускаю дебагер, дебагер впадает в вечный цикл с ошибкой выбора инструкции по адресу 0xC ?!

Причем в оригинале, как полагается, после сброса в PC грузится 0х40.

Так поди ж, в том же дебагере при этом можно поглядеть регистры.

Например r14_abt, и локализовать место.

Можно тут почитать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Похоже что то с вычислением адреса возврата в portRESTORE_CONTEXT() макросе, если закоментарить последнюю строчку (__asm{ SUBS PC, LR, #4 }), то он завершается без зависонов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Похоже что собака зарылась в настройках контроллера прерываний.

Для начала я во freertos-ном обработчике прерывания вставил дрыгание IO пина, увидеть который так и не смог.

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

Дальше пошли варианты ... екперименты ... безрезультатно, обрабочики прерываний не вызываются (пробовал еще I2C).

Функции инициализации VIC и инсталляции обработчиков перетащил из своих рабочих примеров.

Странно, но в самой rtos я не нашел инициализации VIC.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Блин, уперся обеими рогами.

Никак немогу заставить работать прерывания.

Все облазил, даже доку прочитал :), не помогло.

Гляньте плиз на стартап, может что заметите.

В 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, и то что он устанавливается во всех режимах, как думаете насколько корректно убрать его из юзерского режима?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пока стартап форматировал обратил внимание на I_Bit, и то что он устанавливается во всех режимах, как думаете насколько корректно убрать его из юзерского режима?
Подумайте сами логично - Reset_Handler выполняется при старте процессора. Если вы уберете I_Bit, вы тем самым разрешите прерывания IRQ. То, что разрешение прерываний происходит до настройки VIC может и не приведет ни к чему плохому, но я бы не рискнул. Но кроме этого в обработчиках прерываний могут вызываться сервисы ОС, а в этот момент ОС еще не проинициализирована. Вот тут точно ничего хорошего не получится.

если закоментарить последнюю строчку (__asm{ SUBS PC, LR, #4 }), то он завершается без зависонов.
Вообще-то это ARMовский аналог reti. Интересно, если оно не висло, то куда же его уносило?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пока стартап форматировал обратил внимание на 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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

на мой вкус, по-хорошему, все надо делать после входа в main(). и инициализировать железо, и разрешать прерывания. дело стартапа - инициализация памяти

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а вот у freertos другие вкусы ...

да ладно ... думаю после старта какой-нибудь из задач наверное точно можно VIC-жаждущее железо инить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

а вот у freertos другие вкусы ...

да ладно ... думаю после старта какой-нибудь из задач наверное точно можно VIC-жаждущее железо инить.

ну я ваще-то все иничу перед стартом многозадачности, после входа в main(). вроде никаких проблем. так что насчет вкусов FreeRTOS я немного недопонял. а вот зависание, по-моему, происходит из-за разрешения прерывания до инициализации системы - у меня это было так, во всяком случае

Изменено пользователем sergik_vrn

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прерывания разрешаются, насколько я проникся, после инита всей системы. Например, имею I2C LCD, обмен которого осуществляется через прерывания, соответсвенно на ините этого LCD (если его вначале main включать) все и встанет.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

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