LINUX.ORG.RU

Сообщения KivApple

 

Отладка ошибки многопоточности

Форум — Development

Столкнулся с некоторой проблемой в своём проекте. Имеются сервисные функции засыпания-пробуждения нитей:

void Thread::resume() {
	pthread_mutex_lock(&m_sleepMutex);
	m_disableSleep++;
	pthread_mutex_unlock(&m_sleepMutex);
	pthread_cond_broadcast(&m_sleepCond);
}
		
static void Thread::sleep() {
	Thread* thread = current();
	pthread_mutex_lock(&(thread->m_sleepMutex));
	while (thread->m_disableSleep <= 0) {
		pthread_cond_wait(&(thread->m_sleepCond), &(thread->m_sleepMutex));
	}
	thread->m_disableSleep--;
	pthread_mutex_unlock(&(thread->m_sleepMutex));
}

А также некоторая логика:

Поток 1 взводит некую переменную-флаг, делает работу, а затем делает sleep.
Поток 2 в какой-то момент времени (но точно после установки флага, ибо в нём есть в некотором роде его проверка) сбрасывает флаг, а затем делает resume для потока 1.
Поток 1 просыпается и проверяет, почему его разбудили, проверяя флаг. Если флаг сброшен, то продолжает работу сначала, иначе выходит из цикла, ибо это показатель ошибки, если поток разбудили, а флаг не сбросили.

Проблема в том, что с некоторой небольшой вероятностью происходит состояние ошибки (поток 1 проснулся и увидел, что флаг не сбросили), хотя её быть не должно. При этом единственный код, который вызывает resume таки перед этим безусловно сбрасывает флаг (в настоящий момент других вызовов resume банально нет). Более того, если поставить точку останова на выход из цикла при обнаружении взведённого флага, то отладчик видит, что флаг сброшен.

Я также сделал проверку - передавал в resume булева-параметр (значение по умолчанию сделал false), который сохранял в классе потока. В коде, который сбрасывает флаг, передавал инвертированное текущее значение флага после сброса (то есть true). А в потоке 1 считывал поле класса потока в локальную переменную (а затем присваиваю полю класса false), а затем в новую локальную переменную - текущее состояние флага. В отладчике ставлю точку остановка на команду сразу после создания этих локальных переменных и получаю, что оба флага равны true, хотя такого быть не может (ибо другой поток присваивает полю класса значение обратное флагу).

Флаги описаны как voltatile bool, проект собирается с -O0, но это не помогает. При использовании условных точек остановка баг полностью пропадает (вероятно, многопоточность становится не такой многопоточной, если отладчик постоянно останавливает приложение и проверяет условие). Также можно просто забить на флаг и работать дальше вместо выхода из цикла - всё будет идеально работать. Но это не решение, потому что в будущем не сброшенный флаг будет свидетельствовать об ошибке. Пытался создать минимально работающую демонстрацию бага, но не получилось.

Как вообще такое отлаживать? Такое возможно, чтобы, например, это было следствием работы программы на многоядерной системе - значение флага закешировалось у одного ядра и новое дошло до него не сразу? Я пробовал добавлять __sync_synchronize между сбросом флага и вызовом resume, а также между sleep и проверкой флага, но это не помогло.

 ,

KivApple
()

Проблемы с беспроводной клавиатурой Logitech

Форум — Linux-hardware

Приобрёл недавно беспроводную клавиатуру и мышку Logitech (K360 и M560). У них обоих приёмник Unifying. Взял приёмник от клавиатуры, установил Solaar и забиндил к нему и мышку. В итоге всё отлично работало какое-то время, а сейчас начал иногда замечать проблему - в какой-то момент времени может появится огромная задержка между нажатием клавиши и реакцией компьютера. Может секунд 10 ничего не работать, а потом резко ввестись все нажатия, которые я сделал. При этом прямо в этот момент мышка отлично работает без каких-либо глюков. Проблема исчезает сама собой через какое-то время или мгновенно если включить-выключить клавиатуру. Батарейки используются комплектные и Solaar показывает 90% заряда для клавиатуры и 70% заряда для мыши.

В чём может быть проблема?

 

KivApple
()

Удалить плазмойд с рабочего стола

Форум — Desktop

У меня стоит ArchLinux с KDE5. Нечаянно добавил на рабочий стол плазмойд «Двумерный график» и теперь не могу его удалить. По правому клику менюшка не появляется (для других плазмойдов появляется менюшка, где есть пункт удаления). Могу только таскать его за края. Что делать? Не хотелось бы сносить весь профиль плазмы, потому что я её удобно для себя настроил.

 ,

