Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: TEventFlag.Signal_isr()
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > scmRTOS
abutorin
Доброго времени суток.
Пробую использовать TEventFlag для оповещения основного цикла программы о завершении передачи даннных через SPI на STM32F103. В основном цикле очищаю флаг события, записываю данные в регистр, начинаю ждать событие. В обработчике прерывания взвожу флаг события методом signal_isr. Все работает, но остается одна проблема, процесс ожидающий этого события пробуждается только после следующего планирования процессов по системному таймеру, т.е. только примерно через 1мс. Мне казалось что такой задержки быть не должно. Я что-то делаю не так, или непонимаю как это должно работать. Подскажите кто чем может.
DmitryM
Цитата(abutorin @ Mar 9 2015, 00:06) *
Доброго времени суток.
Пробую использовать TEventFlag для оповещения основного цикла программы о завершении передачи даннных через SPI на STM32F103. В основном цикле очищаю флаг события, записываю данные в регистр, начинаю ждать событие. В обработчике прерывания взвожу флаг события методом signal_isr. Все работает, но остается одна проблема, процесс ожидающий этого события пробуждается только после следующего планирования процессов по системному таймеру, т.е. только примерно через 1мс. Мне казалось что такой задержки быть не должно. Я что-то делаю не так, или непонимаю как это должно работать. Подскажите кто чем может.

Каким образом ожидаете событие? TEventFlag.wait()?
Сергей Борщ
Цитата(abutorin @ Mar 8 2015, 23:06) *
Подскажите кто чем может.
В обработчике прерывания создается объект класса TISRW_SS?
abutorin
Цитата(Сергей Борщ @ Mar 9 2015, 09:45) *
В обработчике прерывания создается объект класса TISRW_SS?

Создается объект TISRW. Как я понял для Cortex-M3 можно использовать его.
Цитата
Каким образом ожидаете событие? TEventFlag.wait()?

Да, именно так.
Вот код:
Код
OS::TEventFlag SPIRE_Event;
uint8_t SPI_data;

OS_INTERRUPT void SPI2_IRQHandler(void)
{
    OS::TISRW TISRW_O;
    if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
    {

        SPI_I2S_ClearITPendingBit(SPI2,SPI_I2S_IT_RXNE); //эта строка необязательна
        SPI_data = SPI_I2S_ReceiveData(SPI2);
        SPIRE_Event.signal_isr();
    }
}

int8_t ReadWrite(uint8_t data)
    {
        /* Loop while DR register in not emplty */
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

        /* Send byte through the SPI1 peripheral */
        SPI_I2S_SendData(SPI2, data);

        SPIRE_Event.wait();
        SPIRE_Event.clear();
        return SPI_data;
    }


Обработчик прерывания включен только для события RXNE.
Сергей Борщ
Цитата(abutorin @ Mar 9 2015, 11:14) *
Создается объект TISRW. Как я понял для Cortex-M3 можно использовать его.
Все верно. Должно работать. В деструкторе этого объекта взводится запрос перывания PendSVC. После выхода из текущего прерывания должен вызваться обработчик PendSVC, в котором собственно и должна произойти перепланировка. Причем с системным тиком механизм идентичный, а симптомы один-в-один напоминают забытый TISRW.
abutorin
Цитата(Сергей Борщ @ Mar 9 2015, 13:10) *
Все верно. Должно работать. В деструкторе этого объекта взводится запрос перывания PendSVC. После выхода из текущего прерывания должен вызваться обработчик PendSVC, в котором собственно и должна произойти перепланировка. Причем с системным тиком механизм идентичный, а симптомы один-в-один напоминают забытый TISRW.


Похоже я где-то что-то напутал. Сейчас еще раз проверил, и все работает корректно. Видимо я не ту прошивку в железо залил. Спасибо за ответы.
SergNK
Доброго дня!

Решил поднять тему вот таким вопросом.
Создаю ПО под Freescale M0+ с использованием scmRTOS. Четыре процесса:
CODE
typedef OS::process<OS::pr0, 512> TProc1;
typedef OS::process<OS::pr1, 512> TProc2;
typedef OS::process<OS::pr2, 512> I2C0_TASK;
typedef OS::process<OS::pr3, 1024> TBackgroundProc;

