Страницы

Поиск по вопросам

среда, 8 мая 2019 г.

Можно ли и как программировать AVR микроконтроллер (attiny13) силами самого микроконтроллера?

Т.е. задача такая, иметь возможность с помощью кнопок, подключенных к микроконтроллеру, запрограммировать его без перепрошивки и без написания интерпретатора (первое, что пришло в голову - fort). Т.е. сохранить и вызвать функцию в которой используется ограниченный набор команд, принимается один числовой параметр и возвращается один числовой параметр. Спасибо!
Пояснение
Необходимо:
Загрузиться Сгенерировать байткод прямо в программе Передать ему выполнение После окончания его работы вернуться в место вызова и получить результат.
Примером самой простой подпрограммы может быть: var + 1.


Ответ

Ответ ДА :) Сам не пробовал. Фрагмент статьи с хабра
Самым распространенным и удобным интерфейсом для прошивки AVR является SPI (Serial Peripheral Interface). Для подключения по SPI нужно всего четыре провода, не считая земли: SCK — тактовый сигнал, синхронизирует все операции обмена данными; MOSI (Master Out Slave In) — линия данных от ведущего устройства к ведомому; MISO (Master In Slave Out) — линия данных, наоборот, от ведомого устройства к ведущему; RESET — для разрешения прошивки по SPI нужно подать логический «0» на этот вывод.
Схема: кнопки от VCC на пины Reset, Mosi, Sck, после нажатия подтянуты к земле резисторами. Пин GND на землю, с пина Miso светодиод с резистором на землю.
Режим программирования включается подачей «0» на ногу RESET. Но есть некоторые тонкости. Atmel рекомендует сначала выставить на выводах RESET и SCK низкий уровень, а только потом подавать на контроллер питание. Если такой возможности нет, нужно после включения питания подать «0» на SCK, а затем положительный импульс на RESET
Далее нужно передать команду на собственно включение режима программирования: 10101100 01010011 xxxxxxxx xxxxxxxx Биты, обозначенные как x, могут быть любыми. Во время передачи третьего байта контроллер должен переслать обратно второй байт (01010011). Если это произошло, значит, все хорошо, команда принята, контроллер ждет дальнейших инструкций. Если ответ отличается, нужно перезагрузить МК и попробовать все сначала.
Сначала необходимо загрузить данные в буфер страницы, для этого используется команда «Load Program Memory Page» 01000000 000xxxxx xxxxbbbb iiiiiiii — для загрузки младшего байта слова, и 01001000 000xxxxx xxxxbbbb iiiiiiii — для загрузки старшего. 4 младших бита 3-го байта команды bbbb — адрес слова на странице, iiiiiiii — загружаемый байт. Сначала всегда должен загружаться младший байт слова, а затем — старший байт того же слова.
После того, как буфер страницы загружен, нужно выполнить команду «Write Program Memory Page» 01001100 0000000a bbbbxxxx xxxxxxxx для записи страницы непосредственно в память контроллера. Младший бит второго байта и старшие 4 бита третьего a:bbbb — пятибитный номер страницы для записи.
Лучше в подробностях смотреть по ссылке. На случай необитаемого острова распечатать даташит, заламинировать, хранить с собой.

Шутки браузеров: криво работает php валидация?

Я тестирую в основном сайт в Google Chrome (посл. версия), и только что заметил, что Opera (последняя версия) позволяет обойти ОБЯЗАТЕЛЬНОЕ ТРЕБОВАНИЕ заполнить возраст. Просто игнорирует это поле и даже успешно отправляется форма и тп.
Ссылка на форму
А также наверно какие-то старые браузеры умудряются еще регать людей с НЕВОЗМОЖНЫМ значением пола, например.
Т.е. Опера в данном случае игнорит и JS, и PHP валидацию. Это вообще законна такая работа PHP и браузеров?
Использую rules:
$rules[] = array( 'gender', 'required', 'message' => 'Укажите пол' ); $rules[] = array( 'birthYear', 'required', 'message' => 'Укажите год рождения' ); $rules[] = array('gender', 'in', 'range' => array("f", "m", "?"), 'message' => 'Укажите пол.');
Обновление
Добавил еще правило:
$rules[] = array( 'birthYear', 'length', 'min'=>$AGE_START, 'max'=>$AGE_END, 'tooShort' => 'Укажите год рождения', 'tooLong' => 'Укажите год рождения', );
Опера перестала глючить.


Ответ

К вам на сервер от клиента (в данном случае браузер) могут прийти какие угодно данные. Валидация данных всегда должна быть на сервере помимо JS. Если у вас регистрация проходит даже без обязательных полей, значит у вас некорректный PHP код с валидацией.
UPD
Лучше не обращаться к массиву $_POST напрямую. К тому же, в вашем выпадающем списке есть пустое значение. Один браузер его вам посылает, другой нет. Получается при обращении к $_POST['Form']['gender'] у вас в одном случае строка пустая, в другом случае null (не факт, это моё предположение).
Проверьте $_POST массив в контроллере в разных браузерах:
var_dump($_POST); die();
Вам может помочь либо метод saveAttributes(), либо как минимум проверка на пустое значение:
if(isset($_POST['Form']['gender']) && $_POST['Form']['gender'] != '') { $form->gender = $_POST['Form']['gender']; }

