22.06.2015, 09:48 | #11 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Пасибки всем кто откликнулся, но к решению проблемы меня это не приблизило ни разу.
Теперь библиотека позволяет компилять стандартный Blink.ino в размер аж 502 байта... но вот только "не пашет" как надо. Что делал и как (файл arhat_time.c): 1. Проверка обработчика прерывания (код теста в примерах) - читаем тупо счетчик прерываний таймера по переполнению и считаем задержки по его значениям. Всё пашет как надо. Но он считает по 1.024 миллисекунды, а стало быть задержки НЕ миллисекундные. Можно пользоваться только им, но тогда свои чиселки из миллисекунд надо пересчитывать в тики таймера вручную, на куркуляторе. Обработчик прерываний минимизирован "до не могу" и работает верно. Заодно, уменьшается требование к оперативке: нет хранения fract и счетчика миллисекунд. Экономия 5 байт оперативы. 2. Начальная инициализация скетча: устранены все предварительные настройки таймеров из функции init(), которая подшивается в типовом main() принудительно. Только настройка таймера 0. За счет константной настройки, можно перекомпилять "по другому" и потом использовать "как хочется", и дополнительно от init() осталось ... 26 байт кода. Дополнительно сделан макрос pwmSet(pin), который надо использовать в setup(), для добавления настроек нужного таймера. Фактически, какие ноги под аппаратный PWM используем - настройка таких счетчиков и будет добавлена, но уже в setup(). Для полноты, добавлен макрос pwmOff(pin), отключающий таймер и ногу. 3. Функция micros() реализована ассемблерной вставкой, устраняющей косяк компилятора. Точнее, его слабую оптимизацию переиспользования регистров и отсутствие байтовой компиляции "длинных чисел", при том, что контроллер - таки байтовый. Эта же оптимизация ручками использована и в обработчике прерывания по переполнению. Вот тут - я сильно не уверен, что поступил верно. Поскольку в asm-вставке не указано никак, что функция использует стек и прячет и достает "всё что портит". Из-за этого, её пришлось увеличить на 8 байт. Но, глядя на листинг ассемблера, хорошо вижу что компилируется верно. Собственно, вторая проверка в тестовом скетче - использование одной этой функции для формирования микросекундных задержек - показывает, что всё работает верно... по крайней мере, я визуально, косяков не обнаружил... ... требуется детальная перепроверка, может её кто-то сделать? К сожалению, эта функция, точно также как и стандартный millis() совершенно непригодна для формирования решений методом % (кратно значению микросекунд от начала счета), типа так: if( micros() % 500 ) { /*...код...*/ } поскольку её результат "скачет" далеко не подряд... сам счетчик кратен 4 микросекундам, плюсом идет насчет собственного времени работы. Вот чиселко в ovf_count - использовать ТАК - очень даже можно... Для этого, добавлена функция getOvfCount(), считывающая его значение при запрещенных прерываниях (консистентно). По-хорошему, надо бы превратить в макрос для inline вставок в код "по желанию"... (скорость/размер) 3. Функция millis() - проверял раньше, работала, более не изменял. Ибо - это "затычка". В отличии от стандартной, она пересчитывает текущее состояние счетчика переполнений с учетом текущего состояния счетчика и использует библиотеку деления длинных целых чисел. Это ни разу не быстро, поэтому её активное использование - сильно не рекомендуется. Но, предпочитаю иметь пусть долгую, но верно работающую функцию, чем нечто косячное... тут, что называется "на вкус и цвет". Если нужна именно эта и "быстрая", то проще оставить типовой wiring.c вместо файла arhat_time.c Тут требуется мнение сообщества "что нужнее"? 4. Функция delay(). Реализована в двух вариантах: с параметром unsigned long (по сути, полная копия из wiring.c) и параметром unsigned int (uint16_t). Обе функции имеют собственные названия с префиксом: time_delay(uint32_t) и time_delay16(uint16_t) и в стандартный delay() переименовываются препроцессором согласно режиму либы. Вот они обе, работают сейчас неверно и я не могу понять "в чем дело". Смотрел ассемблерный листинг, и в нем тоже "всё ровно": обрезка значения происходит верно: тупо после вызова time_micros() использовано только 16 младших бит, сравнение вроде как с константой в 16бит ... может конечно "не то", я ещё плохо ориентируюсь в ассемблерных командах... Больше опасался, что асм-реализация micros как-то криво подшивается в вызов ... но нет, все тоже вроде бы "ровно". Может кто-нибудь скомпилировать вручную arhat_time.c в ассемблер и посмотреть "что там не так"? (может мне ещё не по глазам?) Ну или погонять под отладчиком и/или имитатором ... (уже смотрю в сторону virtualbox, чтобы поставить себе нормальный софт ... пока только линуксовый блокнот, консоль и сама Ардуино ИДЕ) P.S. Извиняюсь за большой пост, можно использовать как начало описания функций библиотеки (позже добавлю полный хелп и кейвордс, они уже делаются) Последний раз редактировалось Arhat109; 22.06.2015 в 09:56. Причина: правка очепяток. |
22.06.2015, 12:12 | #12 |
Senior Member
Регистрация: 20.09.2014
Сообщений: 145
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Могу тебе погонять ассемблер. Ты мне код, входные параметры и что на выходе получить.
По результатам прогона могу выдать сколько тактов потрачено в разных режимах. Либо предложи свое видение прогона. Асемблер сильно привязан в архитектуре, на тиньках количество команд сильно урезано. |
22.06.2015, 13:11 | #13 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
В первом посту, zip-архив. В нем есть файлик arhat_time.c со всеми вышеописанными функциями и проблемами.
Вот, требуется помощь "где я в нем накосячил" ... Пардон, забыл: либа пишется в первую очередь под Мегу 2560. У меня есть ещё УНО, но я её ещё даже не распаковал... хочу довести до релиза с Мегой, а уже потом, "портировать" на неё. Последний раз редактировалось Arhat109; 22.06.2015 в 13:13. Причина: дополнение, склероз... |
22.06.2015, 13:21 | #14 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
В первую очередь, мне хочется разобраться почему в тестовом примере (папка examples в том же архиве) тест по delay() работает неправильно. Он считает значительно быстрее чем "надо". И это при том, что тест по micros(), которая в нем использована, визуально проходит верно (больше проверить нечем), а сам код delay() тупо не содержит "ничего такого", что могло бы повлиять ТАК... такое ощущение, что что-то примитивное, но мне - вот совсем не по глазам.
|
22.06.2015, 21:02 | #15 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Вот теперь, я уже ваще ничего не могу понять.
Методом "эксперментального тыка" установлено, что функция time_delay16() создает задержку, визуально похожую на правду, если значение задержки умножать на 4. Такое ощущение, что time_micros() возвращает в delay() не количество микросекунд, а количество тиков! Но ведь, в свой тест, где задержка вычисляется только через micros() считается "визуально верно", то есть ... возвращаем таки микросекунды. Да и умножение на 4 там прописано сдвигами явно ... просмотрел ассемблерный листинг ещё раз... КАК такое можно объяснить? |
22.06.2015, 21:37 | #16 |
Senior Member
Регистрация: 20.09.2014
Сообщений: 145
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Я пока инсталю проги для ковыряния в ваших трудах и плюс пытаюсь освоить отладчик для ардуино иде.
Я предполагал что на мне будет только асемблерный код доделать, вы предложили ковырятся во всем вашем проекте. Зы. Ассемблерный блок где вы обрабатываете прерывание - выход по Reti. Чуть ниже блок ассемблерный - там просто кончается на команде pop, а где Ret? |
22.06.2015, 23:09 | #17 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Пасибки за участие, но я уже нашел.
Команду ret втыкает компилятор самостоятельно. Это же С-шная функция. Я не уверен, что в asm volatile {} не надо ничего указывать во второй и третьей секции ... с ними ещё не разобрался. Причина была в том, что в time_micros(), не проверялось значение счетчика == 255. Флаг переполнения счетчика 0 в этом режиме устанавливается уже при этом значении (похоже что так), но прерывания ещё нет. И, в результате, micros() добавляет 1024 мксек. "заблаговременно" заскакивая периодически вперед. Там ещё куча ляпов в самом тесте... вот и наложилось одно на другое так причудливо. Правлю (вот прям щас...), заодно можно будет освободить 2 регистра в micros() и убрать push/pop ... Пытаюсь понять КАК можно инкрементировать 3-х байтовое значение на +1, не занимая лишний регистр. Пока ещё с системой команд "трудно" ... приходится лазить в мануал по каждому чиху. Ещё раз, пасибки за участие. Ваша перепроверка - ну вот никак не помешает. |
23.06.2015, 22:34 | #18 | |
Senior Member
Регистрация: 20.09.2014
Сообщений: 145
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Цитата:
Upload requires a serial port or programmer. Upload cancelled. У мну неть ардуйни, получается без нее никак? Втыкал в бук PL2303, думал плагин зохавает сом порт, а фиг там. Паять PL2303 c бутлодырем на базе АтМеги328 для обмана плагина? Еще плагин выдает 30 дневный триал, на сайте ни слова о стоимости, бетка чтоль еще. |
|
24.06.2015, 10:31 | #19 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Как понимаю, без неё - только на имитаторах. Я пока этим всем не пользуюсь, но уже активно задумался насчет расширения используемого ПО...
|
28.06.2015, 11:02 | #20 |
Senior Member
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0 |
Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.
Очередное обновление библиотеки в первом посту темы:
27.06: Архив обновлен: - Добавлена работа с аппаратным servo с использованием любых 16-и разрядных таймеров. Тестовый пример pwmServo - крутит SG-90 в обе стороны. Константы крайних положений - для конкретно моей сервы; - Добавлены макросы для работы с аналоговым вводом. Тестовый пример AnalogRead - читает потенциометр и управляет яркостью светодиода через ШИМ; - Изменены файлы arhat.h и arhat_pins2560.h с целью дальнейшей совместимости с Wiring: теперь подключается HardwareSerial в обоих режимах. 28.06: Сделана первая версия описания. Пока текстовый файл, кодировка utf-8. ... на ближайшую пару недель, это "пока всё". Жду откликов, насколько надо продолжать эту работу. |
Метки |
arduino mega 2560, скетч, ардуино |
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1) | |
|
|