KivApple
()

Замена Wi-Fi адаптера в ноутбуке

Форум — Linux-hardware

Имеется ноутбук HP 15 R161NR. Хочу заказать на AliExpress PCI-E Wi-Fi адаптер и заменить штатный. Зачем? Хочу поддержку не только 2.4, но и 5 ГГц. Однако есть два вопроса:

1) Это вообще получится на данном ноутбуке без каких-нибудь страшных вещей вроде перепрошивки BIOS? Вроде на некоторых ThinkPad с этим были проблемы (белый список Wi-Fi адаптеров вшитый в BIOS). У меня, конечно, HP, а не Lenovo, но мало ли. Не хочу потратить деньги на девайс, с которым потом ноутбук откажется работать.

2) Какие модели стоит выбирать, чтобы не было потом проблем с драйверами под Linux?

Сейчас в ноутбуке стоит вот это:

$ lspci | grep Wireless
0a:00.0 Network controller: Realtek Semiconductor Co., Ltd. RTL8723BE PCIe Wireless Network Adapter

 ,

KivApple
()

Django + FastCGI

Форум — Web-development

Решил я ради расширения кругозора попробовать серверного питона, а именно - фреймворк Django. С самой разработкой под него проблем не возникало, но никак не могу запустить его в production-режиме.

У меня есть веб-сервер lighttpd, соответственно, как я понимаю, Django должен быть запущен в FastCGI режиме (так написано в официальной инструкции - https://docs.djangoproject.com/en/1.8/howto/deployment/fastcgi/), а он в этом режиме запускаться отказывается:

./manage.py runfcgi ...
Unknown command: 'runfcgi'
Type 'manage.py help' for usage.

Перед этим сделал pip install flup6 (просто flup не ставился, потому что он оказывается несовместим с Python3 и везде говорят ставить flup6).

ЧЯДНТ?

 

KivApple
()

Преобразование значение по таблице

Форум — Development

Есть некая таблица преобразования, известная ещё на этапе компиляции. Содержит 10-20 значений типа int. Какого-либо математического закона преобразования нет, просто таблица.

Сейчас преобразование выглядит следующим образом:

int f(int a) {
    switch (a) {
        case X:
            return M;
        case Y:
            return N;
        case Z:
            return K;
        ... ещё 10-20 case'ов ...
        default:
            return -1;
    }
}

Выглядит громоздко. Как это можно реализовать лучше на plain C? Без привлечения сторонних библиотек. Можно запилить какую-нибудь самодельную реализацию хеш-таблицы (поскольку значения на этапе компиляции известны, запихнуть их в массив в отсортированном порядке, а затем в рантайме искать двоичным поиском). Таблиц преобразований несколько (но все по отдельности небольшие), так что на размере кода это должно сказаться благоприятно (ведь можно вынести поиск в отдельную функцию). Но будет ли это эффективнее по скорости, чем простой switch на небольшом объёме данных?

 ,

KivApple
()

Тулчайн CMake

Форум — Development

Хочу попробовать использовать CMake для сборки прошивок для микроконтроллеров. Разумеется, для этого требуется другой тулчайн (arm-none-eabi) вместо системного. Как я понимаю, есть два варианта:

1) Тупой. Сделать SET(CMAKE_C_COMPILER «arm-none-eabi») внутри CMakeLists.txt проекта.

2) Умный. Сделать специальный файлик тулчайна, где прописать все необходимые опции. А затем подсунуть его в переменную CMAKE_TOOLCHAIN_FILE.

Проблема в том, что второй вариант рекомендуют делать с помощью опций запуска CMake. Типа cmake -DCMAKE_TOOLCHAIN_FILE=...

Однако в случае с прошивкой для микроконтроллера возможность лёгкого выбора целевой платформы не имеет смысла, так как весь код всё равно заточен под конкретный МК. Более того, попытка компиляции с нативным тулчайном гарантированно обломается. Соответственно, хотелось бы как-нибудь прописать тулчайн прямо внутри CMakeLists.txt, а не указывать его явно. Однако SET(CMAKE_TOOLCHAIN_FILE ...) не срабатывает. Вероятно, чтение этой переменной происходит раньше, чем исполнение команд из файла проекта.

Что делать? Как правильно сменить тулчайн и при этом по возможности как-то жёстко это зафиксировать, а не указывать в опциях командной строки при запуске CMake?

 , ,

KivApple
()

Широкие мониторы

Форум — Talks

