реклама на сайте
подробности

 
 
> SignalISR() в Blackfin, флаг устанавливается медленно
sevstels
сообщение Feb 22 2010, 04:19
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 626
Регистрация: 3-12-07
Пользователь №: 32 910



Собственно трудность заключается в медленном поднятии флага при вызове функции SignalISR().
Разместил флаги в секции "l2_var", функцию SignalISR() в секции "drivers_L1_code"
Но это не помогло решить проблему.

Принимаются блок данных по SPI, после корректного приёма заголовка должен устанвливаться флаг события. Если в коде обработчика прерывания от SPI по совпадению условий вызывается SignalISR() - то такое прерывание затягивается дольше чем принимается байт данных, в итоге весь блок портится, т к следующий байт повреждён. На фотографии красный луч показывает длительность нахождения в прерывании. Самый широкий импульс как раз и есть вызов функции SignalISR().
Если закомментировать строчку с вызовом - всё приходит в норму. Но только процесс ничего не знает о событии.




На фотографии ниже показана длительнось обработки SPI прерывания без подьёма флагов, примерно 400ns.
Вопрос - как победить неувязку? Пока не удаётся разогнать SPI даже до приемлимого уровня...



--------------------
Herz - дятел.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
dxp
сообщение Feb 22 2010, 08:15
Сообщение #2


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(sevstels @ Feb 22 2010, 10:19) *
Собственно трудность заключается в медленном поднятии флага при вызове функции SignalISR().
Разместил флаги в секции "l2_var", функцию SignalISR() в секции "drivers_L1_code"
Но это не помогло решить проблему.

Странное поведение. Функция-то очень простая:

Код
void OS::TEventFlag::SignalISR()
{
    TCritSect cs;
    if(ProcessMap)                                          // if any process waits for event
    {
        TProcessMap Timeouted = Kernel.ReadyProcessMap;     // Process has its tag set in ReadyProcessMap if timeout
                                                            // expired, or it was waked up by OS::ForceWakeUpProcess()
        if( ProcessMap & ~Timeouted )                       // if any process has to be waked up
        {
            SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map
            ClrPrioTag(ProcessMap, ~Timeouted);             // remove all non-timeouted processes from the waiting map.
            return;
        }
    }
    Value = efOn;
}


тут негде тормозить. Вот реализация в моем проекте (буков много, но по коду там совсем чуть):

CODE