Проверить установку пакета

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


Ответ

Проверка на то, установлено ли приложение:
boolean installed = appInstalledOrNot("com.Example.kek");
private boolean appIsInstalled(String uri) { PackageManager pm = getPackageManager(); boolean app_installed; try { pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES); app_installed = true; } catch (PackageManager.NameNotFoundException e) { app_installed = false; } return app_installed; }

Как добавить файл в 7-zip архив с сохранением структуры каталогов?

Использую SevenZipSharp
SevenZipCompressor.SetLibraryPath("7z.dll"); SevenZipCompressor szc = new SevenZipCompressor(); szc.DirectoryStructure = true; szc.PreserveDirectoryRoot = true; szc.ZipEncryptionMethod = ZipEncryptionMethod.Aes256; szc.CompressionMode = CompressionMode.Create;
Если добавить несколько файлов сразу, то каталоги создаются нормально
szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test2\123.txt", @"C:\Test\Test\123.txt", @"C:\Test\123.txt");
А если добавлять по одному, то все файлы записываются в корень архива.
szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test2\123.txt"); szc.CompressionMode = CompressionMode.Append; szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\Test\123.txt"); szc.CompressFilesEncrypted("test.7z", "123", @"C:\Test\123.txt");
В итоге получается 3 файла 123.txt в корне.
Что я делаю не так? Как добавлять по одному файлу с сохранением полного пути?


Ответ

Нужно передавать длину общего пути для всех файлов:
string commonPath = "C:\\Test\\"; int commonPathLength = commonPath.Length;
szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\Test2\123.txt"); szc.CompressionMode = CompressionMode.Append; szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\Test\123.txt"); szc.CompressFilesEncrypted("test.7z", commonPathLength, "123", @"C:\Test\123.txt");

Судя по исходникам (к сожалению, у проекта нету документации), метод CompressFilesEncrypted отличает часть пути, которая принадлежит архиву, от части пути внутри архива, при помощи вычисления общей части пути всех переданных файлов.
public void CompressFilesEncrypted( string archiveName, string password, params string[] fileFullNames) { CompressFilesEncrypted(archiveName, CommonRoot(fileFullNames), password, fileFullNames); }
То есть, если переданы файлы C:\Test\Test2\123.txt и C:\Test\Test4\123.txt, то общей частью будет C:\Test\. А вот для одного файла общей частью оказывается весь путь.
Поэтому и приходится вычислять нужную общую длину вручную, и передавать, используя перезагрузку с длиной.

java.text.ParseException: Unparseable date

Столкнулся с проблемой, не работает следующий java - код:
String s_date = " Ср, 16 12 2015 16:24:31 GMT"; SimpleDateFormat sdf = new SimpleDateFormat( " dd MM yyyy hh:mm:ss " ); Date date = sdf.parse( s_date ); System.out.println( sdf.format( date ) );
Выкидывает:
java.text.ParseException: Unparseable date: " Ср, 16 12 2015 16:24:31 GMT"
Можно конечно обрезать первые пять символов и последние четыре. Но у меня будет много разных форматов дат, и для каждой разный подход. Как сделать чтобы SimpleDateFormat.parse(), парсил только то что указано?
Если в коде не видно, я в задании шаблона подставил 5 пробелов в начале и 4 в конце, это не помогло.


Ответ

Конкретно в вашем случае надо править форматную строку:
// было: "dd MM yyyy hh:mm:ss" // модификации: EEE - день недели строкой, HH - час 0-23, zzz - временная зона SimpleDateFormat sdf = new SimpleDateFormat( " EEE, dd MM yyyy HH:mm:ss zzz", new Locale("ru", "RU") ); Date date = sdf.parse( s_date ); System.out.println( sdf.format( date ) ); //Вывод: Ср, 16 12 2015 19:24:31 MSK
Новое API:
DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern( "E, d M y H:m:s z", new Locale("ru", "RU") ); ZonedDateTime newDate = ZonedDateTime.parse( s_date.trim(), newFormatter ); System.out.println( newFormatter.format( newDate )); // Вывод: Ср, 16 12 2015 16:24:31 GMT

Режет форму на разных ОС (Win7/Win10)&Win8.1

Написал небольшое приложение. И на кросс-платформенности споткнулся. Что имеем:
Win10, разрешение 1366х768

Win10, разрешение 800х600

А теперь Win8.1, разрешение 1920х1080
На Win8 срезает кусок формы, тем самым пропадает кнопка нижняя и боковая, что вообще неприемлемо, да и textbox-ы подрезает немного. Платформа .NET 2.0 (нужна именно она, перекомпилить в .NET 4+ не вариант). На Win7 c разрешением 1920*1080 все норм! В чем проблема может быть?


Ответ

Решил установкой значения Inherit для свойства AutoScaleModeв формах

Регулярные выражения в форме регистрации

Как учесть только латиницу или кирилицу?
Есть форма регистрации, мне нужно учесть только русские или латинские буквы, но смешивать их нельзя. Пример: "Lexans" и "Алексей" - разрешено, а "Lexaнс" - нет!
Вот как такое учесть?


Ответ

/^([A-Za-z]+|[А-Яа-я]+)$/u Вот такая регулярка