Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC1768 непонятное поведение
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
dpatrakov
Форумчане прошу помощи в поиске проблемы

Проблема в следующем, камень запущен на частоте 100 МГц тоесть инструкции должны выполняться за 10нс, дерганье ножкой показывает что примерно так и есть, но вот возникла задача генерить высокую частоту таймером, и больше 1 мегагерца не получилось, хотя по мануалу вход в прерывание занимает 12 тактов или 120 нс, путем тыка найдена инструкции которые выполняются не за 10нс а за целых 250.
Вот проблемная команда LPC_TIM0->MR0 += T0MR0->interval; ее выполнение занимает 500 нс, это не то что медленно, а вообще жесть.
в ассемблере это занимает всего 4 инструкции (загрузка адреса, чтение, сложение, выгрузка обратно)
в итоге прерывание даже пустого таймера выполняется за 750 нс плюс 120нс вход и 120 выход тоесть 1мкс.
750 получается из 1) операция проверки флага mr0 2) сброс флага 3) изменение mr0

Вторую проверку проводил так
Код
while (1)
{
f = 1-f;
if (f) PINSET;
else PINCLR;
LPC_TIM0->MR0 += T0MR0->interval;
}
итог период выполнения ~600 нс

Код
while (1)
{
f = 1-f;
if (f) PINSET;
else PINCLR;
//LPC_TIM0->MR0 += T0MR0->interval;
}
период выполнения ~85нс

ассемблере тесты различаются всего на 4 инструкции

еще тест
Код
while (1)
{
f = 1-f;
if (f) PINSET;
else PINCLR;
LPC_TIM0->MR0 = T0MR0->interval;
}
итог период выполнения ~300 нс

если рассуждать логически то включение ноги процессора это банальная операция записи в ячейку памяти соответствующую GPIO, а запись в регистр сравнения это такая же операция записи числа в ячеку памяти, но одна выполняется за 10 нс другая аж за 250
Встал в ступор куда копать не знаю
skripach
Цитата(dpatrakov @ Jan 27 2017, 22:27) *

Надо смотреть на какой шине таймер висит, какая частота шины, много факторов влияет на скорость доступа к переферии.
dpatrakov

Я это в душе понимаю, но как посмотреть?
250нс это 4Мгц таких источников вроде нет
jcxz
Цитата(dpatrakov @ Jan 27 2017, 23:41) *
Я это в душе понимаю, но как посмотреть?
250нс это 4Мгц таких источников вроде нет

Смотрится это по мануалу, в частности "Simplified block diagram" и "Architectural overview".
И выставляются соответствующие делители частоты для каждой периферии.
Процессор работает на своей частоте, периферийные блоки - каждый на своей. В LPC1768 можно каждому периферийному блоку назначить свой делитель частоты.
Получить 1МГц прерывание можно, только писать ISR надо оптимально. И возможно на асм, чтобы не грузить CPU на 100% одним только ISR.
dpatrakov
Цитата(jcxz @ Jan 28 2017, 10:43) *
Смотрится это по мануалу, в частности "Simplified block diagram" и "Architectural overview".
И выставляются соответствующие делители частоты для каждой периферии.
Процессор работает на своей частоте, периферийные блоки - каждый на своей. В LPC1768 можно каждому периферийному блоку назначить свой делитель частоты.
Получить 1МГц прерывание можно, только писать ISR надо оптимально. И возможно на асм, чтобы не грузить CPU на 100% одним только ISR.


Таймер висит на шине APB0, тактируется cclk (100МГц)

Запустить на мегагерце получается пустое прерывание, но при этом процессор загружен почти на 100%
из за выполнения всего трех инструкций

Код
if (TIM_GetIntStatus(LPC_TIM0, TIM_MR0_INT)== SET) //250нс
    {        
    LPC_TIM0->MR0 = m_tc + T0MR0->interval; //500нс

    TIM_ClearIntPending(LPC_TIM0, TIM_MR0_INT); //250нс
    }

