Форум обсуждения систем  

Вернуться   Форум обсуждения систем "Умный дом", проектов Ардуино, OpenWRT и других DIY устройств > Форум умного дома > Сделай сам

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.06.2015, 10:30   #1
Arhat109
Senior Member
 
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0
Arhat109 is an unknown quantity at this point
По умолчанию Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Библиотека для уменьшения размеров скетчей, без их изменения (замена Wiring).

Допустимые процессоры (и платы Ардуино на их основе):
ATmega2560, 16Mhz -- основная разработка. Тестируется под него постоянно.
ATmega328P, 16Mhz -- сделан файл "распиновки" для типичных плат на его основе: Arduino UNO (тестируется), Arduino Pro Mini и др.
Также разрешена компиляция под процессоры ATmega168P, ATmega88P, ATmega48P, но не тестируется ввиду отсутствия таковых.

Если машинка не на этом чипе, то первое сообщение будет об ошибке: error this board is not supprted yet... ибо заблокировано.

Возвращен режим совместимости с wiring!


Внимание! Проект на гитхаб ПЕРЕЕХАЛ на адрес: https://github.com/dimanus/ARHAT_H
Все дальнейшие обновления и патчи - там. Пока есть только одна ветка trunk.
Архив здесь обновлен 24.12.2015 и дальнейших обновлений архива - не планируется.

1. Версия 2.1 (частично тестирована);
2. Установка: импортируется и разворачивается как обычная библиотека. Может потребовать переименования wiring.c "error: redefine __vector23()";
4. Использование: основная цель - сделать инструментарий, не жрущий лишнюю память и максимально совместимый с типовыми функциями.

Для использования надо:
1. Развернуть архив в отдельный подкаталог Arhat (уже есть в архиве!) каталога libraries ваших скетчей. Точно так же как добавляются все прочие библиотеки
2. В скетч воткнуть:

#define ARHAT_MODE {1|2} // описание ниже
#include "arhat.h"

2.1 Для автоматного стиля дополнительно воткнуть:

#include "tsc.h" /* если включаются автоматные библиотеки (сейчас есть только для HCSR-04), то tsc.h - не обязателен: есть автоподключение из hcsr04.h */

3. Для ознакомления можно открыть примеры и попробовать самостоятельно. А равно читать исходники. Документирована практически каждая строчка.

02.12.2015:
1. Расширена обработка прерываний PCINT на все уровни. Для ATmega328P и его клонов все уровни 0,1,2. Для ATmega2560 реализованы только уровни 0 и 2. PCINT1 -- не реализован из-за малого количества подключенных ног и использовании 2-х регистров процессора (уровень размазан по двум регистрам внутри)
2. Возврат режима "совмещенный" через предопреление константы ARHAT_MODE == 1. В этом режиме подключается файл Arduino.h и НЕ производится переопределения стандартных функций wiring, что конечно же отражается на размере скетча. Обработчик прерываний от таймера 0 тут используется от wiring, что устраняет конфликт. Также можно пользоваться всеми макросами и функциями билиотеки.

Если константа режима НЕ определена ИЛИ определена как 2, то компилируется в "автономном" режиме БЕЗ подключения Arduino.h. В этом случае, все типовые функции переопределяются на макросы с константным указанием номера пина. Обработчик прерываний используется свой, что может потребовать переименования wiring.c

Переименование файла не требуется в случае ИДЕ 1.6.4 (остальные не проверял) для Линукс, если инсталяция ИДЕ - НЕ ПРОИЗВОДИТСЯ. Просто распаковываем ИДЕ куда надо и запускаем arduino.sh ручками. Как признак того, что проблем не будет - в детальной компиляции видно что файлы wiring компилируются из каталога установки, а не /usr/share/Arduino. Вот если из шары - то требуется переименование.