Речь пойдёт не про стандартные широкоформатные мониторы, а про более продвинутые варианты - экраны 21:9. Да, фильмы будут без рамок и в каких-то играх обзор лучше. Но меня интересует в первую очередь не это.

Насколько такие мониторы удобны с точки зрения программиста? Вот я, например, иногда подрабатываю веб-разработкой. Можно будет, скажем, открыть на пол-экрана IDE и на пол-экрана браузер. По идее должно быть удобно.

Что лучше? Широкий монитор или два обычных? Широкий монитор в принципе выгоднее (я знаю вариант всего в 1.5 раза дороже, чем монитор с аналогичными характеристиками, но обычный Full HD IPS). Но, быть может, мне вообще не стоит переплачивать и взять один монитор, если я не геймер, не киноман и не дизайнер.

Есть тут обладатели широких мониторов, которые используют их для кодинга?

P. S. Испытываю нехватку места на своём ноутбучном 1366 х 768, поэтому задумался о покупке внешнего монитора.

 

KivApple
()

Организация небольшого проекта на Python

Форум — Development

Запилил маленькую консольную утилиту для генерации заголовочных файлов с описанием регистров и прерываний (пример - http://pasted.co/31caec09), а также скрипта линковщика (а ещё выводит необходимые ключики компилятора). Полезно при программировании некоторых микроконтроллеров (в данный момент поддерживается лишь два семейства ARM).

Проект небольшой, но таки состоит из нескольких файлов. Хотел бы узнать как правильно его структурировать (или все py-файлы в корне это ок?). А также как облегчить его установку и опакечивание (в случае C/C++ проекта я бы добавил цели install/uninstall в Makefile).

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

Ссылка: https://github.com/KivApple/mcu-info-util

 

KivApple
()

Предупреждения BTRFS

Форум — General

Пришёл долгожданный optibay и я вернул жёсткий диск в мой ноутбук, заменив им оптический дисковод (ранее я заменил HDD на SSD и накатил систему с нуля).

На диске была ext4 и файлы (в принципе, не сказать чтобы прямо совсем критичные, но не хотел их удалять). Я сконвертировал файловую систему жёсткого диска в btrfs, примонтировал, удалил резервную копию ext4 (это выражается в удалении субтома ext2_saved). Вроде всё работает.

Перенёс всё старое в каталог old-system в корне, также перенёс в корень домашний каталог своего пользователя. Смонтировал диск как /home, закрепив это в fstab. Перезагрузился. УМВР.

После этого рекомендуют выполнить дефрагментацию и ребалансировку древа.

# btrfs fi defrag -r /home && btrfs balance start /home
ERROR: defrag failed on /home/old-system/var/tmp/kdecache-kiv/icon-cache.kcache: Input/output error
ERROR: defrag failed on /home/kiv/.dropbox-dist/dropbox-lnx.x86_64-6.4.14/dropbox: Success
total 2 failures
# btrfs balance start /home
WARNING:

        Full balance without filters requested. This operation is very
        intense and takes potentially very long. It is recommended to
        use the balance filters to narrow down the balanced data.
        Use 'btrfs balance start --full-balance' option to skip this
        warning. The operation will start in 10 seconds.
        Use Ctrl-C to stop it.
10 9 8 7 6 5 4 3 2 1
Starting balance without any filters.
ERROR: error during balancing '/home': Input/output error
There may be more info in syslog - try dmesg | tail
[root@kiv-hp15r161nr ~]# dmesg | tail
[11397.780166] BTRFS info (device sdb2): found 511 extents
[11398.146912] BTRFS info (device sdb2): relocating block group 729213304832 flags 4
[11399.980078] BTRFS info (device sdb2): found 509 extents
[11400.791373] BTRFS info (device sdb2): relocating block group 729204916224 flags 4
[11402.324515] BTRFS info (device sdb2): found 511 extents
[11402.680300] BTRFS info (device sdb2): relocating block group 729196527616 flags 4
[11404.002392] BTRFS info (device sdb2): found 512 extents
[11404.247011] BTRFS info (device sdb2): relocating block group 729171361792 flags 1
[11404.438483] BTRFS warning (device sdb2): csum failed ino 824 off 1048576 csum 1775494736 expected csum 39867248
[11404.438680] BTRFS warning (device sdb2): csum failed ino 824 off 1048576 csum 1775494736 expected csum 39867248

Как я должен это понимать? Всё плохо и мне надо срочно копировать ценные данные обратно на SSD и пересоздавать ФС? Или это нормальная ситуация? Как мне её следует исправить?

 

KivApple
()

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

Форум — Talks

После прочтения очередной новости про наказания для операторов мессенджеров у меня возникла идея (мне самому это, конечно не нужно, просто вольная фантазия на заданную тематику).

Ведь есть альтернатива использованию всяких Telegram, I2P и подобного.

1) Шифруем сообщение любыми средствами, переводим в base64, отправляем личным сообщением Facebook, ВКонтакте или любой другой соцсети. Ну а что, правилами же не запрещено, если второй собеседник не против, чтобы я слал ему бессмысленный набор букв (если против, то это уже спам будет). Разумеется, не обязательно это делать ручками, можно использовать специальный клиент, который будет логинится через API соцсети, но при получении и при отправке сообщений шифровать/дешифровать текст.

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

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

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

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