на ассемблере эта конструкция занимает 12 операций тоесть если рассуждать логически то должна отработать за 120нс, а по факту получается 1000нс что в 10 раз больше, остальные инструкции в обработчике если добавить код выполняются примерно за 10нс




на картинке 2 пути отмечены, GPIO и таймеры висят на системной шине, к выводам шина напрямую время доступа 10нс, к таймеру через AHB->APB мост и время увеличивается до 250нс, то есть получается скорость работы моста 4МГц? вроде бред, или в документации было бы написано что операции чтения регистров периферии ОЧЕНЬ медленныеи используйте их осторожно


Вообще мне мегагерц прерывание не нужно, фактически нужно до 200кГц выполнить нужную задачу, и еще мэйну оставить время для работы, но на такой частоте получаем только операции обслуживания прерывания жрут 20% скорости, а приплюсовав еще один таймер для задержек и пару уартов то наверное и все 50% пропадает
jcxz
Цитата(dpatrakov @ Jan 28 2017, 11:39) *
Таймер висит на шине APB0, тактируется cclk (100МГц)
есть получается скорость работы моста 4МГц? вроде бред, или в документации было бы написано что операции чтения регистров периферии ОЧЕНЬ медленныеи используйте их осторожно

Я понимаю конечно что "чукча не читатель...", но может всё-таки прочитаете и попытаетесь понять, что я писал?
Каждый периферийный блок в LPC1768 тактируется своей частотой, получаемой делением системной частоты на некий делитель.
У Вас этот делитель чему равен? Вы уверены, что он ==1?

Цитата(dpatrakov @ Jan 28 2017, 11:39) *
Запустить на мегагерце получается пустое прерывание, но при этом процессор загружен почти на 100%
из за выполнения всего трех инструкций

Это не инструкции, это си-исходник. Который может компилиться в любое число инструкций. Если хотите получить ВЧ-прерывание, придётся писать на асм.

Цитата(dpatrakov @ Jan 28 2017, 11:39) *
на ассемблере эта конструкция занимает 12 операций тоесть если рассуждать логически то должна отработать за 120нс, а по факту получается 1000нс что в 10 раз больше, остальные инструкции в обработчике если добавить код выполняются примерно за 10нс

Если рассуждать логически, то перед написанием ПО, надо сперва прочитать документацию на железо.
Вы её как видно не читали. Иначе бы знали, что такое стэкинг на входе/выходе в ISR и сколько тактов он занимает. Это десятки тактов.

Цитата(dpatrakov @ Jan 28 2017, 11:39) *
таймеры висят на системной шине,

Странно как-то вроде смотрите на картинку, а видите нечто, чего на ней нет... %-)
Я вот вижу, что только GPIO висит на системной шине (AHB), таймеры же - на периферийной шине (APB). И для каждого блока на APB есть свой делитель, в отличие от AHB, где все работают на частоте AHB.

Цитата(dpatrakov @ Jan 28 2017, 11:39) *
Вообще мне мегагерц прерывание не нужно, фактически нужно до 200кГц выполнить нужную задачу,

Чувствую что ваяется очередное ногодрыгательное "творение"...
А Вы, позвольте спросить, кроме таймера и GPIO, про какую-нить другую периферию LPC хоть читали?
Да и вообще - хоть даже про таймер-то прочитали? И если да - зачем так много инструкций в Вашем ISR? Можно получать периодическое прерывание от таймера не записывая в него ничего.
AVI-crak
Цитата(dpatrakov @ Jan 28 2017, 01:27) *
Встал в ступор куда копать не знаю


A Memory Protection Unit (MPU) is included.
Ожидание завершения операции записи в периферийное устройство с дробной системной частотой.
Если отключить блок защиты MPU - начнутся такие весёлости, что вы сами добровольно и с песней побежите его включать.
dpatrakov
Цитата(AVI-crak @ Jan 28 2017, 16:12) *
A Memory Protection Unit (MPU) is included.
Ожидание завершения операции записи в периферийное устройство с дробной системной частотой.
Если отключить блок защиты MPU - начнутся такие весёлости, что вы сами добровольно и с песней побежите его включать.