Краткая сводка сделанного:
1. "однокомандное" управление пинами: один вызов = 1 команда ЦПУ;
2. однокомандные макросы управления таймерами: позволяют устанавливать регистры таймеров произвольным способом;
3. "однокомандный" ШИМ. В том числе и режимы аппаратного серводвигателя на 16-и битных таймерах.
4. АЦП. Есть режим как разового, так и потокового чтение по прерываниям. Макросы отдельного запуска, останова и настройки режимов оцифровки;
5. PCINT Обработка прерываний для подсчета длительности импульса ИЛИ подсчета количества импульсов (энкодер на прерываниях). Имитация виртуальных методов, позволяет дополнять способы обработки прерывания;
6. Работа со временем. Дополнение wiring 16-и битным временем, позволяющим сократить вызовы типовых функций времени на 6 байт каждый; Дополнительно сделано консистентное чтение счетчика переполнений. Добавлены простые макросы микросекундных и менее задержек;
7. Автоматное программирование (Блинк без делай):
7.1. Макросы, позволяющие исполнять заданный код по истечению времени (everyMillis(), everyOvf()). Второй проще, дешевле и компактнее;
7.2. Структура TSC_Simple и конечные автоматы, с собственной функцией переходов;
7.3. Структура TSC_Control и конечные автоматы с таблицей переходов. К ним теперь ещё добавились функции микросекундного управления задержками.
8. В обработчик прерывания таймера 0 встроена возможность вызова и выполнения процедур без параметров, позволяющая организовывать RTOS. А также добавлена функция
TimerHookProc setTimerHook(TimerHookProc);
позволяющая атомарно изменять процедуру, вызываемую из под прерывания. Возвращает предыдущее значение хука. Изначально = 0.
Процедура хука вызывается с открытыми прерываниями, что позволяет таймеру продолжать счет. Есть "защелка", блокирующая повторный вызов хука ДО возврата из него. То есть хук вызывается только раз до своего завершения.

... Пробуйте, пользуйтесь, если что-то не так - пишите тут.

08.12.2015: Обработчик прерываний автономного режима дополнен способностью вызывать внешнюю функцию в глобале timer0_hook каждые 1024мксек. Процедура запускается с открытыми прерываниями и блокировкой повторного вызова. Это позволяет использовать "долгие" функции и не завешивать таймер времени. Типовой Blink вырос до 568байт;
Кроме этого, добавлен пример (не тестирован) оригинального кода получения температуры и влажности с датчика DHT.
24.12.2015: Исправлен баг добавления хука в обработчик прерывания (опечатка после тестирования функции прерывания). Дополнительно добавлено атомарное чтение/изменение функции хука TimerHookProc setTimerHook(TimerHookProc); - устанавливает новую функцию и возвращает предыдущее значение. Изначально =0 -- нет хука.
Расширен пример TestTimer0.ino для проверки/образца установки хука.

Код тут обновлен 24.12.2015 и можно брать с гитхаба. Если что-то работает "не так" - пишите тут или на почту.

29.03.2016: Обновлена версия на гитхабе:
1. Исправлен баг по настройке регистров таймеров в режимах PWM для семейства UNO: arhat_pins328p.h;
2. Исправлен хук таймера 0, для вызова сторонних процедур в заданное время - была ошибка несохраняемого контекста;
3. Добавлена работа с датчиком цвета TCS3200. Датчик работает как хук таймера (режим RTOS) по умолчанию в полном режиме. Датчик умеет и это можно отключать по отдельности:
3.1. восстановление цветов по обратной матрице из даташит (взяты средние значения);
3.2. восстановление баланса белого от засветки собственными светодиодами (подобрано экспериментально);
3.3. повышение контрастности цвета - корректировка общей фоновой засветки (подобрано экспериментально);
3.4. усреднение нескольких замеров, по умолчанию - 1 замер;
3.5. автоподстройка длительности измерения для улучшения качества в темных условиях (от 10лк);
3.6. нормировка белого канала в люксы. Не очень точно, но терпимо.
3.7. также можно отключить замер цветных каналов и получать ч/б результат только в яркостном канале с повышением скорости замеров.
Возможно подключение более одного датчика общими ногами на один счетчик (задействован T5), замеры "по очереди" на базе сигнала разрешения !ОЕ (проверять что не закорочен на плате датчика!!!)
Проверка работы в качестве датчика линии (ч/б вариант без автоподстройки скорости, на замер 1мсек) показал очень надежную работу.