_SignalISR__Q2_2OS10TEventFlagFv:
.LN_SignalISR__Q2_2OS10TEventFlagFv:
.LN12:
unsigned int __rval = __builtin_cli(); // line "D:\CAD\AD\VisualDSP5.0\Blackfin\include\builtins.h":1762
P1 = R0;
.LN13:
{ // line "scmRTOS\Common\OS_Services.h":237
LINK 0;
.LN14:
unsigned int __rval = __builtin_cli(); // line "D:\CAD\AD\VisualDSP5.0\Blackfin\include\builtins.h":1762
.MESSAGE/SUPPRESS 5515;
CLI R1;
I0 = R0;
.LN15:
TCritSect () : StatusReg(cli()) { } // line "scmRTOS\Blackfin\OS_Target.h":109
W[SP + 8] = R1;
.LN16:
if(ProcessMap) // if any process waits for event // line "scmRTOS\Common\OS_Services.h":239
R0 = W[P1] (Z);
CC = R0 == 0;
if CC jump .P41L27 ;

.P41L1:
P0.L = _Kernel__2OS+2;
P0.H = _Kernel__2OS+2;
NOP; // Inserted 2 instrs to fix anomaly w05_00_0245_with_boundaries.
NOP;
.LN17:
TProcessMap Timeouted = Kernel.ReadyProcessMap; // Process has its tag set in ReadyProcessMap if timeout // line 241
R2 = W[P0] (Z);
.LN18:
if( ProcessMap & ~Timeouted ) // if any process has to be waked up // line 243
R1 = -1;
R1 = R2 ^ R1;
R0 = R0 & R1;
CC = R0 == 0;
if !CC jump .P41L13 ;

.P41L27:
.LN19:
Value = efOn; // line 250
R0 = 1;
[P1 + 4] = R0;
.LN20:
~TCritSect() { sti(StatusReg); } // line "scmRTOS\Blackfin\OS_Target.h":110
R0 = W[SP + 8] (Z);
.LN21:
__builtin_sti(__a); // line "D:\CAD\AD\VisualDSP5.0\Blackfin\include\builtins.h":1777
.MESSAGE/RESTORE 5515;
STI R0;

.P41L7:
.LN22:
return; // line "scmRTOS\Common\OS_Services.h":247
P0 = [FP + 4];
UNLINK;
// -- 2 stalls --
JUMP (P0);

.P41L13:
.LN23:
SetPrioTag(Kernel.ReadyProcessMap, ProcessMap); // place all waiting processes to the ready map // line 245
R0.L = W[I0];
.LN24:
INLINE inline void SetPrioTag(TProcessMap& pm, const TProcessMap PrioTag) { pm |= PrioTag; } // line "scmRTOS\Common\OS_Kernel.h":81
R1.L = W[P0];
.LN25:
R0 = R0 | R1;
.LN26:
W[P0] = R0.L;
.LN27:
INLINE inline void ClrPrioTag(TProcessMap& pm, const TProcessMap PrioTag) { pm &= ~PrioTag; } // line 82
R0.L = W[I0];
.LN28:
R0 = R2 & R0;
.LN29:
W[I0] = R0.L;
.LN30:
~TCritSect() { sti(StatusReg); } // line "scmRTOS\Blackfin\OS_Target.h":110
R0 = W[SP + 8] (Z);
.LN31:
__builtin_sti(__a); // line "D:\CAD\AD\VisualDSP5.0\Blackfin\include\builtins.h":1777
.MESSAGE/RESTORE 5515;
STI R0;
jump .P41L7;



Провел замеры на текущем проекте.

1. Время выполнения самой функции SignalISR.

Код
            ...
            START_CYCLE_COUNT(start_count);
            GIFH_complete.SignalISR();
            STOP_CYCLE_COUNT(stop_count, start_count);
            print("cycles: %d\r", stop_count);
            ...


получил значение 62 цикла. Значение это, думаю, не очень точное, т.к. на такой малой величине сильно влияют накладные расходы на эти макросы.

2. Время от начала SignalISR до Wait.

Код
// fpga.cpp

            ...
            START_CYCLE_COUNT(start_count);
            GIFH_complete.SignalISR();
            ...

// video.cpp

            ...
        GIFH_complete.Wait();
        STOP_CYCLE_COUNT(stop_count, start_count);
        print("cycles: %d\r", stop_count);
            ...


Полученное значение - 363 цикла, что при тактовой 200 МГц составляет порядка 1.8 мкс, что похоже на время из примера - порядка 1.5-1.6 мкс (там у меня еще часть кода выполняется, поэтому время чуть больше).

Попробуйте так же замерить. Сколько сама функция, сколько время передачи управления в ожидающий процесс.

Какая у вас тактовая частота? На какой скорости SPI гоняете?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- sevstels   SignalISR() в Blackfin   Feb 22 2010, 04:19
- - blackfin   Вы или неверно изложили суть проблемы, или выбрали...   Feb 22 2010, 05:09
- - sevstels   Цитатавесь блок данных уже принят и уже сохранен в...   Feb 22 2010, 05:32
|- - blackfin   Цитата(sevstels @ Feb 22 2010, 08:32) Оче...   Feb 22 2010, 05:40
- - sevstels   Речь о scmRTOS функции: void OS::TEventFlag::Signa...   Feb 22 2010, 05:45
|- - blackfin   Цитата(sevstels @ Feb 22 2010, 08:45) Реч...   Feb 22 2010, 05:48
- - sevstels   Видимо вопрос к разработчикам scmRTOS, т к в такие...   Feb 22 2010, 05:52
- - sevstels   ЦитатаКакая у вас тактовая частота? На какой скоро...   Feb 22 2010, 08:38
- - sevstels   Перенёс флаги в L1. Измерил. Непосредственно сама ...   Feb 22 2010, 11:00
- - blackfin   Тоже сделал замеры при вызове макросов VDK на дост...   Feb 22 2010, 12:54
- - sevstels   Всё равно - нет в жизни счастья. Звенит тактовый с...   Feb 22 2010, 13:29
|- - blackfin   Цитата(sevstels @ Feb 22 2010, 16:29) Бло...   Feb 22 2010, 13:58
- - sevstels   Нет необходимости вообще что либо делать, кроме ка...   Feb 22 2010, 14:45
- - sevstels   дел   Feb 22 2010, 14:52
- - sevstels   В общем - победил, всё идеально "летает...   Feb 23 2010, 03:40


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 8th July 2025 - 23:04
Рейтинг@Mail.ru


Страница сгенерированна за 0.01386 секунд с 7
ELECTRONIX ©2004-2016