И включал и выключал

Цитата(jcxz @ Jan 28 2017, 15:06) *
Я понимаю конечно что "чукча не читатель...", но может всё-таки прочитаете и попытаетесь понять, что я писал?
Каждый периферийный блок в LPC1768 тактируется своей частотой, получаемой делением системной частоты на некий делитель.
У Вас этот делитель чему равен? Вы уверены, что он ==1?


Это не инструкции, это си-исходник. Который может компилиться в любое число инструкций. Если хотите получить ВЧ-прерывание, придётся писать на асм.


Если рассуждать логически, то перед написанием ПО, надо сперва прочитать документацию на железо.
Вы её как видно не читали. Иначе бы знали, что такое стэкинг на входе/выходе в ISR и сколько тактов он занимает. Это десятки тактов.


Странно как-то вроде смотрите на картинку, а видите нечто, чего на ней нет... %-)
Я вот вижу, что только GPIO висит на системной шине (AHB), таймеры же - на периферийной шине (APB). И для каждого блока на APB есть свой делитель, в отличие от AHB, где все работают на частоте AHB.


Чувствую что ваяется очередное ногодрыгательное "творение"...
А Вы, позвольте спросить, кроме таймера и GPIO, про какую-нить другую периферию LPC хоть читали?
Да и вообще - хоть даже про таймер-то прочитали? И если да - зачем так много инструкций в Вашем ISR? Можно получать периодическое прерывание от таймера не записывая в него ничего.

Ну вы видимо тот еще читатель, раз это понаписали, или привыкли считать себя умнее других.

Если бы вы внимательно прочитали, то там все подробно написано, и про то что делитель равен 1 уверен на 100%, насчет си исходника ниже написано что компилируется в 12 инструкций ассемблерных, про стекинг было написано выше и это не десятки тактов а 12 то есть 120 нс (видимо плоховато вы знаете контроллер), с чего вы решили что документация не читалась и ваяется ногодрыгалка?

Не имейте привычки флудить чтобы сумничать.
jcxz
Цитата(dpatrakov @ Jan 28 2017, 20:10) *
Если бы вы внимательно прочитали, то там все подробно написано, и про то что делитель равен 1 уверен на 100%,

Где написано?

Цитата(dpatrakov @ Jan 28 2017, 20:10) *
про стекинг было написано выше и это не десятки тактов а 12 то есть 120 нс

И что?
12 - только вход + прерывание выполняющейся в фоне команды + время на загрузку кода (prefetch) ISR + выполнение ISR + выход ISR + prefetch фонового кода.
И prefetch - вещь длительная из из flash. У Вас откуда прога выполняется? Наверняка из флешь. И какая частота флешь?
dpatrakov
Цитата(jcxz @ Jan 28 2017, 20:43) *
Где написано?


И что?
12 - только вход + прерывание выполняющейся в фоне команды + время на загрузку кода (prefetch) ISR + выполнение ISR + выход ISR + prefetch фонового кода.
И prefetch - вещь длительная из из flash. У Вас откуда прога выполняется? Наверняка из флешь. И какая частота флешь?


Вы отчего так невнимательны, нервничаете?

вот в первом посте было написан пример проверки, выполняется в мэйне с отключенными прерываниями, включено только тактирование периферии
Код
while (1)
{
f = 1-f;
if (f) PINSET;
else PINCLR;
LPC_TIM0->MR0 += T0MR0->interval;
}

дак вот этот код выполняется за 500нс