4. Добавлены команды чтения/записи EEPROM от DeGlucker.
5. Работа с датчиком DHT22 выделена в отдельные файлы, но даже ещё не компилировалась ... (чтобы не забыть)

10.04.2016: Обновлена версия на гитхабе:
1. Выложена улучшенная версия аппаратного драйвера I2C(TWI, 2Wire). Пока тестирован только Master-Transmitter. Остальное только скомпилировано. По идее "должно работать" .. ежели вчё - пишите тут или на мыло. Отличия от wiring:
1.1. "Раздельная" компиляция блоков - режимов работы: Управляется константой #define TWI_ON перед подключением файла #include "arhat_twi.h". Значения:
1 -- подключить режим Master-Transmitter; 2 -- подключить Master-Receiver; 4 -- Slave-Receiver; 8 -- Slave-TRansmitter.
Режимы можно комбинировать, например так:
#define TWI_ON 15 // == 1+2+4+8 -- включить всё.
Это позволило поиметь минимальный объем обработчика Master-Transmitter (нужен чаще всего) размером 190байт. Каждый режим по одиночке тянет примерно по 200байт, все 4 сразу = 424байта.
1.2. Внешняя буферизация данных. Файл содержит только указатели на буфер приема/передачи и счетчик байт на сеанс. Переустановка указателя и счетчика - задача вызывающей программы. Это позволило сэкономить около 200 байт оперативной памяти;
1.3. Добавлен аппаратный режим Read After Write для чтения устройств по передаваемым командам. Позволяет одним запуском обработчика передать команду устройству и получить результат без освобождения шины, при условии что адрес чтения тот же что и адрес записи. @see twiRAW().
1.4. Добавлен макрос, вычисляющий настройку битрейт регистров скорости работы шины по заданной частоте. Позволяет устанавливать произвольную частоту обмена по I2C от 490гц до 880кгц включительно.
1.5. Запрещено (аппаратно!) совмещение режимов Master-Receiver + Slave-Receiver, а также не получилось реализовать режим "самопрослушки": Master-Transmitter + Slave-Receiver. Первое запрещено аппаратно - разное использование сигнала TWEA (ACK) в этих режимах, а второе нельзя сделать из-за единого регистра статуса автомата: пропадают статусы или передатчика или приемника. Не разбирался какие точно. "Запрещено" - в смысле нельза настроить обработчик так, чтобы он принимал быйтики сам как мастер И одновременно слушал шину на прием "а вдруг мне там что прилетит" .. из-за этого реализовал ОДИН указатель буфера для приема данных...
1.6. Функции вывода в интерфейс проверяют занятость шины предыдущим сеансом связи и ждут его завершения.. Сделаны отдельные функции-примитивы для создания собственных верхних уровней работы с I2C (раздел Protected файла arhat_twi.h).

2. Добавлен файлик для работы с LCD1602 через эту реализацию I2C(TWI). Пока только в виде функции записи N байт с заданного указателя. Особенности:
2.1. Неблокирующая работа с дисплеем. Запись возвращается в код вызова не когда байт/строка будет записано в дисплей, а сразу как только запущен автомат.
2.2. Произвольная скорость работы интерфейса с дисплеем. Мой устойчиво "терпит" от 10кгц до 880кгц.
2.3. Потоковый захват шины при выводе на дисплей. Посылка "всей пачки байт" (6шт) при выводе одного байта в 4-х битном режиме.
2.4. "Безбуферная" работа с дисплеем. Буфер организован только на подготовку этих самых 6 байт. Больше все равно незачем.
2.5. Добавлен пример в каталог примеров LCD1602.ino
2.6. Инициализация I2C шины сделана по принципу "если ещё никто не запустил, то так" .. далее этот способ будет распространен на все остальные файлы устройств тут. Понравилось.
2.7. Функция вывода байтика на дисплей отрабатывает задержку в 4мсек. Это реальное у меня время "отработки" дисплеем полученной команды. Пока, на всякий случай.

3. Мелкие правки в файле arhat_pins328p.h -- указание I2C ножек было сделано неверно. Поправил.

