|
|
|
TEventFlag.Signal_isr() |
|
|
|
Jan 23 2017, 17:15
|
Частый гость
Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991
|
Да, не видно. То, что удалось словить, - это уже следствие. Ближе я пока что не подобрался. Поэтому и спрашиваю многоуважаемое сообщество, как можно заглянуть поглубже. Банальная точка останова на коде, который вызывается из множества мест, не поможет. Городить средства профилировки? Сложно и можно испортить что-то ещё, появятся артефакты, с которыми тоже придётся повоевать.
Может, у кого есть уже опробованное средство, а?
|
|
|
|
|
Jan 23 2017, 19:31
|
Частый гость
Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991
|
Простите, не понял сразу. CODE PendSV_Handler
#if defined __ARM_ARCH_6M__ // Cortex-M0(+)/Cortex-M1 CPSID I // Prevent interruption during context switch MRS R0, PSP // Load process stack pointer to R0 SUBS R0, R0, #32 // Adjust R0 to point to top of saved context in stack MOV R1, R0 // Preserve R0 (needed for os_context_switch_hook() call) STMIA R1!, {R4-R7} // Save low portion of remaining registers (r4-7) on process stack MOV R4, R8 // Move high portion of remaining registers (r8-11) to low registers MOV R5, R9 MOV R6, R10 MOV R7, R11 STMIA R1!, {R4-R7} // Save high portion of remaining registers (r8-11) on process stack
// At this point, entire context of process has been saved PUSH {LR} // we must save LR (exc_return value) until exception return LDR R1, =os_context_switch_hook // call os_context_switch_hook(); BLX R1
// R0 is new process SP; ADDS R0, R0, #16 // Adjust R0 to point to high registers (r8-11) LDMIA R0!, {R4-R7} // Restore r8-11 from new process stack MOV R8, R4 // Move restored values to high registers (r8-11) MOV R9, R5 MOV R10, R6 MOV R11, R7 MSR PSP, R0 // R0 at this point is new process SP SUBS R0, R0, #32 // Adjust R0 to point to low registers LDMIA R0!, {R4-R7} // Restore r4-7 CPSIE I POP {PC} // Return to saved exc_return. Exception return will restore remaining context
#else
Если есть необходимость, могу загрузить проект. Но Вы под IAR-ом не работаете. Для визуального контроля границ стеков процессов добавил в функцию TBaseProcess::init_stack_frame возможность записи заголовков в формате "ProcXX". Хорошо видно тогда в дампе памяти дно стека. Если затёрт заголовок полностью - хана, стек закончился! А выглядит это так: или вот так: Код функции: CODE //------------------------------------------------------------------------------ void TBaseProcess::init_stack_frame( stack_item_t * Stack , void (*exec)() #if scmRTOS_DEBUG_ENABLE == 1 , stack_item_t * StackBegin #endif ) { // ARM Architecture Procedure Call Standard [AAPCS] requires 8-byte stack alignment: StackPointer = (stack_item_t*)((uintptr_t)Stack & 0xFFFFFFF8); // Prepare Process Stack Frame. *(--StackPointer) = 0x01000000UL; // xPSR *(--StackPointer) = reinterpret_cast<uint32_t>(exec); // Entry Point StackPointer -= 14; // emulate "push R14,R12,R3,R2,R1,R0,R11-R4"
#if scmRTOS_DEBUG_ENABLE == 1 for (stack_item_t* pDst = StackBegin; pDst < StackPointer; ++pDst) *pDst = STACK_DEFAULT_PATTERN; stack_item_t* pDst = StackBegin; *pDst++ = 0x636f7250; int a = this->priority()& 0x0000003F; if (a == prIDLE) { *pDst = 0x454c4449; return; } #if scmRTOS_PRIORITY_ORDER > 0 a = scmRTOS_PROCESS_COUNT - a; #endif int b = 48; while (a>10) { b++; a -= 10; } b += (a+48)<<8; *pDst = b; #endif // scmRTOS_DEBUG_ENABLE }
Эту фичу можно включить с помощью макроса scmRTOS_DEBUG_ENABLE
|
|
|
|
|
Jan 23 2017, 20:23
|
Частый гость
Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991
|
Вот приоритеты: CODE //----------------------------------------------------------------------------- // EQUATES // NVIC_SYSPRI14 EQU 0xE000ED22 // System priority register (priority 14). NVIC_PENDSV_PRI EQU 0xFF // PendSV priority value (lowest). NVIC_SYSPRI15 EQU 0xE000ED23 // System priority register (priority 15). NVIC_ST_PRI EQU 0xFF // SysTick priority value (lowest).
NVIC_ST_CTRL EQU 0xE000E010 // SysTick Ctrl & Status Reg. NVIC_ST_RELOAD EQU 0xE000E014 // SysTick Reload Value Reg. NVIC_ST_CTRL_CLK_SRC EQU 0x00000004 // Clock Source. NVIC_ST_CTRL_INTEN EQU 0x00000002 // Interrupt enable. NVIC_ST_CTRL_ENABLE EQU 0x00000001 // Counter mode.
Присваивание приоритетов: CODE //----------------------------------------------------------------------------- // Perform systick timer initialization. // init_system_timer LDR R1, =NVIC_SYSPRI15 // Set the SysTick exception priority (lowest) LDR R2, =NVIC_ST_PRI STRB R2, [R1] LDR R1, =NVIC_ST_RELOAD // Setup SysTick LDR R2, =(SYSTICKFREQ/SYSTICKINTRATE-1) STR R2, [R1] LDR R1, =NVIC_ST_CTRL // Enable and run SysTick LDR R2, =(NVIC_ST_CTRL_CLK_SRC | NVIC_ST_CTRL_INTEN | NVIC_ST_CTRL_ENABLE) STR R2, [R1] BX LR //----------------------------------------------------------------------------- // START MULTITASKING // void os_start(stack_item_t* sp) // // Note(s) : 1) os_start() MUST: // a) Setup PendSVexception priority to lowest; // Setup system timer (exception priority and reload value); // c) Enable interrupts (tasks will run with interrupts enabled). // d) Jump to exec() function of the highest priority process. // os_start LDR R1, =NVIC_SYSPRI14 // Set the PendSV exception priority (lowest) LDR R2, =NVIC_PENDSV_PRI STRB R2, [R1] #ifdef __SOFTFP__ LDR R4, [R0, #(4 * 14)] // Load process entry point into R3 ADDS R0, R0, #(4 * 16) // emulate context restore #else LDR R4, [R0, #(4 * 15)] ADDS R0, R0, #(4 * 16) #endif MSR PSP, R0 // store process SP to PSP MOVS R0, #2 // Switch thread mode stack to PSP MSR CONTROL, R0 ISB // Insert a barrier #if USE_SYSTICK_TIMER != 0 LDR R1, =init_system_timer // Init and run system timer BLX R1 #endif CPSIE I // Enable interrupts at processor level BX R4 // Jump to process exec() function
|
|
|
|
|
Jan 28 2017, 20:43
|
Частый гость
Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991
|
Только сегодня добрался до проекта. Работа, однако! Итак, дело действительно было в приоритетах и только в приоритетах. Я их поправил и всё заиграло! И вот что я сделал по-быстрому: 1. Назначил константы регистров и констант приоритетов: CODE #if defined __ARM_ARCH_6M__ // Cortex-M0(+)/Cortex-M1 NVIC_SYSPRI14 EQU 0xE000ED20 // System priority register (priority 12..15). NVIC_PENDSV_PRI EQU 0x00C00000 // PendSV priority value (lowest) NVIC_SYSPRI15 EQU 0xE000ED20 // System priority register (priority 12..15). NVIC_ST_PRI EQU 0xC0000000 // SysTick priority value (lowest) #else NVIC_SYSPRI14 EQU 0xE000ED22 // System priority register (priority 14). NVIC_PENDSV_PRI EQU 0xFF // PendSV priority value (lowest). NVIC_SYSPRI15 EQU 0xE000ED23 // System priority register (priority 15). NVIC_ST_PRI EQU 0xFF // SysTick priority value (lowest). #endif
NVIC_ST_CTRL EQU 0xE000E010 // SysTick Ctrl & Status Reg. NVIC_ST_RELOAD EQU 0xE000E014 // SysTick Reload Value Reg. NVIC_ST_CTRL_CLK_SRC EQU 0x00000004 // Clock Source. NVIC_ST_CTRL_INTEN EQU 0x00000002 // Interrupt enable. NVIC_ST_CTRL_ENABLE EQU 0x00000001 // Counter mode.
2. Поправил загрузку приоритета PendSV в os_start: CODE os_start #if defined __ARM_ARCH_6M__ // Cortex-M0(+)/Cortex-M1 LDR R1, =NVIC_SYSPRI14 // Set the SysTick exception priority (lowest) LDR R2, =NVIC_PENDSV_PRI LDR R3, [R1] ADD R2, R3 STR R2, [R1] #else LDR R1, =NVIC_SYSPRI14 // Set the PendSV exception priority (lowest) LDR R2, =NVIC_PENDSV_PRI STRB R2, [R1] #endif
3. Поправил загрузку приоритета SysTick в init_system_timer: CODE init_system_timer #if defined __ARM_ARCH_6M__ // Cortex-M0(+)/Cortex-M1 LDR R1, =NVIC_SYSPRI15 // Set the SysTick exception priority (lowest) LDR R2, =NVIC_ST_PRI LDR R3, [R1] ADD R2, R3 STR R2, [R1] #else LDR R1, =NVIC_SYSPRI15 // Set the SysTick exception priority (lowest) LDR R2, =NVIC_ST_PRI STRB R2, [R1] #endif
Всем спасибо! PS Хотел сделать по-красивому, как для mx-gcc, но не пошла строчка: CODE " LDR R1, =os_context_switch_hook \n" // call os_context_switch_hook();
Как сделать видимой для IAR-овского встроенного ассемблера адрес функции из другого модуля?
|
|
|
|
|
Jan 28 2017, 20:56
|
фанат дивана
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684
|
Цитата(SergNK @ Jan 29 2017, 01:43) Как сделать видимой для IAR-овского встроенного ассемблера адрес функции из другого модуля? Код EXTERN os_context_switch_hook По крайней мере, в порте для M3 так.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Jan 28 2017, 21:31
|
Частый гость
Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991
|
Цитата(AHTOXA @ Jan 28 2017, 23:56) Код EXTERN os_context_switch_hook По крайней мере, в порте для M3 так. Это определение для файла "*.s", т.е. чисто ассемблерное.
|
|
|
|
|
Jan 30 2017, 13:44
|
Профессионал
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877
|
Цитата(SergNK @ Jan 28 2017, 23:43) Как сделать видимой для IAR-овского встроенного ассемблера адрес функции из другого модуля? Или я не понял вопрос, или Вам нужен EXTERN. Как оно работает, можно подсмотреть в любом другом ассемблерном модуле (например, в штатном стартапе). UPD. Перечитал ещё раз. Да, вопрос я не понял. Тут инлайн ассемблер (с какими-то своими правилами). Извиняюсь...
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Feb 6 2017, 19:18
|
Частый гость
Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991
|
Удалось-таки победить. Вот что вышло: Это обработчик прерывания для среды IAR: CODE extern "C" void PendSV_Handler() { #if (defined __ARM_ARCH_6M__) // Cortex-M0(+)/Cortex-M1 asm volatile ( " CPSID I \n" // Prevent interruption during context switch " MRS R0, PSP \n" // Load process stack pointer to R0 " SUBS R0, R0, #32 \n" // Adjust R0 to point to top of saved context in stack " MOV R1, R0 \n" // Preserve R0 " MOV R2, R0 \n" // Preserve R0 (needed for os_context_switch_hook() call) " STMIA R1!, {R4-R7} \n" // Save low portion of remaining registers (r4-7) on process stack " MOV R4, R8 \n" // Move high portion of remaining registers (r8-11) to low registers " MOV R5, R9 \n" " MOV R6, R10 \n" " MOV R7, R11 \n" " STMIA R1!, {R4-R7} \n" // Save high portion of remaining registers (r8-11) on process stack : : ); asm volatile ( // At this point, entire context of process has been saved " PUSH {LR} \n" // we must save LR (exc_return value) until exception return " MOV R1, %0 \n" // load os_context_switch_hook() address; " MOV R0, R2 \n" // Restore R0 (needed for os_context_switch_hook() call) " BLX R1 \n" // call os_context_switch_hook(); // R0 is new process SP; " ADDS R0, R0, #16 \n" // Adjust R0 to point to high registers (r8-11) " LDMIA R0!, {R4-R7} \n" // Restore r8-11 from new process stack " MOV R8, R4 \n" // Move restored values to high registers (r8-11) " MOV R9, R5 \n" " MOV R10, R6 \n" " MOV R11, R7 \n" " MSR PSP, R0 \n" // R0 at this point is new process SP " SUBs R0, R0, #32 \n" // Adjust R0 to point to low registers " LDMIA R0!, {R4-R7} \n" // Restore r4-7 " CPSIE I \n" " POP {PC} \n" // Return to saved exc_return. Exception return will restore remaining context : : "r" (os_context_switch_hook) ); #else // #if (defined __ARM_ARCH_6M__)
#if (defined __SOFTFP__) // M3/M4 cores without FPU asm volatile ( " CPSID I \n" // Prevent interruption during context switch " MRS R0, PSP \n" // PSP is process stack pointer " STMDB R0!, {R4-R11} \n" // Save remaining regs r4-11 on process stack
// At this point, entire context of process has been saved " PUSH {LR} \n" // we must save LR (exc_return value) until exception return " LDR R1, =os_context_switch_hook \n" // call os_context_switch_hook(); " BLX R1 \n"
// R0 is new process SP; " LDMIA R0!, {R4-R11} \n" // Restore r4-11 from new process stack " MSR PSP, R0 \n" // Load PSP with new process SP " CPSIE I \n" " POP {PC} \n" // Return to saved exc_return. Exception return will restore remaining context : : );
#else // #if (defined __SOFTFP__) // Core with FPU (cortex-M4F) asm volatile ( " CPSID I \n" // Prevent interruption during context switch " MRS R0, PSP \n" // PSP is process stack pointer " TST LR, #0x10 \n" // exc_return[4]=0? (it means that current process " IT EQ \n" // has active floating point context) " VSTMDBEQ R0!, {S16-S31} \n" // if so - save it. " STMDB R0!, {R4-R11, LR} \n" // save remaining regs r4-11 and LR on process stack
// At this point, entire context of process has been saved " LDR R1, =os_context_switch_hook \n" // call os_context_switch_hook(); " BLX R1 \n"
// R0 is new process SP; " LDMIA R0!, {R4-R11, LR} \n" // Restore r4-11 and LR from new process stack " TST LR, #0x10 \n" // exc_return[4]=0? (it means that new process " IT EQ \n" // has active floating point context) " VLDMIAEQ R0!, {S16-S31} \n" // if so - restore it. " MSR PSP, R0 \n" // Load PSP with new process SP " CPSIE I \n" " BX LR \n" // Return to saved exc_return. Exception return will restore remaining context : : ); #endif // #if (defined __SOFTFP__) #endif // #if (defined __ARM_ARCH_6M__) }
А это функция старта оси, также для среды IAR: CODE extern "C" NORETURN void os_start(stack_item_t *sp) { // Set PendSV lowest priority value #if (defined SHP3_WORD_ACCESS) SHPR3 |= (0xFF << 16); #else PendSvPriority = 0xFF; #endif
#if (!defined __SOFTFP__) FPCCR |= ASPEN | LSPEN; #endif
asm volatile ( #if (defined __SOFTFP__) // code without FPU " LDR R4, [%[stack], #(4 * 14)] \n" // Load process entry point into R4 " ADDS %[stack], #(4 * 16) \n" // emulate context restore #else " LDR R4, [%[stack], #(4 * 15)] \n" // Load process entry point into R4 " ADD %[stack], #(4 * 17) \n" // emulate context restore #endif " MSR PSP, %[stack] \n" // store process SP to PSP " MOVS R0, #2 \n" // set up the current (thread) mode: use PSP as stack pointer, privileged level " MSR CONTROL, R0 \n" " ISB \n" // Insert a barrier : [stack]"+r" (sp) // output ); asm volatile ( " MOV R1, %0 \n" // Init and run system timer " BLX R1 \n" // " CPSIE I \n" // Enable interrupts at processor level " BX R4 \n" // Jump to process exec() function : :"r" (__init_system_timer) // output ); }
В результате я перенёс некоторые функции, приведя в соответствие с версией для GCC и избавился от файла os_target_asm.s
|
|
|
|
|
Feb 7 2017, 07:44
|
Adept
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343
|
QUOTE (SergNK @ Feb 7 2017, 14:28) Можно. Я отладил код под Freescale M0+. Подчистить исходники по комментариям и отступам - и вперёд! Куда сбрасывать и как? Два варианта. Первый (предпочтительный). Пререквизиты (что требуется от вас): 1. Какое-то умение работать с git. 2. Аккаунт на гитхабе. 3. Желание/готовность участвовать в проекте - сопровождать этот порт и не только. В этом случае получаете доступ к репозиторию на гитхабе (включаем вас в команду), далее в соответствии с этим документом вносите свои правки и фиксируете. Я не знаю, насколько вам близок git, но если будут возникать затруднения, мы (с Антоном) всегда готовы помочь. Второй (простой). Если по какой-то причине первый вариант не подходит, то можете выложить архив с портом (и желательно примерами) где вам удобно (например, яндекс диск или любой другой файлообменник). Дальше мы сами добавим порт в репозиторий. Ваш выбор.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|