По-любому, я не первый кто до этого догадался. Интересно узнать, кто уже до этого доходил ранее. И да, суть именно в автоматизированном решении для соцсетей. А также какие подводные камни есть у этой идеи. Я пока не вижу способов защититься от этого. Даже если разрешить только официальные клиенты, ничто не мешает пользователю копипастить сообщения из программы и обратно в программу.

 , ,

KivApple
()

Производительность C++

Форум — Development

Как насчёт производительности у C++ по сравнению с C? Мои предположения на текущий момент:

1) Код, не использующий возможности C++ (то есть по сути plain C), скомпилированный C++ компилятором будет иметь абсолютно ту же производительность, что и код на С.

2) Исключения и dynamic_cast медленные. Если нам важна производительность, лучше их не использовать.

3) Класс без виртуальных методов, должен быть по производительности эквивалентен сишной структуре и функциям, обрабатывающим её. Не считая копирования. Нужно везде, где можно использовать передачу по указателю или ссылке (собственно, если в Си делать memmove при передаче структуры в качестве аргумента, то это вызовет примерно такой же оверхед, как дефолтный конструктор копирования С++. Верно?).

4) Класс с виртуальными методами полностью аналогичен пункту 3, но при вызове виртуальных методов добавляется небольшой оверхед. Сишный эквивалент obj->vtable->func(obj, ...). Если сравнивать с plain C кодом, реализующим ООП в той же манере (каждая структура-объект имеет поле, указывающее на структуру, содержащую адреса функций работы с ней), то оверхеда по сравнению с plain C не должно быть.

5) При использовании атрибута класса final (если компилятор поддерживает соответствующий стандарт) даже при наличии виртуальных методов в нём, их вызов будет превращаться в прямые вызовы функций вместо обращения к vtable, если переменная имеет соответствующий тип, а не указатель/ссылка на его предка (который не final).

6) Шаблоны могут привести к разбуханию кода. Впрочем, #define-ы и inline-функции в C++ могут устроить то же самое. Вопрос: будет ли использование шаблона с одинаковыми параметрами создавать 2 копии реализации или же всё-таки компилятор догадается сделать её лишь один раз. А если шаблон используется с одинаковыми параметрами в нескольких объектных файлах? Будет ли реализация расшариваться между ними или у каждого своя?

7) Что насчёт inline-методов класса? (те, которые описываются прямо в момент определения самого класса, внутри блока class). Может ли их реализация расшариваться между модулями или в каждом будет своя копия (допустим, метод слишком длинный, чтобы инлайнится в момент вызова)?

Я не претендую на правоту, какие-то утверждения могут быть ложными. Хотел бы узнать, как обстоят дела на самом деле. А также какие подводные камни я ещё не знаю. Разумеется, речь идёт о последних версиях gcc/clang с включённой оптимизацией не ниже -O2.

 ,

KivApple
()

Падают некоторые приложения KDE

Форум — Desktop

Я наконец-то купил себе SSD и воткнул в свой ноутбук вместо HDD (HDD верну в качестве /home раздела, когда придёт из Китая optibay). В связи с этим переустановил систему (Arch Linux x86_64).

И что же я получил? Пытаюсь удалить файл в Dolphin (не важно Shift + Del или просто Del или же выбрать пункт контекстного меню) - и Dolphin падает. Вылазит окошко обработчика ошибок KDE, которое радостно сообщает, что собранная о сбое информация «скорее всего бесполезна». Жмякую по ссылке «список необходимых файлов», чтобы поискать какие пакеты ещё поставить на packages.archlinux.org - и тут уже падает сам обработчик ошибок.

Также падает приложение системных настроек KDE иногда при применении изменений (изменения при этом применяются).

Зато плазма вообще не падает, да.

Что интересно - на старой системе такой фигни не было. Хотя там было точно также обновлённое всё. Возможно, сейчас я поставил чуть больше/чуть меньше пакетов. Ну либо за прошлую ночь вышло какое-то обновление, которое всё сломало.