11.04.2016: Обновлена версия на гитхабе:
1. В файл arhat.c добавлено автовключение режима "с хуком таймера" в виде #define ARHAT_MODE 3 -- вот если 3, то с хуком .. а если нет, то обработчик таймера будет компилироваться в старом, "сокращенном виде".
2. Дополнительно добавил функции pushAllRegs(), popAllRegs() позволяющие сохранять и восстанавливать контекст с подменой точки возврата. Теперь сохранение контекста в обработчике таймера при вызове хука идет через них.
Компилируется, не тестировалось ещё.
Вложения
Тип файла: txt help.txt (18.6 Кб, 1480 просмотров)

Последний раз редактировалось Arhat109; 13.06.2019 в 15:07.
Arhat109 вне форума   Ответить с цитированием
Старый 19.06.2015, 13:59   #2
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,616
Вес репутации: 9820
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Добавил ссылку на эту тему
Admin вне форума   Ответить с цитированием
Старый 19.06.2015, 14:16   #3
Arhat109
Senior Member
 
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0
Arhat109 is an unknown quantity at this point
По умолчанию Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Пасибки. Посмотрел генерацию .asm для функций таймера и ужаснулся... желание использовать unsigned long или его клоны отпало напрочь.

Ушел думать...
Arhat109 вне форума   Ответить с цитированием
Старый 19.06.2015, 15:18   #4
Arhat109
Senior Member
 
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0
Arhat109 is an unknown quantity at this point
По умолчанию Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Небольшое итого:

1. Компилятор не использует арифметику в памяти. ИМЯ++ компиляется в загрузку значения в регистр(ы) (long мать его!) его инкремент и выгрузку "взад"... грустно. Вроде же есть команды?!?

В итоге, процедура обработки прерывания из единственной команды СЧЕТЧИК++ занимает дикое количество байт... под 40.

2. Сложные структуры struct{}, union{} не ассоциируются с регистрами, даже если это можно туда запиховывать... как только, так сразу всё лезет в память (идет лесом).

3. Компиляция выражения ((micro+tov)<<8)+timer для 32-битного micro и 8-битных timer, tov приводит к созданию временной переменной (***** Б. на регистрах), которую создаем перетаскивая содержимое байтов из регистра в регистр... ваще "дурь какая-то" ... и это с ключом оптимизации -Os. Впрочем, с остальными - тот же фиг только сбоку...

Как итог: это не оптимизация... гонятся за "байтиками", используя avg-gcc нет никакого смысла.
Все критичные секции надо катать на асм-вставках... пошел учить ассемблер.
Arhat109 вне форума   Ответить с цитированием
Старый 21.06.2015, 10:01   #5
Arhat109
Senior Member
 
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0
Arhat109 is an unknown quantity at this point
По умолчанию Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Похоже что без удаления wiring.c написать собственный обработчик таймера 0 - не получится. Так и не нашел КАК воткнуть собственный ISR(__vector_23) {} при наличии его же реализации в этом файле.

На самом деле нет никакого способа?

Тогда нужен совет, как лучше поступить?

вариант "а":
оставить исходный комплект wirng "без изменений", и, соответственно, остается исходный код обработчика нулевого таймера и типовые функции, в т.ч. и вся кривизна в millis() ... остальные, вроде бы нормальные.
Зато можно превратить эту библиотеку в "типовое подключение библиотек", и даже можно поперекрывать даже тот же millis() своей реализацией: назвать иначе и редефайнить на типовые названия.

вариант "б":
Сделать свой wiring.c, заодно укоротив его код примерно на 30-40%?
Также можно будет сделать "типовую библиотеку", но с требованием переименования wiring.c...

По сути, вопрос упирается в следующую дилемму:

стоит ли требование отключать wiring.c экономии кода примерно в 80-150 байт?
Arhat109 вне форума   Ответить с цитированием
Старый 21.06.2015, 12:22   #6
Arhat109
Senior Member
 
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0
Arhat109 is an unknown quantity at this point
По умолчанию Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Вот собственно ради такого. Картинка скомпилирована в режиме asm реализации прерывания и функции micros().
Миниатюры
Нажмите на изображение для увеличения
Название: blink1.png
Просмотров: 934
Размер:	108.0 Кб
ID:	2618  
Arhat109 вне форума   Ответить с цитированием
Старый 21.06.2015, 23:06   #7
Arhat109
Senior Member
 