если из него убрать операция обращения к регистру сравнения LPC_TIM0->MR0 += T0MR0->interval;
то время выполнения цикла падает до 85нс
на ассемблере цикл занимает 9 инструкций и 5 инструкций вот это LPC_TIM0->MR0 += T0MR0->interval;
дак если читали внимательно, я писал что 9 инструкций цикла выполняются за 85 нс а 5 которые записывают в регистр таймера около 500

По поводу флешь, вы что не знали что она требует 5 тактов задержки? значит 20МГц, но этот вариант был проверен сразу, путем отключения ускорителя, во вторых в мэйне код выполняется в одном месте и не прыгает в прерывание, поэтому перезагрузка не требуется
KRS
Если уж боретесь за наносекунды, пишите код оптимально
LPC_TIM0->MR0 += T0MR0->interval;
особенно в цикле... мягко скажем не оптимально (особенно учитывая что регистры описаны как volatile)
dpatrakov
Цитата(KRS @ Jan 28 2017, 22:36) *
Если уж боретесь за наносекунды, пишите код оптимально
LPC_TIM0->MR0 += T0MR0->interval;
особенно в цикле... мягко скажем не оптимально (особенно учитывая что регистры описаны как volatile)

И как это оптимизировать? в цикле я проверяю за сколько времени выполняется код
в ассемблере это 5 команд
Код
LPC_TIM0->MR0 += 1000;
00012a  f04f2040          MOV      r0,#0x40004000 -- 1 цикл
00012e  6980              LDR      r0,[r0,#0x18]       -- 2 цикла
000130  f500707a          ADD      r0,r0,#0x3e8     -- 1 цикл
000134  f04f2140          MOV      r1,#0x40004000 -- 1 цикл
000138  6188              STR      r0,[r1,#0x18]       -- 2 цикла

итого 7 циклов по 10 нс = 70нс, а выполняется за 500 вот в чем вопрос
RabidRabbit
Цитата(dpatrakov @ Jan 27 2017, 22:27) *
Проблема в следующем, камень запущен на частоте 100 МГц тоесть инструкции должны выполняться за 10нс, дерганье ножкой показывает что примерно так и есть, но вот возникла задача генерить высокую частоту таймером, и больше 1 мегагерца не получилось

Настраиваете таймер 1 раз и он будет генерить до потери пульса без Вашего участия. Ему не надо каждый раз параметры перенастраивать...
dpatrakov
Цитата(RabidRabbit @ Jan 28 2017, 23:46) *
Настраиваете таймер 1 раз и он будет генерить до потери пульса без Вашего участия. Ему не надо каждый раз параметры перенастраивать...

мне надо каждый раз период перестраивать


А во вторых в таймере 4 регистра сравнения, их нужно проверить и сбросить флаги при необходимости, и вот каждая из этих операций длится 250нс

Еще по поводу того что - не читал документацию, не понимаю что делаю прошу заметить что зарегистрировался я 11 лет назад, и за это время всего 18 сообщений, это потому что 11 лет не было вопросов, и за это время прочитаны тысячи документаций и реализовано десятки больших проектов, но вот сейчас наступил на какие то грабли и обратился к залу так сказать.
jcxz
Цитата(dpatrakov @ Jan 28 2017, 23:51) *
А во вторых в таймере 4 регистра сравнения, их нужно проверить и сбросить флаги при необходимости, и вот каждая из этих операций длится 250нс

Прям беда эти 250нс! smile3009.gif
И что за задача такая, интересно, требующая прерывания в 1МГц??

Цитата(dpatrakov @ Jan 28 2017, 23:58) *
реализовано десятки больших проектов, но вот сейчас наступил на какие то грабли и обратился к залу так сказать.

Ага "реализованы десятки проектов" и после этого не знаете, что получить такие частоты прерывания крайне проблематично - не знаете?? Имхо - это вроде как почти самоочевидно.
Сомнения берут в десятках проектов...

И каким образом кстати произведены все эти замеры с точностью до десятков нс? Вы умудрились воткнуть щуп осциллографа прямо в AHB? blink.gif
Поделитесь вашим бесценным опытом! cool.gif
dpatrakov
Цитата(jcxz @ Jan 28 2017, 23:59) *
Прям беда эти 250нс! smile3009.gif
И что за задача такая, интересно, требующая прерывания в 1МГц??

250 нс не беда, но когда выполняются 3 такие инструкции подряд, плюс время входа и выхода из прерывания это 1 мкс, это дофига.

1 МГц мне не нужен, я писал ранее, нужно 200 кГц, но это тоже не мало.

самая медленная операция в прерывании это посчитать теорему пифагора для 6мерного пространства тоесть корень из суммы 6квадратов

Цитата(jcxz @ Jan 29 2017, 00:03) *
И каким образом кстати произведены все эти замеры с точностью до десятков нс? Вы умудрились воткнуть щуп осциллографа прямо в AHB? blink.gif
Поделитесь вашим бесценным опытом! cool.gif


Вы что издеваетесь? в первом посте все написано, меряю все цифровым осциллографом, ножкой для этого и дергаю
Dog Pawlowa
Не могу похвастаться хорошим знанием ARM, но рассчитывать, что даже при коэффициенте деления = 1 мост между шинами работает без задержек, выглядит чрезмерно оптимистичным.
Периферия медленная, мост вставляет циклы ожидания. Все должно быть описано в AMBA.
Сам сейчас шлюз клепаю - ну просто живой пример, хотя совершенно в другой области.

>> меряю все цифровым осциллографом, ножкой для этого и дергаю
Вы не имеете возможности оценить задержки моста, поэтому стоит почитать документацию
http://infocenter.arm.com/help/index.jsp?t...ch04s01s04.html
dpatrakov
Цитата(Dog Pawlowa @ Jan 29 2017, 00:18) *
Не могу похвастаться хорошим знанием ARM, но рассчитывать, что даже при коэффициенте деления = 1 мост между шинами работает без задержек, выглядит чрезмерно оптимистичным.
Периферия медленная, мост вставляет циклы ожидания. Все должно быть описано в AMBA.
Сам сейчас шлюз клепаю - ну просто живой пример, хотя совершенно в другой области.

в документации написано что для общения с периферией буферизированная запись для того чтобы не ждать
Цитата
APB peripherals are connected to the CPU via two APB busses using separate slave
ports from the multilayer AHB matrix. This allows for better performance by reducing
collisions between the CPU and the DMA controller. The APB bus bridges are configured
to buffer writes so that the CPU or DMA controller can write to APB devices without
always waiting for APB write completion
.


ну пусть он их вставит, но не 25 тактов же
jcxz
Цитата(dpatrakov @ Jan 29 2017, 00:16) *
Вы что издеваетесь? в первом посте все написано, меряю все цифровым осциллографом, ножкой для этого и дергаю

Да это Вы похоже издеваетесь, мозг тут всем выносите, "десятки проектов" и т.п. И при этом меряете команды дёргая ножкой и ещё про какие-то нс пишете! lol.gif
Dog Pawlowa
Цитата(dpatrakov @ Jan 29 2017, 00:23) *
without always waiting

Загадочный английский язык, варианты перевода какие?
"всегда без ожидания", "без ожидания всегда"

А если чтение-модификация-запись, то шине и периферии оклематься надо.
Ну пишут же напрямую - скорость по APB снижена для экономии потребления.
dpatrakov
Цитата(Dog Pawlowa @ Jan 29 2017, 00:28) *
Загадочный английский язык, варианты перевода какие?
"всегда без ожидания", "без ожидания всегда"

А если чтение-модификация-запись, то шине и периферии оклематься надо.
Ну пишут же напрямую - скорость по APB снижена для экономии потребления.

дак снижена до 48МГц, но не до 4х же

пробовал и просто запись и просто чтение дает 250нс, чтение модификация запись соответственно 500
jcxz
Цитата(dpatrakov @ Jan 29 2017, 00:16) *
1 МГц мне не нужен, я писал ранее, нужно 200 кГц, но это тоже не мало.

На этом МК я получал частоты прерывания от таймера (с полезной работой внутри в десяток команд) до 500-600 КГц.
И получал работающий ISR на частоте 200КГц с выполнением нескольких десятков команд внутри ISR с записью всех регистров в память и копированием до 2-х десятков слов ОЗУ-ОЗУ.

Странно, что с вашим опытом в десятки проектов cool.gif у Вас не получается гораздо более простая задача...
dpatrakov
Цитата(jcxz @ Jan 29 2017, 00:35) *
На этом МК я получал частоты прерывания от таймера (с полезной работой внутри в десяток команд) до 500-600 КГц.
И получал работающий ISR на частоте 200КГц с выполнением нескольких десятков команд внутри ISR с записью всех регистров в память и копированием до 2-х десятков слов ОЗУ-ОЗУ.

Странно, что с вашим опытом в десятки проектов cool.gif у Вас не получается гораздо более простая задача...


200 килогерц прерывание работает, и выполняет свою функцию, но 3 операции по обслуживанию прерывания, занимаю столько времени как весь код самого обработчика

Цитата(jcxz @ Jan 29 2017, 00:35) *
На этом МК я получал частоты прерывания от таймера (с полезной работой внутри в десяток команд) до 500-600 КГц.

ну естественно 1мкс вход выход и непонятные задержки, и десяток команд это 100-150 нс, еще и основному потоку остается время правда мало, вставь в такое прерывание вычисление корня и оно у тебя повиснет, а с десятком команд у меня до 800кГц получалось
jcxz
Цитата(dpatrakov @ Jan 29 2017, 00:43) *
200 килогерц прерывание работает, и выполняет свою функцию, но 3 операции по обслуживанию прерывания, занимаю столько времени как весь код самого обработчика

Опять про нс....
Похоже Вы не поняли - я уже выше написал в чём у Вас проблема.
Никто не меряет сигналы в десятки нс, измерителем с разрешением в десяток МГц. На какой частоте Вы думаете у Вас GPIO работает? cool.gif
Измерять время выполнения команд надо таймером, а не GPIO.
Ну а если так хочется GPIO, то измерять только группу команд от 1000 и больше чтобы получить полезный результат.
dpatrakov
Цитата(jcxz @ Jan 29 2017, 00:53) *
Опять про нс....
Похоже Вы не поняли - я уже выше написал в чём у Вас проблема.
Никто не меряет сигналы в десятки нс, измерителем с разрешением в десяток МГц. На какой частоте Вы думаете у Вас GPIO работает? cool.gif
Измерять время выполнения команд надо таймером, а не GPIO.
Ну а если так хочется GPIO, то измерять только группу команд от 1000 и больше чтобы получить полезный результат.

Ну у меня с этого и началось. При возникновении прерывания, TC==MR0, тоесть после проверки флага и его сброса что занимает 12 тактов плюс 12 тактов на сохранение регистров при вызове обработчика TC должен опередить MR0 на 24 такта, а по факту опережает на 75

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

Да еще изменение частоты тактирования таймера не влияет на результат

[indent][/indent]
Цитата(jcxz @ Jan 29 2017, 00:28) *
Да это Вы похоже издеваетесь, мозг тут всем выносите, "десятки проектов" и т.п. И при этом меряете команды дёргая ножкой и ещё про какие-то нс пишете! lol.gif

О этот пост я пропустил.
мальчик ты чего раздухарился так? ты вообще понимаешь как найти время выполнения конкретной инструкции? похоже что нет

вот ты jcxz дофига умный
расчитай время выполнения следующего кода
Код
;;;1257       while (1)
000128  e011              B        |L1.334|
                  |L1.298|
;;;1258       {
;;;1259           f=1-f;
00012a  f1c40401          RSB      r4,r4,#1
;;;1260           if (f) LPC_GPIO0->FIOCLR = 1;
00012e  b11c              CBZ      r4,|L1.312|
000130  2001              MOVS     r0,#1
000132  4919              LDR      r1,|L1.408|
000134  61c8              STR      r0,[r1,#0x1c]
000136  e002              B        |L1.318|
                  |L1.312|
;;;1261           else LPC_GPIO0->FIOSET = 1;
000138  2001              MOVS     r0,#1
00013a  4917              LDR      r1,|L1.408|
00013c  6188              STR      r0,[r1,#0x18]
                  |L1.318|
;;;1262           LPC_TIM0->MR0 += 1000;
00013e  f04f2040          MOV      r0,#0x40004000
000142  6980              LDR      r0,[r0,#0x18]
000144  f500707a          ADD      r0,r0,#0x3e8
000148  f04f2140          MOV      r1,#0x40004000
00014c  6188              STR      r0,[r1,#0x18]
                  |L1.334|
00014e  e7ec              B        |L1.298|
;;;1263       }
Dog Pawlowa
Цитата(dpatrakov @ Jan 29 2017, 01:59) *
мальчик ты чего раздухарился так?

Опять г...о по трубам.
dpatrakov
Вот думал тут, на шине где висит таймер, есть другие устройства и время от времени занимают его что соответственно при обращении должно вызвать ожидание, но в этом случае период выполнения был бы плавающим, а он стоит как вкопанный, щас попозже на работу съезжу сфотографирую, и как вариант отключу всю периферию кроме на шине
jcxz
Цитата(Dog Pawlowa @ Jan 29 2017, 09:57) *
Опять г...о по трубам.

Да, Вы правы - очередное хамло....
В игнор.
KRS
Цитата(dpatrakov @ Jan 28 2017, 23:18) *
И как это оптимизировать? в цикле я проверяю за сколько времени выполняется код
в ассемблере это 5 команд


в данном случае должно быть две


Код
000130  f500707a          ADD      r0,r0,#0x3e8     -- 1 цикл
000138  6188              STR      r0,[r1,#0x18]       -- 2 цикла


dpatrakov
Цитата(KRS @ Jan 30 2017, 21:42) *
в данном случае должно быть две


Код
000130  f500707a          ADD      r0,r0,#0x3e8     -- 1 цикл
000138  6188              STR      r0,[r1,#0x18]       -- 2 цикла

плюс одна команда включить пин в начале кода, одна команда выключить в конце, одна перейти в начало петли

Проблема частично решена, частично благодаря рассуждениям jcxz правда диалог с ним не получился и зашел в тупик, прерывание запустил с частотой почти 1,5 МГц, но это сожрало 50% ресурса контроллера только на вход и выход но зато получил четкое время накладных расходов прерывания (вход, выход, обслуживание и походу перезеагрузка prefetch в 600-700 ns), также ранее не задумывавшись о передаче данных внутри контроллера так вопрос максимально быстрого отклика отсутствовал, выяснил следующее, буферизации на шинах APB0 и 1 похоже нету, хотя в мануале написано что есть, но может неправильно понял нерусский язык, хотя читаю вроде неплохо, в общем решил отказаться от использования более одного регистра сравнения, и запускать таймер только в режиме сравнения и сброса TC, ну по крайне мере в текущем проекте, хотя отказ от 3 регистров сравнения повлечет изменение алгоритма сильное. Второе выяснилось то что регистр GPIO->FIOPIN имеет буфер записи, с задержкой 2 такта, то есть если записать в него и следующей командой прочитать (на ассемблере) получим предыдущее состояние, добавление 2 nop между записью и чтением решает проблему, хотя такая ситуация редка и в большинстве случаев ее можно избежать. И еще нашел ускорение работы с массивом структур за счет выравнивания руками а не средствами компилятора код занимавший 15 операций (ASM), снизился до 11 за счет выравнивания к 4 не только размеров полей структуры , но и их количества
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.