В какую сторону вообще копать? Я могу смириться со падением утилиты настроек (изменения то применяются), но вылеты Dolphin при удалении файла - это уже выходит за все рамки.

UPD: http://pastebin.com/rt6icMrr - вот стеквызовов падения Dolphin при удалении файла.

 ,

KivApple
()

Проектирование печатной платы

Форум — Science & Engineering

Меня уже давно интересует тема создания самодельного нейроинтерфейса. И какое-то время назад я даже приобрёл микросхему АЦП ADS1298, которая должна отлично подойти для снятия сигналов без каких-либо предусилителей и фильтров (фильтровать шумы можно уже цифровым методом, потому что точности оцифровки хватит на всё).

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

Итак, у меня есть сама микросхема, малощумящие линейные стабилизаторы TPS76933 (надо же чем-то сделать 3.3В из 3.7В от литий-полимерного аккумулятора), сборка 4 резисторов 2.2 кОм в едином корпусе (100 штук, может быть использовано для защиты входов от статики), защитные диоды TPD4E1B06 (совместно с резисторами - защита входов от статики), выкупленный лот (в смысле заказ оплачен, но Gerber-файлы не загружены) на сайте ITEAD Studio на изготовление 10 двухсторонних плат 5 х 5 см. Также есть принципиальная схема и разводка печатной платы моего авторства, выполненные в DipTrace. Однако есть два «но» - я ошибся и использовал не тот корпус для микросхемы (так что всё придётся переделывать) и я не уверен в качестве разводки и оптимальности схемы.

Требуется: проверить правильность схемы (исправить, если что) и спроектировать печатную плату, на которой бы была вся обвязка АЦП и с одной стороны на гребёнку 2х8 (8 каналов, каждый имеет входы + и -) были выведены входы АЦП, а с другой стороны на гребёнку - питание (3.5-5В, стабилизаторы должны быть размещены на самой плате, желательно сделать аналоговое и цифровое питание от разных стабилизаторов) и сигналы интерфейса SPI (выделенные пины RESET, SLEEP и т. д. мне не нужны, ибо эти режимы можно активировать и по SPI, нужны только SCK, MOSI, MISO, SS и выход прерывания DRDY). Плата должна иметь минимальный размер, при котором не испортятся параметры (всё-таки на голову вешать). Спаяю плату я сам.

Сколько это может стоить? Может ли кто-то из вас за такое взяться?

Возможно, кто-то может захотеть поучаствовать в проекте за «спасибо» (я таки студент-нищеброд)?

Все схемы, прошивки и программы выложу под OpenSource-лицензией.

 , нейроинтерфейс, ,

KivApple
()

Пьезоэлектрический датчик давления

Форум — Science & Engineering

Попросили меня помочь разобраться с пьезоэлектрическим датчиком давления.

Известны параметры:

Чувствительность: 20 пКл/бар

Измеряемый диапазон: 0.1-250 бар

Электрическая ёмкость: 7..12 пФ

Сопротивление изоляции: 10 ^ 10 Ом

Чувствительный элемент: кварц

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

Первым делом я вспомнил формулу ёмкости конденсатора из школьной программы: C = q/U => U = q/C. И после нехитрых расчётов (250 бар * 25 пКл/бар) / 12 пФ, получается, что датчик может выдавать сотни вольт. Что я не учитываю?

Вторым делом я нагуглил схему усилителя заряда. Точнее вот этот документ: http://phys.rsu.ru/web/petin/analog.pdf (начиная со страницы 43).

Рассчитал по формулам из этого документа номиналы компонентов цепи обратной связи. R=2 МОм, C = 2.2 нФ. Взлетит? С учётом того, что я собираюсь снимать данные с помощью АЦП STM32 (так что макс. напряжение 3.3В на выходе должно быть). Не совсем понял требования к ОУ. Скажем, в следующем разделе для «усилителей медленно меняющихся сигналов» есть требование, чтобы у ОУ был очень маленький входной ток (пикоамперы) и рекомендуют TL082, а вот к этой схеме рекомендаций нет. Туда можно воткнуть дешёвый LM358 или всё же есть какие-то требования кроме полосы пропускания?

 

KivApple
()

Вопрос по лицензии QBS

Форум — Talks

В составе проекта Qt есть система сборки QBS. Она достаточно гибкая и может быть использована для сборки отнюдь не только проектов, использующих библиотеку Qt.

