Feel Good.

19 января 2015

Hello world для ATmega328 + avr-gcc + avrdude (USBasp)


Хочу поделиться своим опытом знакомства с микроконтроллером ATmega328. Но сначала небольшое отступление.
Наверное уже все читали или уж точно слышали про Arduino. На мой взгляд, Arduino хорошая платформа для ознакомления с миром микроконтроллеров. Низкий порог вхождения и богатый набор различных библиотек, несомненно, является ключевым достоинством этой платформы. Под словом платформа я понимаю само устройство и штатная IDE с набором библиотек. Но к сожалению, ради обеспечения низкого порога вхождения штатная IDE вынуждена многое делать неявно для программиста. Например, процесс компиляции и прошивки, или даже формирование конечного main-файла с подключением всех include. Именно эти неявные действия и создают пробелы в знаниях при изучении платформы.
Итак, наши цели:
  1. Написать программку на чистом C, которая будет мигать светодиодом (aka "Hello world!" только для МК)
  2. Собрать прошивку для МК
  3. Настроить fuses bits нашего МК
  4. Прошить МК
Естественно все действия постараемся проделать из-под консоли.

24 октября 2012

Инфраструктурный код

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

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

28 марта 2012

Семантическое версионирование в DVCS Mercurial

Эта статья о том, как я наладил семантическое версионирование (semantic versioning) в своем проекте на базе DVCS Mercurial (можно читать как Git). На хабре есть отличный перевод про Семантическое управление версиями, советую начать с него.

В качестве хранилища кода, я выбрал mercurial. Помимо функции хранилища кода, mercurial будет выступать еще и как провайдер версий, это означает, что запрашивать текущую семантическую версию (Major.Minor.Patch) мы будем именно у него.

Итак, рассмотрим пару Major.Minor. Обычно эта пара всегда задается вручную в момент релиза, и самый простой способ это сделать - пометить руками нужный сhangeset тегом, содержащим версию релиза (например: 1.4, или v1.4, но не 1.4.3, так как path мы договоримся вычислять).

С Patch все намного сложнее. Наша цель, добиться чтобы при каждой фиксации(commit) изменений кодовой базы автоматически бы инкрементировался path-номер. Это примерно означало бы, что path будет равен числу фиксаций в текущем релизе (например: 1.4.17 - 17-ая фиксация в релизе 1.4, но в то же время 1.5.0 уже новый релиз, с новой path-нумерацией). Но здесь не стоит забывать один факт: мы ведь работаем с DVCS и у нас нет единого "брокера" path-номеров...

В интернете я нашел несколько вариантов решения этой задачи (SO, RSDN), где в основном предлагалось использовать число, полученное как {latesttagdistance}, но можно заметить, что {latesttagdistance} перестает работать в общем случае, когда тег может содержать произвольный текст. Но эта идея мне очень понравилась, и я начал искать универсальное решение. И вскоре решение было найдено.

Я предлагаю в качестве path-номера брать разницу между номером ревизии текущего changeset-а (замечу, что это не всегда tip) и номером ревизии changeset-а, имеющего тэг с релизной версией и являющегося ближайшим предком по отношению к текущему changeset-у.

На текущий момент, при таком подходе мне удалось достичь желаемого семантического версионирования своих проектов.

Теперь осталось все это как-то оформить. В конечном же счете, я преследовал цель автоматической генерации файла AssemblyInfo.cs на основе номера версии полученной от mercurial до начала сборки проекта, и с последующей сборкой. Очевидным решением здесь было сделать Custom MSBuild Task/Target, и в итоге появился проект Devme.MSBuildTasks.


Коротко о Devme.MSBuildTasks (текущая версия 0.3.0)

Q: Какие системы контроля версий поддерживает библиотека?

A: Пока только для mercurial.

Q: Как я могу начать использовать это в своем проекте?

A: Необходимо выполнить 3 простых шага:

Шаг 1. Используя Nuget, установить/скачать библиотеку к себе в проект.

Шаг 2. Создать в каталоге Properties (если использовали nuget, то файл шаблон будет создан автоматически) файл шаблон следующего содержания (за основу можно взять Ваш текущий файл AssemblyInfo.cs):

using System.Reflection;
 
[assembly: AssemblyTitle("todo")]
[assembly: AssemblyDescription("todo")]
[assembly: AssemblyCompany("todo")]
[assembly: AssemblyProduct("todo")]
[assembly: AssemblyCopyright("Copyright © todo")]
 
[assembly: AssemblyVersion("${major}.${minor}.${path}")]
[assembly: AssemblyFileVersion("${major}.${minor}.${path}")]
[assembly: AssemblyInformationalVersionAttribute("${major}.${minor}.${path}-${branch} ${hash|short}")]
Формат шаблона думаю Вам понятен, здесь в качестве ${some} будут подставлены соответствующие значения взятые из mercurial (см wiki). У себя я называю этот файл AssemblyInfo.cs.template.

Шаг 3. Открыть в блокноте файл проекта (*.csproj) и добавить в самом конце пару тэгов (или расширить существующую цель BeforeBuild), указав правильный путь к Devme.MSBuildTasks.dll:

<UsingTask 
    TaskName="SemanticVersioningTask" 
    AssemblyFile="ПУТЬ К ФАЙЛУ Devme.MSBuildTasks.dll" />
<Target Name="BeforeBuild">
    <semanticversioningtask 
        TemplateFilePath="Properties/AssemblyInfo.cs.template" 
        OutputFilePath="Properties/AssemblyInfo.cs" />
</Target>
Все готово!

Заключение
  1. Следует помнить, что каждый раз, во время сборки проекта, файл AssemblyInfo.cs будет генерироваться автоматически, поэтому его можно(надо) исключить из кодовой базы добавив в .hgignore.
  2. Так же не рекомендуется вносить в файл AssemblyInfo.cs любые изменения. Все изменения надо делать в шаблоне AssemblyInfo.cs.template.
  3. Исходники
  4. Wiki
Ссылки:
  1. Semantic Versioning
  2. AssemblyVersion и git. Давайте жить дружно.
  3. Полуавтоматическое выставление номера версии с помощью git

Всем приятного использования!