Регистрация: 14.06.2015
Адрес: СССР
Сообщений: 122
Вес репутации: 0
Arhat109 is an unknown quantity at this point
По умолчанию Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Выложил свежий вариант (инструкцию внутри ещё не правил!!!).

1. Приведение архива к "стандартному виду". Включается как обычная библиотека. Отличие - необходимость отключать (переименовывать) wiring.c

То есть, теперь можно распаковать в libraries в свой подкаталог и пользоваться, указывая 2 директивы в скетчах:
#define _ARHAT_ 1 // теперь необязательная директива. Если нет - режим совместимости с Wiring
#include "arhat.h"

2. В подкаталоге examples лежит тестовый пример, который моргает 13 ногой, проверяя:
а) обработчик прерывания (моргает 10 раз по 1 сек);
б) функцию micros() (моргает 10 раз по 0.5сек);
в) функцию delay() ...

Изменения:
1. Сделал ассемблерные вставки в обработчик прерывания и функцию micros(). Не уверен, что верно, тут требуется помощь... но первые 2 теста проходят вроде как нормально.

2. Замена void delay(unsigned long); на void delay16(unsigned int);
Это позволяет значительно сократить размер loop() за счет экономии по 6 байт на каждый вызов. Ну и сама функция занимает на 20 байт меньше места.

3. Функция micros() возвращает текущие микросекунды с учетом собственного времени работы включая команду ret. Не уверен, что посчитал верно, возможно потребуется уточнить и вставить nop для выравнивания микросекунд.
Ассемблер, вставка. Вроде бы сохраняет всё, компиляется нормально.

... и вот появилась какая-то засада, так и не понял "где именно":

функция delay(), в т.ч. и "стыренная" из wiring.c работает неверно! Отсчитывает примерно раз в 10 быстрее... или даже больше.

Кто-то может помочь?
Arhat109 вне форума   Ответить с цитированием
Старый 21.06.2015, 23:29   #8
Alex19279
Senior Member
 
Регистрация: 20.09.2014
Сообщений: 145
Вес репутации: 0
Alex19279 will become famous soon enough
По умолчанию Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Минус ардуин что нет пошаговых отладчиков, нельзя без костылей отлаживать код, только метод тыка и подбора.
Alex19279 вне форума   Ответить с цитированием
Старый 21.06.2015, 23:30   #9
Wagan
Senior Member
 
Регистрация: 02.06.2015
Адрес: Москва
Сообщений: 168
Вес репутации: 0
Wagan is an unknown quantity at this point
Отправить сообщение для Wagan с помощью Skype™
По умолчанию Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Не вдавался в детали, лишь просмотрел по диагонали, поэтому пока могу предложить лишь одно: при сравнении переменной типа long int с константой, константу лучше принудительно указать с суффиксом L. В Вашей функции time_delay есть место:
while (interval > 0L) {
У меня мало опыта с ардуиновским компилятором, поэтому мое предположение может быть ошибочным, но в "честном" Си лучше делать именно так, иначе переменную обрежут
Соответственно, если мое предположение верно, лучше это проверить везде.
Wagan вне форума   Ответить с цитированием
Старый 22.06.2015, 08:37   #10
D1soft
Junior Member
 
Регистрация: 22.06.2015
Сообщений: 1
Вес репутации: 0
D1soft is an unknown quantity at this point
Smile Re: Ускоряем и улучшаем скетчи. Ещё одна библиотека.

Цитата:
Сообщение от Alex19279 Посмотреть сообщение
Минус ардуин что нет пошаговых отладчиков, нельзя без костылей отлаживать код, только метод тыка и подбора.
Вот пример отладки (англ.)
http://stackoverflow.com/a/16002424/1360210

вот видео (англ.)
http://www.instructables.com/id/Ardu...epoints-and-E/
D1soft вне форума   Ответить с цитированием
Ответ

Метки
arduino mega 2560, скетч, ардуино


Здесь присутствуют: 2 (пользователей: 0 , гостей: 2)
 
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 10:55. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Яндекс.Метрика