Есть прерывания:
CODE
TRTC rtc;
OS_INTERRUPT void RTC_second_Handler()
{
OS::TISRW TISRW_O;
rtc.RtcSecondIrqHandler();
OneSecondFlag.signal_isr();
}

Устанавливаю флаг в прерывании и ловлю его в процессе TProc1:
CODE
template<> OS_PROCESS void TProc1::exec()
{
for(;;)
{
OneSecondFlag.wait();
// while (!rtc.getNewSecondFlag());
led_bl.Cpl();
sleep(5);

}
}

Вылетает по HardFault. Если закомментировать OneSecondFlag.signal_isr(); то не вылетает. Ковыряюсь уже довольно долго. Накопал, что при восстановлении контекстов из критических секций происходит лишнее действие, которое затирает правильно восстановленный контекст.
Если использовать флаг rtc.getNewSecondFlag(), вызываемый из объекта, то всё ОК.
Куда копать?

Вдогонку:

Вылетает при выполнении кода:
CODE
bool OS::TEventFlag::wait(timeout_t timeout)
{
TCritSect cs;

if(Value) // if flag already signaled
{
Value = efOff; // clear flag
return true;
}
else
{
cur_proc_timeout() = timeout;

suspend(ProcessMap);

if(is_timeouted(ProcessMap))
return false; // waked up by timeout or by externals

cur_proc_timeout() = 0; <== вылетает при попытке выполнить эту инструкцию - обращение к несуществующей памяти
return true; // otherwise waked up by signal() or signal_isr()
}
}
Сергей Борщ
QUOTE (SergNK @ Jan 18 2017, 13:23) *
Вылетает при выполнении кода:

Смотрим, во что выливается этот код:
CODE
Kernel.ProcessTable[Kernel.CurProcPriority]->Timeout = 0;
Давайте начнем с того, чему равен Kernel.CurProcPriority до вызова wait() и перед падением. Потом посмотрим, куда указывает ProcessTable[Kernel.CurProcPriority]. И дальше надо искать, кто портит одну из этих переменных.
SergNK
Ща попробую

Контекст портится после suspend(ProcessMap);
Я поставил точку останова на if(is_timeouted(ProcessMap)), а там уже запорчено.
Я так понимаю: suspend останавливает процесс, а потом перепланировщик его возобновляет. И при восстановлении контекста что-то происходит.
SergNK
Словил за хвост эту проблему. Словами или кодом описывать тяжеловато, поэтому сделал скриншоты практически пошагового прохождения.

Из-за большого объёма топика всё спрятал в прикреплённом файле.

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

В связи с этим подскажите, как исследовать эту часть так, чтобы можно было в режиме реального времени обнаружить источник. Пошаговое прохождение не приводит к фатальному исходу. Можно ухитриться словить только хвост проблемы, да и то самый кончик. Я это выложил в виде скриншотов.

Когда-то код, связанный с перепланировкой, наверняка подвергался отладке, иначе в руководстве не уделяли подробному описанию проблемы, которая очень похожа на эту.
Либо как вариант использовать планировщик с прямой передачей управления.
AHTOXA
Извините за банальность, но не пробовали ли вы выключить и снова включить увеличить стеки задач?
И нет ли у вас какого-нибудь ещё прерывания, которое может портить память?
SergNK
Это было сделано в первую очередь. Я не новичок в осях и понимаю подводность камней. Лет 10 назад починил PicOS18. Там при определённых условиях стек Idle восстанавливался не полностью, из-за чего происходило переполнение стеков. Тяжёлая ошибка.
AHTOXA
Не обижайтесь, но раз вы этого явно не написали, кто-то должен был спросить sm.gif
Ещё банальный вопрос: укажите использованную версию оси, и используемый компилятор.
SergNK
scmRTOS v5.1
IAR 7.70
Windows 10
AHTOXA
Понятно. Свой порт под IAR для M0+?