Вопрос: можно ли собирать с помощью QBS проприретарщину (или просто что-то несовместимое по лицензии с Qt) не имея коммерческую лицензию Qt? При условии, что конечный продукт линковаться и как-либо использовать Qt не будет, только систему сборки и встроенные скрипты сборки для C++ (но, разумеется, от скриптов ничего не останется в исполняемом файле, они просто подёргают компилятор с нужными параметрами).

Второй вопрос: а если использовать QBS со своими собственными скриптами сборки - должны ли они обязательно быть под OpenSource?

Вообще, я хочу написать качественные скрипты для использования QBS для программирования различных микроконтроллеров и выложить их в паблик (сейчас я находил только более-менее костыльные решения «лишь бы работало», а я хочу сделать всё красиво и аккуратно - с генерацией скриптов линкера по имени МК, с поддержкой некоторых RTOS). Однако я хотел бы, чтобы если кто-нибудь будет их использовать, то он не был обязан публиковать исходники прошивки просто потому что использовал QBS для сборки.

А ещё интересно есть ли какие-то ограничения под какой лицензией я могу публиковать свои скрипты сборки.

 ,

KivApple
()

Небольшой вопрос про операционный усилитель

Форум — Science & Engineering

Имеется простая схема. ШИМ-сигнал 30 кГц 50% заполнение с микроконтроллера проходит через RC-цепь (15 кОм и 100 нФ), чтобы стать аналоговым (в итоге получается хороший постоянный сигнал с очень маленькими пульсациями). Затем он усиливается по току с помощью операционного усилителя LM358 в буферном включении (сигнал подан на неинвертирующий вход, выход ОУ и инвертирующий вход соединены напрямую). И на выходе ОУ присутствует тот же самый сигнал, плюс добавляются микроскопические (на грани возможностей осциллографа) ВЧ-помехи. Всё бы хорошо... но.

Подключаем между выходом ОУ и землёй конденсатор 100 нФ (типа для стабилизации значения на всякий случай). И получаем на выходе синусоиду с амплитудой где-то 0.5В. Ладно, не очень то нам и нужен этот конденсатор, убираем.

Вообще, данный ОУ подключен в буферным режиме не случайно, ибо данный сигнал используется дальше по схеме. И так получается, что он подключен в том числе к одному концу резистора 47 кОм, на другой контакт которого периодически подаются короткие (30 кГц 1% заполнение) импульсы 12В.

Я ожидаю, что эти импульсы никак не должны влиять на буферизованный сигнал. Ведь 12В / 47 кОм = 250 мкА. А в реальности там даже чуть меньше, ибо уровень сигнала ОУ около 1.5В, а не 0В, поэтому разность потенциалов, и как следствие ток, меньше. А они влияют. Не синусоида, конечно, как с конденсатором, но есть ярко выраженные сильные искажения сигнала в момент прихода импульсов (тоже примерно 0.5-1В амплитудой).

