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

dpatrakov

Участник
  • Постов

    26
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о dpatrakov

  • Звание
    Участник
    Участник
  1. плюс одна команда включить пин в начале кода, одна команда выключить в конце, одна перейти в начало петли Проблема частично решена, частично благодаря рассуждениям jcxz правда диалог с ним не получился и зашел в тупик, прерывание запустил с частотой почти 1,5 МГц, но это сожрало 50% ресурса контроллера только на вход и выход но зато получил четкое время накладных расходов прерывания (вход, выход, обслуживание и походу перезеагрузка prefetch в 600-700 ns), также ранее не задумывавшись о передаче данных внутри контроллера так вопрос максимально быстрого отклика отсутствовал, выяснил следующее, буферизации на шинах APB0 и 1 похоже нету, хотя в мануале написано что есть, но может неправильно понял нерусский язык, хотя читаю вроде неплохо, в общем решил отказаться от использования более одного регистра сравнения, и запускать таймер только в режиме сравнения и сброса TC, ну по крайне мере в текущем проекте, хотя отказ от 3 регистров сравнения повлечет изменение алгоритма сильное. Второе выяснилось то что регистр GPIO->FIOPIN имеет буфер записи, с задержкой 2 такта, то есть если записать в него и следующей командой прочитать (на ассемблере) получим предыдущее состояние, добавление 2 nop между записью и чтением решает проблему, хотя такая ситуация редка и в большинстве случаев ее можно избежать. И еще нашел ускорение работы с массивом структур за счет выравнивания руками а не средствами компилятора код занимавший 15 операций (ASM), снизился до 11 за счет выравнивания к 4 не только размеров полей структуры , но и их количества
  2. Вот думал тут, на шине где висит таймер, есть другие устройства и время от времени занимают его что соответственно при обращении должно вызвать ожидание, но в этом случае период выполнения был бы плавающим, а он стоит как вкопанный, щас попозже на работу съезжу сфотографирую, и как вариант отключу всю периферию кроме на шине
  3. Ну у меня с этого и началось. При возникновении прерывания, TC==MR0, тоесть после проверки флага и его сброса что занимает 12 тактов плюс 12 тактов на сохранение регистров при вызове обработчика TC должен опередить MR0 на 24 такта, а по факту опережает на 75 согласен что при входе в обработчик переписывается префетч, но в простом цикле тот же результат Да еще изменение частоты тактирования таймера не влияет на результат О этот пост я пропустил. мальчик ты чего раздухарился так? ты вообще понимаешь как найти время выполнения конкретной инструкции? похоже что нет вот ты 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 }
  4. 200 килогерц прерывание работает, и выполняет свою функцию, но 3 операции по обслуживанию прерывания, занимаю столько времени как весь код самого обработчика ну естественно 1мкс вход выход и непонятные задержки, и десяток команд это 100-150 нс, еще и основному потоку остается время правда мало, вставь в такое прерывание вычисление корня и оно у тебя повиснет, а с десятком команд у меня до 800кГц получалось
  5. дак снижена до 48МГц, но не до 4х же пробовал и просто запись и просто чтение дает 250нс, чтение модификация запись соответственно 500
  6. в документации написано что для общения с периферией буферизированная запись для того чтобы не ждать ну пусть он их вставит, но не 25 тактов же
  7. 250 нс не беда, но когда выполняются 3 такие инструкции подряд, плюс время входа и выхода из прерывания это 1 мкс, это дофига. 1 МГц мне не нужен, я писал ранее, нужно 200 кГц, но это тоже не мало. самая медленная операция в прерывании это посчитать теорему пифагора для 6мерного пространства тоесть корень из суммы 6квадратов Вы что издеваетесь? в первом посте все написано, меряю все цифровым осциллографом, ножкой для этого и дергаю
  8. мне надо каждый раз период перестраивать А во вторых в таймере 4 регистра сравнения, их нужно проверить и сбросить флаги при необходимости, и вот каждая из этих операций длится 250нс Еще по поводу того что - не читал документацию, не понимаю что делаю прошу заметить что зарегистрировался я 11 лет назад, и за это время всего 18 сообщений, это потому что 11 лет не было вопросов, и за это время прочитаны тысячи документаций и реализовано десятки больших проектов, но вот сейчас наступил на какие то грабли и обратился к залу так сказать.
  9. И как это оптимизировать? в цикле я проверяю за сколько времени выполняется код в ассемблере это 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 вот в чем вопрос
  10. Вы отчего так невнимательны, нервничаете? вот в первом посте было написан пример проверки, выполняется в мэйне с отключенными прерываниями, включено только тактирование периферии 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МГц, но этот вариант был проверен сразу, путем отключения ускорителя, во вторых в мэйне код выполняется в одном месте и не прыгает в прерывание, поэтому перезагрузка не требуется
  11. И включал и выключал Ну вы видимо тот еще читатель, раз это понаписали, или привыкли считать себя умнее других. Если бы вы внимательно прочитали, то там все подробно написано, и про то что делитель равен 1 уверен на 100%, насчет си исходника ниже написано что компилируется в 12 инструкций ассемблерных, про стекинг было написано выше и это не десятки тактов а 12 то есть 120 нс (видимо плоховато вы знаете контроллер), с чего вы решили что документация не читалась и ваяется ногодрыгалка? Не имейте привычки флудить чтобы сумничать.
  12. Таймер висит на шине 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% пропадает
  13. Я это в душе понимаю, но как посмотреть? 250нс это 4Мгц таких источников вроде нет
  14. Форумчане прошу помощи в поиске проблемы Проблема в следующем, камень запущен на частоте 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 Встал в ступор куда копать не знаю
  15. Огромное спасибо, то что нужно
×
×
  • Создать...