Давайте теперь по ходу процесса. Скриншот 1. - Это же выход из прерывания RTC_Second_Handler()? Если так, то перепланировка ещё не произошла, а только запланирована (взведён флаг прерывания PendSV). Так что никакой порчи регистров в этом месте ещё нет.
После выхода из прерывания вы попадаете в sched(), который как раз и должен дождаться срабатывания прерывания PendSV и собственно перепланировки.
А этого как раз в вашем расследовании и не видно.
SergNK
Да, не видно. То, что удалось словить, - это уже следствие. Ближе я пока что не подобрался. Поэтому и спрашиваю многоуважаемое сообщество, как можно заглянуть поглубже.
Банальная точка останова на коде, который вызывается из множества мест, не поможет.
Городить средства профилировки? Сложно и можно испортить что-то ещё, появятся артефакты, с которыми тоже придётся повоевать.

Может, у кого есть уже опробованное средство, а?
AHTOXA
Вы не ответили про порт. Что за порт? Покажите код PendSV_Handler, хотя бы.
SergNK
Простите, не понял сразу.

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
AHTOXA
С обработчиком порядок, он один-в-один как в порте GCC. Ещё посмотрите приоритеты прерываний. Прерывание PendSV должно иметь минимальный приоритет.
На всякий случай, если есть возможность, попробуйте собрать проект другой версией IAR, или поменять уровень оптимизации.
Больше пока ничего в голову не приходит.
SergNK
Вот приоритеты:
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;
// cool.gif 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
AHTOXA
Ага, вот оно! В M0 нет побайтового доступа к регистру приоритета SHPR3. Нужно назначать приоритет при помощи операций со словом.
Например, вот так.
Поправьте назначения приоритетов для PendSV и для SysTick, и всё должно заработать.
SergNK
Только сегодня добрался до проекта. Работа, однако!

Итак, дело действительно было в приоритетах и только в приоритетах.
Я их поправил и всё заиграло!
И вот что я сделал по-быстрому:
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-овского встроенного ассемблера адрес функции из другого модуля?
AHTOXA
Цитата(SergNK @ Jan 29 2017, 01:43) *
Как сделать видимой для IAR-овского встроенного ассемблера адрес функции из другого модуля?


Код
    EXTERN  os_context_switch_hook

По крайней мере, в порте для M3 так.
SergNK
Цитата(AHTOXA @ Jan 28 2017, 23:56) *
Код
    EXTERN  os_context_switch_hook

По крайней мере, в порте для M3 так.

Это определение для файла "*.s", т.е. чисто ассемблерное.
esaulenka
Цитата(SergNK @ Jan 28 2017, 23:43) *
Как сделать видимой для IAR-овского встроенного ассемблера адрес функции из другого модуля?

Или я не понял вопрос, или Вам нужен EXTERN.
Как оно работает, можно подсмотреть в любом другом ассемблерном модуле (например, в штатном стартапе).

UPD. Перечитал ещё раз. Да, вопрос я не понял. Тут инлайн ассемблер (с какими-то своими правилами). Извиняюсь...
SergNK
Удалось-таки победить. Вот что вышло:

Это обработчик прерывания для среды 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

dxp
QUOTE (SergNK @ Feb 7 2017, 02:18) *
Удалось-таки победить. Вот что вышло:

<...>

В результате я перенёс некоторые функции, приведя в соответствие с версией для GCC и избавился от файла os_target_asm.s

Я правильно понимаю, что вы сделали универсальный порт Cortex-M под IAR? Если так, то не желаете ли эту наработку включить в основной репозиторий?
SergNK
Можно. Я отладил код под Freescale M0+. Подчистить исходники по комментариям и отступам - и вперёд! Куда сбрасывать и как?
dxp
QUOTE (SergNK @ Feb 7 2017, 14:28) *
Можно. Я отладил код под Freescale M0+. Подчистить исходники по комментариям и отступам - и вперёд! Куда сбрасывать и как?

Два варианта.

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

1. Какое-то умение работать с git.
2. Аккаунт на гитхабе.
3. Желание/готовность участвовать в проекте - сопровождать этот порт и не только. sm.gif

В этом случае получаете доступ к репозиторию на гитхабе (включаем вас в команду), далее в соответствии с этим документом вносите свои правки и фиксируете. Я не знаю, насколько вам близок git, но если будут возникать затруднения, мы (с Антоном) всегда готовы помочь.

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

Ваш выбор. sm.gif
SergNK
Спасибо за доверие!

Первый вариант.
dxp
QUOTE (SergNK @ Feb 7 2017, 15:14) *
Спасибо за доверие!

Первый вариант.

Написал в личку.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.