Если симулировать такую схему в Proteus (http://i.imgur.com/gxG5kcQ.png, тут сразу и конденсатор на выходе, и генератор импульсов 12В, пробовал и всё сразу, и что-то одно), то никаких проблем нет. Но, разумеется, данный софт может банально не учитывать какие-то физические законы, поэтому к нему претензий нет.

Вопрос знатокам - в чём проблема? Почему схема плохо себя ведёт? Как это можно исправить? Быть может, мне нужен другой ОУ, а я и не знаю? По какому принципу выбрать замену? Или я делаю что-то, что вообще не должно работать?

 операционный усилитель,

KivApple
()

Управление шаговым двигателем

Форум — Science & Engineering

Пытаюсь управлять шаговым двигателем FL57STH76-2804A. Для этого изготовил следующую схему управления - один конец каждой обмотки (A- и B-) подключен к средней точке питания (в настоящий момент биполярного БП у меня нет, поэтому используется конденсаторная средняя точка с резисторным делителем напряжения для защиты от уплывания средней точки). Второй конец каждой обмотки (A+ и B+) подключен к полумосту на двух IRFZ48N. Управляет каждым полумостом драйвер IR2104 (резисторы на затворах 10 ом). Драйвера же полумостов управляются с микроконтроллера STM32F103. Параллельно каждой обмотке шагового двигателя установлен конденсатор 330 нФ. Частота ШИМ 30 кГц. Питаю от БП 12В, то есть на обмотки реально идёт +-6В. Проверял осциллографом - просадки на средней точке во время работы не превышают +-200мВ.

Я успешно запустил шаговый двигатель как в полношаговом, так и в микрошаговом режиме, однако при вращении присутствует определённая неравномерность и вибрации. Хотелось бы от них избавиться.

Вот алгоритм управления двигателем:

static const int16_t sinTable[256] = {
   0, 6, 12, 18, 24, 31, 37, 43, 49, 55, 61, 68, 74, 79, 85, 91,
   97, 103, 109, 114, 120, 125, 131, 136, 141, 146, 151, 156, 161, 166, 171, 175,
   180, 184, 188, 193, 197, 201, 204, 208, 212, 215, 218, 221, 224, 227, 230, 233,
   235, 237, 240, 242, 244, 245, 247, 248, 250, 251, 252, 253, 253, 254, 254, 254,
   255, 254, 254, 254, 253, 253, 252, 251, 250, 248, 247, 245, 244, 242, 240, 237,
   235, 233, 230, 227, 224, 221, 218, 215, 212, 208, 204, 201, 197, 193, 188, 184,
   180, 175, 171, 166, 161, 156, 151, 146, 141, 136, 131, 125, 120, 114, 109, 103,
   97, 91, 85, 79, 74, 68, 61, 55, 49, 43, 37, 31, 24, 18, 12, 6,
   0, -6, -12, -18, -24, -31, -37, -43, -49, -55, -61, -68, -74, -79, -85, -91,
   -97, -103, -109, -114, -120, -125, -131, -136, -141, -146, -151, -156, -161, -166, -171, -175,
   -180, -184, -188, -193, -197, -201, -204, -208, -212, -215, -218, -221, -224, -227, -230, -233,
   -235, -237, -240, -242, -244, -245, -247, -248, -250, -251, -252, -253, -253, -254, -254, -254,
   -255, -254, -254, -254, -253, -253, -252, -251, -250, -248, -247, -245, -244, -242, -240, -237,
   -235, -233, -230, -227, -224, -221, -218, -215, -212, -208, -204, -201, -197, -193, -188, -184,
   -180, -175, -171, -166, -161, -156, -151, -146, -141, -136, -131, -125, -120, -114, -109, -103,
   -97, -91, -85, -79, -74, -68, -61, -55, -49, -43, -37, -31, -24, -18, -12, -6
};

void setStepperState(int curStep) {
   static const uint16_t microstepCount = sizeof(sinTable) / sizeof(sinTable[0]);
   uint16_t curMicrostep = curStep % microstepCount;
   int16_t phaseA = sinTable[curMicrostep];
   int16_t phaseB = -sinTable[(curMicrostep + 64) % microstepCount];
   uint32_t polarityA = (phaseA < 0) ? PAL_HIGH : PAL_LOW;
   uint32_t polarityB = (phaseB < 0) ? PAL_HIGH : PAL_LOW;
   palWritePad(GPIOB, 1, polarityA); // INA
   pwmEnableChannel(&PWMD3, 0, abs(phaseA)); // ENA
   palWritePad(GPIOB, 10, polarityB); // INB
   pwmEnableChannel(&PWMD3, 1, abs(phaseB)); // ENB
}

...

while (1) {
   for (int i = 0; i < 65536; i++) {
      setStepperState(i);
      chSysPolledDelayX(US2RTC(STM32_SYSCLK, 200));
   }
}

По идее ШИМ на обмотках при шагах должен изменяться следующим образом - http://i.imgur.com/kCMfHQP.png.

При низких скоростях, если режим не полношаговый (достигается умножением i на 64 при вызове setStepperState) двигатель перестаёт крутиться (дёргается на месте).

В чём может быть проблема? У меня ошибка в алгоритме переключения обмоток? Или проблема может быть лишь в силовой части схемы?

 , шаговый двигатель

KivApple
()

Обёртка над Posix Timers

Форум — Development

Написал для своего небольшого проекта обёртку над таймерами Posix.

class VirtualTimer {
	private:
		pthread_mutex_t _mutex;
		
		timer_t _posixTimer;
		
		uint32_t _period;
		
		TimerCallback _callback;
		
		void *_callbackArg;
		
		volatile bool _armed;
		
		static void posixTimerCallback(union sigval val);
		
	public:
		VirtualTimer(uint32_t period = 0, TimerCallback callback = NULL, void *arg = NULL);
		
		~VirtualTimer();
		
		void setCallback(TimerCallback callback, void *arg);
		
		bool setPeriod(uint32_t period);
		
		uint32_t getPeriod() {
			return _period;
		}
		
		void start();
		
		void stop();
		
		bool isArmed() {
			return _armed;
		}
		
};

VirtualTimer::VirtualTimer(uint32_t period, TimerCallback callback, void *arg) {
	_period = period;
	_callback = callback;
	_callbackArg = arg;
	_armed = false;
	pthread_mutex_init(&(_mutex), NULL);
	struct sigevent sev;
	sev.sigev_notify = SIGEV_THREAD;
	sev.sigev_notify_function = posixTimerCallback;
	sev.sigev_value.sival_ptr = this;
	int r = timer_create(CLOCK_MONOTONIC, &sev, &(_posixTimer));
	assert(r == 0);
	if (_period > 0) {
		start();
	}
}

VirtualTimer::~VirtualTimer() {
	timer_delete(_posixTimer);
	pthread_mutex_lock(&(_mutex));	
	pthread_mutex_destroy(&(_mutex));
}

void VirtualTimer::posixTimerCallback(union sigval val) {
	VirtualTimer *timer = (VirtualTimer*)val.sival_ptr;
	pthread_mutex_lock(&(timer->_mutex));
	if ((timer->_callback != NULL) && (!timer->_callback(timer->_callbackArg))) {
		timer->stop();
	}
	pthread_mutex_unlock(&(timer->_mutex));
}

void VirtualTimer::setCallback(TimerCallback callback, void *arg) {
	_callback = callback;
	_callbackArg = arg;
}

bool VirtualTimer::setPeriod(uint32_t period) {
	_period = period;
	if (_armed) {
		start();
	}
	return true;
}

void VirtualTimer::start() {
	time_t sec = _period / 1000000;
	long nsec = (_period % 1000000) * 1000;
	struct itimerspec newValue = {
		.it_interval = {
			.tv_sec = sec,
			.tv_nsec = nsec
		},
		.it_value = {
			.tv_sec = sec,
			.tv_nsec = nsec
		}
	};
	int r = timer_settime(_posixTimer, 0, &newValue, NULL);
	assert(r == 0);
	_armed = true;
}

void VirtualTimer::stop() {
	struct itimerspec newValue = {};
	int r = timer_settime(_posixTimer, 0, &newValue, NULL);
	assert(r == 0);
	_armed = false;
}

Имеется проблема. Допустим, таймер срабатывает и вызывается callback. Однако в этот же момент поток, создавший таймер, решает, что хватит дожидаться его срабатывания и уничтожает объект. В итоге callback (с самого начала или на своей середине) будет работать с уничтоженным объектом и это может привести к печальным последствиям.

Сейчас это частично решается с помощью mutex. Если callback успеет захватить mutex, то деструктор будет терпеливо ждать, пока callback отработает (новый callback уже точно не вызовется, потому что таймер дизармится перед захватом mutex) и только потом уничтожит таймер. Однако если нет? Если деструктор успеет захватить mutex, затем будет вызван callback (callback уже может быть вызван, но таймерный поток ожидает своего кванта времени в очереди планировщика ОС, пока работает деструктор), который будет ждать mutex, который потом уничтожат (что уже само по себе будет плохо, и либо будет зависание таймерного потока, либо обращение к освобождённой области памяти)? Будет плохо.

Как эту ситуацию разрулить?

 ,

KivApple
()

Rust как язык для программирования микроконтроллеров

Форум — Science & Engineering

Собственно сабж. А то часто вижу всякие статьи, где Rust пиарится как «убийца сишечки». Вот даже недавно ОС на Rust вышла. А программирование микроконтроллеров - как раз одна из тех областей, где C на сегодняшний день практически не имеет конкурентов.

Ну так насколько он годен для этого? Сильно ли распухнет код? А что с производительностью? Как со всякими специфичными фичами (обработчики прерываний часто требуют иных прологов/эпилогов, также нужна возможность пихать функции и переменные в не стандартные секции линкера и т. д.)?

Насколько он юзабелен без кучи рантайма? Вот попробовал простую программу кросс-компилировать под STM32 с #![no_std] - так не собралось же. Требует как минимум библиотеку core (и в стабильной версии вроде как нет возможности её отрубить). Насколько эта библиотека жирна?

А что со всякими микроконтроллерами послабее типа всяких AVR, PIC, STM8, MSP430. Как я понимаю, тут уже всё зависит напрямую от LLVM. Для AVR порт есть, для MSP430 тоже (правда, экспериментальный). Вроде как запилить в случае чего LLVM-backend не очень сложно, но есть важный вопрос - насколько оно будет хорошо работать. Есть ли какие-то проигрыши по эффективности или размеру кода, если вместо прямой компиляции (с помощью gcc или sdcc) использовать llvm?

 , ,

KivApple
()

RSS подписка на новые темы