You are on page 1of 436

B GIO DC & O TO TRNG I HC S PHM K THUT TP.

H CH MINH KHOA IN IN T B MN IN T-CNG NGHIP


-----------**-----------

N TT NGHIP
NGNH K THUT IN - IN T

TI:

NGHIN CU V BIN SON GIO TRNH KIT KM9260 TRN NN LINUX.

GVHD: ThS Nguyn nh Ph; SVTH: Nguyn Tn Nh; MSSV: 07101080.

Tp. H Ch Minh - 2/2012

B GIO DC & O TO TRNG I HC S PHM K THUT TP. H CH MINH KHOA IN IN T B MN IN T-CNG NGHIP
-----------**-----------

N TT NGHIP
NGNH K THUT IN - IN T
TI:

NGHIN CU V BIN SON GIO TRNH KIT KM9260 TRN NN LINUX.

GVHD: ThS Nguyn nh Ph; SVTH: Nguyn Tn Nh; Lp: 071012B, H chnh qui; MSSV: 07101080.

Tp. H Ch Minh - 2/2012

PHN I

B Gio Dc V o To CNG HA X HI CH NGHA VIT NAM Trng i Hc S Phm K Thut c lp - T do - Hnh phc Thnh Ph H Ch Minh

KHOA IN - IN T
NGNH K THUT IN T

NHIM V N TT NGHIP
H v tn: NGUYN TN NH MSSV: 07101080 Lp: 071012B Ngnh: K THUT IN - IN T H: I HC CHNH QUY Nin kha: 2007 2012 1.Tn bi: NGHIN CU V BIN SON GIO TRNH KIT NHNG KM9260 TRN NN LINUX 2. Cc s liu ban u: ...................................................................................................................................... 3. Ni dung cc phn thuyt minh: ...................................................................................................................................... ...................................................................................................................................... ...................................................................................................................................... ...................................................................................................................................... 4. Cc bn v th: .................................................................................................................................. .................................................................................................................................. 5. Gio vin hng dn: ThS Nguyn nh Ph 6. Ngy giao nhim v: ............................................................................................ 7. Ngy hon thnh nhim v: ................................................................................. Thng qua b mn Ngy thng nm 2012 Ch nhim b mn

ii

LI M U
Th gii ngy nay vi khoa hc k thut pht trin mnh m cuc sng con ngi ngy cng c pht trin tt hn. Khoa hc k thut em li nhiu tin ch thit thc hn cho cuc sng con ngi. Gp phn to ln trong qu trnh pht trin ca khoa hc k thut l s pht trin mnh m ca vi x l. T b vi x l u tin Intel 4004 c sn xut bi cng ty Intel vo nm 1971, n nay ngnh cng nghip vi x l pht trin vt bc v a dng vi nhiu loi nh: 8951, PIC, AVR, ARM, Pentium,Core i7,. Cng vi s pht trin a dng v chng loi th ti nguyn ca vi x l cng c nng cao. Cc vi x l ngy nay cung cp cho ngi dng mt ngun ti nguyn rng ln v phong ph. C th p ng c nhiu yu cu khc nhau trong thc t. gip cho ngi dng s dng hiu qu v trit cc ti nguyn ny th h thng nhng ra i. H thng nhng (Embedded system) l mt thut ng ch mt h thng c kh nng t tr c nhng vo trong mt mi trng hay mt h thng m. l cc h thng tch hp c phn cng v phn phm phc v cc bi ton chuyn dng trong nhiu lnh vc cng nghip, t ng ho iu khin, quan trc v truyn tin. Vi s ra i ca h thng nhng th vi x l ngy cng c ng dng rng ri trong i sng cng nh trong cng nghip v kh nng x l nhanh, a dng, tit kim nng lng v n nh ca h thng nhng. Nhng nm gn y, s nng ng v tch cc hi nhp quc t em v hi th mi cho Vit Nam v mi mt: kinh t, x hi, vn ha, ngh thut Lnh vc k thut ni chung v k thut in t ni ring cng c nhng thay i theo chiu hng tch cc. Bn cnh vic p dng nhng k thut mi (ch yu mua t nc ngoi) vo sn xut, nhiu cng ty Vit Nam ch trng n vic pht trin i ng R&D (Research And Development) t ch to sn phm hon thin cung ng cho th trng. Mt trong nhng sn phm l kit KM9260 l mt kit nhng c tch hp cao trn nn vi iu khin AT91SAM9260. Tuy h thng nhng rt ph bin trn ton th gii v l hng pht trin ca ngnh in t sau ny nhng hin nay Vit Nam ng k s hiu bit v h thng nhng cn rt hn ch khng p ng c nhu cu nhn lc trong lnh vc ny. Trc tnh iii

hnh thiu nhn lc nh th ny, trng i Hc S Phm K Thut Thnh Ph H Ch Minh vi t cch l mt trong nhng trng s phm k thut ng u ca Vit Nam nghin cu v lnh vc h thng nhng v s a vo h thng mn hc o to trong tng lai gn nht. V vy vic bin son gio trnh v h thng nhng l mt yu cu cn thit trong thi im hin ti cng nh trong tng lai. Nhn thy c nhu cu cp thit nn sinh vin thc hin chn ti: NGHIN CU V BIN SON GIO TRNH KIT NHNG KM9260 TRN NN LINUX lm n tt nghip cho mnh. Nhng kin thc, nng lc t c trong qu trnh hc tp trng s c nh gi qua t bo v n cui kha. V vy sinh vin thc hin ti c gng tn dng nhng kin thc hc trng cng vi s tm ti, nghin cu cng vi s hng dn tn tnh ca Gio vin hng dn cng Thy/C thuc Khoa in-in T c th hon thnh tt n ny. Mc d sinh vin thc hin ti c gng hon thnh nhim v ti t ra v ng thi hn nhng chc chn s khng trnh khi nhng thiu st, mong qu Thy/C v cc bn sinh vin thng cm. Sinh vin thc hin ti mong nhn c nhng kin ng gp ca qu Thy/C v cc bn sinh vin. TP.HCM, Ngy thng nm 2012 Sinh vin thc hin ti Nguyn Tn Nh

iv

LI CM N
Li u tin, sinh vin thc hin ti xin c php chn thnh gi li cm n n thy Nguyn nh Ph, gio vin hng dn ti, nh hng v trao i nhng kinh nghim qu bo em thc hin nhng ni dung trong ti ny cch hon chnh. K n, em cng xin t lng bit n n thy Nguyn Tn Thnh, cu sinh vin ca trng i Hc S Phm K Thut, gip em c c nhng kin thc rt c bn c vai tr l nn tng gip em pht trin nhng ni dung trong ti. Em cng xin trn trng cm n cc thy c trong trng i Hc S Phm K Thut tn tnh truyn t nhng kin thc v tnh yu ngh em c s am m nghin cu khm ph nhng kin thc mi trong ngnh. Cui cng em xin dng li cm n n Cha Gisu, cha, m v nhng ngi thn trong gia nh, bn b, ... to iu kin thun li v tinh thn v vt cht gip em hon thnh ti ny. TP.HCM, Ngy thng nm 2012 Sinh vin thc hin ti Nguyn Tn Nh

MC LC
NI DUNG TRANG

PHN A: GII THIU .........................................................................


Trang ba .............................................................................................................. i Nhim v n ................................................................................................... ii Li m u ......................................................................................................... iii Li cm n ......................................................................................................... iv Mc lc................................................................................................................ v Lit k hnh v .................................................................................................... ix Lit k bng xii

PHN B: NI DUNG ............................................................................


CHNG I: DN NHP ................................................................................ 1 1.1. t vn ................................................................................................. 2 1.2. L do chn ti. .................................................................................... 2 1.3. i tng nghin cu ............................................................................... 3 1.4. Gii hn ti .......................................................................................... 3 1.5. Dn nghin cu ...................................................................................... 3 1.6. Tnh hnh nghin cu ................................................................................ 4 1.7. ngha thc tin. ...................................................................................... 5 CHNG V: KT QU NGHIN CU-KT LUN-HNG PHT TRIN. ........ 116 5.1 Kt qu nghin cu. ............................................................................... 117 5.2 Kt lun . ................................................................................................. 117 5.3 Hng pht trin ..................................................................................... 118

PHN C: PHU LC. 119


vi

LIT K HNH V
Hnh Trang Hnh 2.1: S khi tng qut VN8-01 ....................................................................... 6 Hnh 2.2: S chn VN8-01....................................................................................... 7 Hnh 2.3: CPU x l 5 giai on ................................................................................... 10 Hnh 2.4: Kin trc ng ng 5 tng .......................................................................... 11 Hnh 2.5: 1 lnh n cn 5 xung clock ......................................................................... 11 Hnh 2.6: T chc b nh chng trnh trong VN8-01 ................................................ 12 Hnh 2.7 Hot ng ca PC i vi lnh thng v lnh r nhnh .............................. 13 Hnh 2.8: Cu trc ca 1 lnh n ................................................................................ 14 Hnh 2.9: Cc ngun ngt ca VN8-01 ......................................................................... 17 Hnh 2.10: Hot ng ca Stack v thanh ghi PC ......................................................... 18 Hnh 2.11: Cu trc thanh ghi INTCON ....................................................................... 19 Hnh 2.12: Cu trc thanh ghi PIR1 .............................................................................. 20 Hnh 2.13: Cu trc thanh ghi PIE1 .............................................................................. 21 Hnh 2.14: Cu trc thanh ghi OPTION ....................................................................... 22 Hnh 2.15: Clock ng vo cho cc b Timer 0,1,2 ....................................................... 22 Hnh 2.16: S khi ca Timer0 ................................................................................ 25 vii

Hnh 2.17: S khi b nh thi 1(Timer1) ............................................................. 29 Hnh 2.18: Cu trc thanh ghi T1CON ......................................................................... 29 Hnh 2.19: S khi ca Timer2 ................................................................................ 32 Hnh 2.20: Cu trc thanh ghi T2CON ......................................................................... 32 Hnh 2.21: Thit k hot ng cho chc nng WDT .................................................... 34 Hnh 2.22: S khi Watchdog-Timer....................................................................... 35 Hnh 2.23: Ch hot ng ca CPP v ngun Timer ............................................... 39 Hnh 2.24: Cu trc thanh ghi CCPCON ...................................................................... 39 Hnh 2.25: Cu trc thanh ghi PIR1 .............................................................................. 40 Hnh 2.26: V tr bit CCPIE........................................................................................... 40 Hnh 2.27: quan h gia CK bn phn (Thigh) v CK xung (Tcycle) ......................... 42 Hnh 2.28: S khi Capture ca ng vo CCPI ....................................................... 43 Hnh 2.29: S khi Compare.................................................................................... 45 Hnh 2.30: S khi PWM......................................................................................... 46 Hnh 2.31: Thay i CKNV khi CK xung c nh ....................................................... 47 Hnh 2.32: Cu to b truyn USART .......................................................................... 50 Hnh 2.33: cu trc thanh ghi TXSTA .......................................................................... 51 Hnh 2.34: Cu trc thanh ghi RCSTA ......................................................................... 52 Hnh 2.35: v tr c ngt nhn ....................................................................................... 53 Hnh 2.36: V tr bit c ngt .......................................................................................... 54 Hnh 2.37: Quan h gia clock ly mu v clock truyn d liu ................................55 Hnh 2.38: Clock khi SPBRG = 0x00 .........................................................................56 Hnh 2.39: Gin xung truyn d liu tng bit ........................................................57 Hnh 2.40: Ly mu d liu ng vi BaudRate = Fosc/(64x(X+1))...........................58 Hnh 2.41: Ly mu d liu ng vi Baud Rate = fosc/(16x(X+1))...........................58 Hnh 2.42: Ly mu d liu ng vi Baud Rate = fosc/(8x(X+1)).............................58 Hnh 2.43: Cu to ca b truyn USART .................................................................60 Hnh 2.44: Truyn bt ng b 1 khung d liu dng truyn n l ..........................61 Hnh 2.45: Truyn bt ng b Back-to-Back ............................................................61 Hnh 2.46 Cu to b nhn bt ng b USART.......................................................62 Hnh 2.47: Qu trnh truyn ng b Master ..............................................................65 Hnh 2.48: Ch nhn ng b Master (nhn 1 ln) ................................................67 viii

Hnh 2.49: Hot ng truyn trong ch Standby (ng b Slave) ........................69 Hnh 2.50: Hot ng nhn trong ch Standby (ng b Slave) ..........................70 Hnh 3.1 Gin thi gian th hin tn hiu xung reset v xung presence ................74 Hnh 3.2: Gin trnh t thi gian ca xung reset & presence ................................74 Hnh 3.3: Gin thi gian cho VN8-01 ghi tn hiu mc 1 & mc 0 ......................75 Hnh 3.4: Gin thi gian VN8-01 c tn hiu mc 1 & 0................................75 Hnh 3.5: Dng ng gi TO-92 ................................................................................. 77 Hnh 3.6: Dng ng gi SO .......................................................................................77 Hnh 3.7: M t chi tit gi tr bit trong b nh lu gi tr chuyn i ......................78 Hnh 3.8: Th hin cu trc b nh DS18B20 ............................................................79 Hnh 3.9: Thanh ghi cu hnh phn gii (byte4) ....................................................80 Hnh 3.10: Ngun cung cp qua ng tn hiu .........................................................83 Hnh 3.11: DS18B20 vi ngun cung cp c lp......................................................83 Hnh 3.12: Kt ni phn cng cc thit b giao tip I2C ............................................85 Hnh 3.13: Quan h truyn/nhn d liu gia thit b ch/t .....................................85 Hnh 3.14: Gin th hin tn hiu xung Start v Stop ............................................87 Hnh 3.15: Qu trnh truyn 1bit d liu .....................................................................87 Hnh 3.16: Qu trnh truyn 8bit d liu v tn hiu p ng Ack .............................88 Hnh 3.17: Tn hiu p ng ACK t thit b nhn ....................................................88 Hnh 3.18: Lu thut ton truyn nhn d liu ......................................................89 Hnh 3.19: Cu trc byte d liu u tin ...................................................................89 Hnh 3.20: Qu trnh truyn d liu ............................................................................90 Hnh 3.21: Ghi d liu t ch n t vi chiu c xc nh ...................................91 Hnh 3.22: Thit b ch c d liu t thit b t........................................................91 Hnh 3.23: Thit b ch kt hp c & ghi d liu trong qu trnh truyn thng .......92 Hnh 3.24: Dng ng gi DIP ca DS1307 ...............................................................92 Hnh 3.25: T chc b nh trong DS1307 ..................................................................93 Hnh 3.26: T chc bn trong ca cc thanh ghi thi gian .........................................94 Hnh 4.1: S khi tng qut Kit th nghim VN8-01.............................................99 Hnh 4.2: S chn ca 74HC573............................................................................102 Hnh 4.3: S chn IC 74HC595 .............................................................................103 Hnh 4.5: S chn 74HC138 ..................................................................................106 ix

Hnh 4.7: S chn ca LCD16*2 ...........................................................................107 Hnh 4.8: S chn ca 74HC541............................................................................108 Hnh 4.10 : S chn ca 74HC151.........................................................................111 Hnh 4.11 : S chn ca IC 74HC07......................................................................112 Hnh 4.12 : S chn ca IC 74HC08......................................................................112 Hnh 4.14 : s chn ca ADC0809 ........................................................................113

LIT K BNG
Bng Trang

Bng 2.2: Vng gi tr b nh Ram/bank.14 Bng 2.3: M t thanh ghi INTCON.19 Bng 2.4: m t thanh ghi PIR120 Bng 2.5: M t thanh ghi PIE121 Bng 2.6: M t thanh ghi OPTION22 Bng 2.6: M t thanh ghi OPTION25 Bng 2.7: M t thanh ghi T1CON...29 Bng 2.8: M t thanh ghi T2CON...32 Bng 2.9: M t thanh ghi CCPCON39 x

Bng 2.10: M t ni dung bt c ngt..40 Bng 2.11: M t chc nng bit CCPIE40 Bng 2.12: M t chc nng thanh thi TXSTA51 Bng 2.13: M t chc nng thanh ghi RCSTA...52 Bng 2.14: M t chc nng ca c ngt..54 Bng 2.15: M t chc nng bit c ngt...54 Bng 2.16: Cng thc tnh tc Baud55 Bng 2.17: Cc bc thit lp b truyn bt ng b...60 Bng 2.18: Cc bc thit lp b nhn bt ng b..62 Bng 2.19 Cc bc thit lp cho b truyn MASTER.64 Bng 2.20: Cc bc cu hnh b nhn ng b Master...66 Bng 2.21: Cc bc thit lp mt ch truyn ng b SLAVE 67 Bng 2.22: Cc bc cu hnh ch nhn ng b Slave..69 Bng 3.1: Mi quan h gia nhit v gt lu trong b nh phn gii 12bits79 Bng 3.2: Gi tr cu hnh tng ng vi tng phn gii..80 Bng 4.1 : M t chc nng chn ca GLCD109

xi

PHN II

N TT NGHIP

CHNG I

DN NHP

CHNG I: DN NHP.

N TT NGHIP

1.1.

T VN
Trn th gii h thng nhng (embeded system) xut hin v c mt trn th

trng vo nhng nm 1960, cho n nay hn na th k hnh thnh v pht trin. Vi nhng u im m cc h thng khc khng c nh tnh gn nh, p ng nhanh, tin cy cao, v quan trng l kh nng linh hot trong nhiu ng dng to iu kin thun li cho sn xut hng lot dn n gi thnh gim, ... H thng nhng c s dng a dng trong mi lnh vc nh: dn dng, qun s, y t,... Doanh thu m cc h thng nhng mang li l v cng ln. Theo thng k ca mt hng nghin cu ca Canada th n nm 2009, tng th trng ca cc h thng nhng ton cu t 88 t USD. Trong phn cng t 78 t v phn mm t 3.5 t. Trong tng lai lng doanh thu ny s cn tng ln ng k. Lnh vc ny v ang l mt c hi v thch thc v cng ln cho cc doanh nghip trong v ngoi Vit Nam. Ti Vit Nam, vic bt tay vo nghin cu v pht trin phn mm cng nh phn cng h thng nhng ch mi bt u trong vi nm tr li y v c xem l mt c hi vng cho cc cng ty in t nghin cu v pht trin ng dng vo cc sn phm cng ngh cao. Nhiu cng ty xem vic pht trin phn cng v phn mm h thng nhng l ch ngm trong tng lai v khng ngng u t hp tc vi cc i tc nc ngoi tip thu v pht trin. Trong bi cnh t nc ta ang trn ng hi nhp pht trin, vic u t m cc nh my cng xng chuyn v sn xut h thng nhng v tm kim i tc ln t nc ngoi c kinh nghim trong lnh vc ny l khng kh. Th nhng liu chng ta c yu t con ngi lm vic trong nhng mi trng ny hay khng? Hin nay i ng nhn lc ca nc ta trong lnh vc thit k h thng nhng cn hn ch, cha c mt kin thc rng v su c th hp tc pht. Vit Nam bc u c nhng chng trnh hp tc vi cc hng in t ln nh Toshiba, Samsung, Panasonic, ... tuy nhin nhng chng trnh nh th cn rt hn ch v khng c mt nh hng chin lc chung. Vit Nam cn phi y mnh hn na vn nh hng nghin cu v pht trin cho ngnh h thng nhng t trong cc trng i hc v trung tm nghin cu, cng nh trang b nhng kin thc v l thuyt v thc hnh cho nhng sinh vin tr, p ng nhu cu ngy cng cao ca nh tuyn dng. Mun vy vn t ra l phi c mt chng trnh c thit k chuyn su c v l thuyt v thc hnh trong cc c s o to chnh quy nh hng ban u cho cc sinh vin CHNG I: DN NHP. 2

N TT NGHIP theo hc ti trng c mt nim am m lnh vc lp trnh nhng y tim nng ny, to mt nn tng vng chc cho s pht trin bn vng v nhanh chng trong tng lai. Mt trong nhng yu t quan trong nht quyt nh n cht lng thnh cng ca chng trnh o to l ti liu hng dn thc hin chng trnh o to . V th vic bin son mt gio trnh y , chuyn su, ging dy song hnh gia l thuyt v thc hnh ngi hc khng ch nm vng nguyn l hot ng m cn c th thao tc iu khin vo nhng ng dng thc t ca h thng nhng, t t mnh c th nghin cu pht trin trong cc mi trng chuyn nghip sau ny l mt nhu cu cp thit.

1.2.

L DO CHN TI
Tn ti ca nhm l NGHIN CU V BIN SON GIO TRNH KIT

NHNG KM9260 TRN NN LINUX. Khi mt h CHIP vi iu khin mi c ra i, cng vi nhng tnh nng vt tri hn so vi cc vi iu khin khc, nh sn xut thng cho ra i cc kit nhng s dng ngay nhng CHIP ny lm ni bt nhng tnh nng m n h tr. Kit nghim KM9260 l mt loi nh th. c xy dng da vo cu trc h thng nhng at91sam9260-ek ca hng Atmel, kit c tch hp rt nhiu ngoi vi thch hp vi nhng c im ca h thng nhng nhm chng em chn lm ti nghin cu ca mnh. Vic la chn mt kit c th vit gio trnh hng dn lp trnh ng dng trong h thng nhng c quyt nh bi ba l do sau:

Th nht, a s cc h thng nhng (bao gm phn cng v phn mm) c


xy dng theo mt chun nht nh. Nghin cu mt i tng c th trong chun ny c ngha rng tt c cc i tng khc cng ang c nghin cu. Tip cn theo hng c th s gip cho ngi hc c nhiu kinh nghim lp trnh t thc tin, rt ra kin thc tng qut t nhng thao tc c hng dn, ... to nn tng cho vic nghin cu cc h thng khc. Nu tip cn theo hng chung nht, mc d ngi hc c th hiu r nguyn tc hot ng ca h thng nhng s khng th p dng vo bt k mt h thng thc t no.

Th hai, tin cy cao, gi thnh v thi gian thit k gim. a s cc kit th


nghim c nghin cu v kim tra qua nhiu cng on trc khi xut hin trn th trng i tr v th h thng hot ng vi n nh cao. Do sn xut vi s lng ln nn chi ph thit k s gim, thi gian thc hin c rt ngn. CHNG I: DN NHP. 3

N TT NGHIP

Th ba, cc kit th nghim c sn xut vi rt nhiu ngoi vi khc nhau tch


hp trn mt board mch, nhiu chn cm m rng, ... thch hp cho vic ng dng kt hp vi cc kit th nghim hin c trnh lng ph trong qu trnh chuyn giao thay i cng ngh. Mt h thng nhng c th chy trn nhiu h iu hnh khc nhau nh WinCE, Android, Linux, ...nhng nhm chng em chn h iu hnh Linux nghin cu v trin khai cc bi th nghim trong gio trnh v h iu hnh ny c nhiu u im m cc h iu hnh khc khng c.

u im u tin l Linux c m ngun m, chng ta c th thao tc chnh sa


m ngun ny ph hp vi h thng. Hin ny Linux h tr cho rt nhiu dng vi iu khin khc nhau nh: ARM, AVR, ...nn khi nghin cu linux chng ta c th d dng lm vic trn nhiu h thng khc.

Linux c xy dng hon ton bng ngn ng lp trnh C. y l ngn ng


thng dng v ph bin. Ngi hc khi nghin cu s d dng tip thu c thut ton chng trnh iu khin v nguyn l lm vic ca h thng.

C rt nhiu sch hay v thng tin bn lun v h iu hnh ny trn internet.


Do khi nghin cu ngi hc c th tm hiu trn mi knh thng tin nm vng ni dung ca bi hc.

V cn rt nhiu u im khc, nhng u im ny s c ngi hc nhn ra


trong qu trnh s dng. Vi nhng l do trn nhm chng em chn ti : NGHIN CU V BIN SON GIO TRNH KIT NHNG KM9260 TRN NN LINUX lm ti tt nghip ca mnh. Vi mc ch lm ti liu nghin cu cho cc bn sinh vin mong mun tm hiu th gii lp trnh nhng y th v, gp phn lm cho mn hc ny c pht trin rng ri trong i ng k s tr ca nc ta, nng cao cht lng ca ngun nhn lc. 1.3.

I TNG NGHIN CU

ti ny tp trung nghin cu ch yu l phn mm h thng nhng linux trn kit ARM KM9260. Nhng kin thc v h iu hnh nhng bao gm driver v application c hin thc ha thng qua cc bi thc hnh trn kit th nghim. Cc bi thc hnh c xy dng t n gin n nng cao iu khin cc thit b ngoi vi c tch hp CHNG I: DN NHP. 4

N TT NGHIP trn kit ngi hc c th hiu v ng dng vo cc d n ln hn ngoi thc t. Do y l ti liu hng dn lp trnh h thng nhng da trn nn h iu hnh linux nn nhng kin thc v lp trnh hp ng, nhng chng trnh khng mang tnh cht h iu hnh khng c cp v p dng trong nhng bi thc hnh ca gio trnh.

1.4.

GII HN TI
Ni dung ca ti (gio trnh) bao gm 3 vn :

Lp trnh h thng nhng cn bn:


Trnh by nhng kin cn bn nht v h thng nhng, lm c s ngi hc tip cn phn lp trnh h thng nhng nng cao. Bao gm l thuyt v h iu hnh Linux, l thuyt v h thng nhng, hng dn cc phn mm h tr trong qu trnh s dng kit nhng, hng dn np cc phn mm h thng nhng v bin dch phn mm ng dng. Phn l thuyt v h iu hnh Linux s trnh by cc kin thc cn bn ca Linux: phn vng a trong Linux, cch truy xut phn vng trong Linux, cc th mc h thng trong Linux, mn hnh Terminal. Ngoi ra phn ny cn trnh by cc thao tc c bn trong Linux nh: khi ng li h thng, tt h thng, to th mc tp tin, sao chp th mc tp tin, di chuyn th mc tp tin, phn quyn qun l tp tin th mc, . Cui cng phn ny trnh by trnh son tho trong Linux l trnh son tho VI. Phn l thuyt h thng nhng s trnh by v phn cng ca kit nhng KM9260, trnh by v cc phn mm h thng ca kit nhng bao gm Romcode, Bootstrapcode, U-boot, Kernel, Rootfs. Phn hng dn cc phn mm h tr trong qu trnh s dng kit nhng s trnh by cc phn mm cn thit nh: Vmware Workstation, Samba, Putty, tftpd32, SSH SECURE SHELL CLIENT. V phn cui cng s hng dn np cc phn mm h thng vo cc vng nh tng ng trn kit kit c th chy h iu hnh nhng thnh cng. Phn ny cn trnh by cch bin dch, chy mt chng trnh ng dng v cch bin dch, ci t mt driver.

Lp trnh h thng nhng nng cao:


Bao gm kin thc v mi quan h gia hai lp user v kernel trong h thng phn mm nhng. CHNG I: DN NHP. 5

N TT NGHIP i vi lp user, ti cung cp nhng thng tin cc hm h tr trong qun l thi gian thc ca h thng, cc lnh h tr lp trnh a tuyn v tin trnh. Cho ngi hc c mt tm nhn tng qut trong phng php lp trnh bng h iu hnh. ti khng i su tm hiu vn xung t trong truy xut d liu gia cc tuyn v cc tin trnh vi nhau m ch nu nhng kin thc thc hin cc bi tp v d trong ti. i vi lp kernel, ti cung cp nhng thng tin ch yu v driver, vai tr, v tr v phn loi driver trong h thng phn mm nhng. i su vo tm hiu character device driver, cc hm giao din, cc bc hon chnh vit v a mt driver (loi character) hot ng trong h thng. Bn cnh ti gio trnh cn trnh by cc hm thao tc trong gpio, qun l v truy xut thi gian thc trong kernel lm c s cho iu khin cc thit b ngoi vi.

Thc hnh giao tip cc thit b ngoi v:


Bao gm nhiu bi thc hnh khc nhau, mi bi s iu khin mt loi thit b ngoi vi. ti s cung cp m chng trnh v d cho c hai phn driver v application cho mi bi v d. Cc thit b ngoi vi l nhng linh kin hin th n gin, cc linh kin o lng, iu khin; cc chun giao tip nh UART, I2C, 1-Wire. Do hn ch v thi gian nghin cu nn ti ch a ra cc chng trnh v d nh di dng module cha kt hp thnh mt d n ln c th hiu ht sc mnh m mt h thng nhng c th lm. ti ch nhm cung cp cho ngi c nhng kin thc lp trnh nhng cn bn v c th nht t lm c s lp trnh nhng ng dng ln hn khng phi ch mt m l tp hp nhng k s khc nhau cng nghin cu pht trin.

1.5.

DN NGHIN CU
Gii thiu v vi iu khin AT91SAM9260: cung cp cho ngi hc cc kin thc cn thit v vi iu khin phc v cho vic nghin cu s dng kit nhng. Phn ny bao gm: H vi iu khin ARM. Vi iu khin AT91SAM9260: c im chnh

1.5.1. Lp trnh nhng cn bn:

CHNG I: DN NHP.

N TT NGHIP S chn ca AT91SAM9260 Ngun cp cho AT91SAM9260 Bng vng nh ca AT91SAM9260

L thuyt v h iu hnh Linux: Cung cp cho ngi hc cc kin thc c bn v Linux ng dng cho h iu hnh nhng. Phn ny bao gm: Kin thc ve Linux Cc thao tc c bn trn h iu hnh Linux Trnh son tho VI

L thuyt v h thng nhng: Cng cp cho ngi hc cc kin thc ban u v h thng nhng. Phn ny bao gm: Phn cng h thng nhng trn kit km9260 Phn mm h thng nhng trn kit km9260

Cc phn mm h tr trong qu trnh s dng kit: Hng dn cc thao tc s dng phn mm v chc nng ca tng phn mm. Phn ny bao gm: Chng trnh my tnh o Vmware Workstation Chng trnh Samba Chng trnh Putty Chng trnh tftpd32 Chng trnh SSH SECURE SHELL CLIENT

Hng dn np phn mm h thng v bin dch phn mm ng dng cho kit: Phn ny bao gm: Trnh bin dch cho Cross Toolchians Cc bc bin dch Kernel Chnh sa Kernel Cc bin mi trng v lnh c bn ca U-boot Ci t cho h thng Cc bc bin dch Driver v ci t Driver Cc bc bin dch chng trnh ng dng v chy chng trnh ng dng

1.5.2. Lp trnh nhng nng cao: Lp trnh user application: Cung cp cho ngi hc nhng kin thc cn thit c th vit mt chng trnh ng dng chy trong lp user. Phn ny bao gm nhng ni dung: CHNG I: DN NHP. 7

N TT NGHIP Chng trnh helloworld: y l chng trnh n gin, cung cp kin thc v cc hm n gin trong C (hm printf(), hm exit()) v khc phc nhng li xy ra trong qu trnh bin dch chng trnh user sao cho c th chy n nh. Tr hon thi gian trong user: Cung cp cho ngi hc nhng kin thc v tr hon thi gian trong lp user c n v t giy n nano giy. Ngi hc c thao tc vi hm nh thi gian tc ng alarm(), cc hm truy xut v thao tc thng tin thi gian thc ca h thng linux. Lp trnh a tin trnh trong user: Ngi hc c lm quen vi khi nim tin trnh; cch qun l tin trnh; cc hm to lp, thay th v nhn i tin trnh; ... trong linux. Lp trnh a tuyn trong user: Trnh by cc vn v tuyn; phn bit gia tuyn v tin trnh; Cc hm to lp, ng b ha hot ng; Nhng u v nhc im so vi tin trnh; ... trong linux. Lp trnh trong lp kernel driver: Cung cp cho ngi hc nhng kin thc chuyn su v driver loi character theo h c th t mnh vit v c hiu cc driver khc ngoi thc t. Phn ny bao gm nhng ni dung sau: H thng nhng mi quan h gia driver v application trong phn mm h thng nhng: Nhc li nhng kin thc v nh ngha; cu trc v vai tr tng thnh phn trong h thng nhng. So snh v vai tr, nu mi quan h gia driver v application trong h thng nhng phc v cho vic phn phi nhim v thc thi cho hai thnh phn ny trong h thng. Cc loi driver nhn dng tng loi driver trong linux: Xc nh vai tr ca driver; phn loi; cch qun l driver; cc hm tng tc vi s nh danh driver trong linux; Character device driver: Cung cp nhng kin thc y v charater device driver bao gm: nh ngha, cch thc to s nh danh thit b, cu trc v cc hm ng k character driver vo h thng linux. Cc giao din chun trong driver: Trnh by cu trc, gii thch cc tham s lnh ca giao din hm trong driver linux nh read(), write() v ioctl() phc v cho vic vit hon chnh mt character device driver; Cc bc vit mt character driver: Cn c vo nhng kin thc l 8

CHNG I: DN NHP.

N TT NGHIP thuyt c trnh by trong nhng bi trc. Bi ny rt ra nhng bc cn thit cn phi tin hnh lp trnh thnh cng mt character driver. Nhc li thao tc bin dch driver trong linux. Helloworld driver: a ra v d minh ha lp trnh mt character driver hon chnh mang tn helloworld.ko. Driver ny s dng tt c nhng giao din hm c gii thiu ng thi cn lp trnh sn mt chng trnh user application lin kt gia ngi dng vi driver, s dng tt c nhng chc nng m n h tr. Cc hm trong GPIO: Gii thiu cho ngi hc nhng kin thc v iu khin cc cng vo ra gpio. Bao gm quy nh s chn, cc hm khi to, truy xut cc chn trong CHIP vi iu khin. Tr hon thi gian trong kernel: Cng tng t nh trong phn lp trnh user, bi ny cung cp nhng kin thc v qun l thi gian trong kernel; cc hm truy xut thi gian thc; thao tc khi to ngt dng timer trong kernel.

1.5.3. Lp trnh giao tip phn cng:


Bao gm nhng bi thc hnh ring l, c sp sp theo th t t d n kh. Mi bi s iu khin mt hoc nhiu thit b ngoi vi ty theo yu cu ca bi ton. Hu ht u ng dng nhng kin thc hc trong phn lp trnh user application v lp trnh kernel driver. Cc bi thc hnh bao gm: iu khin LED n; iu khin 2 LED 7 on ri; iu khin nhiu LED 7 on bng phng php qut; iu khin LCD 16x2; Giao tip iu khin GPIO ng vo m xung; iu khin LED ma trn; iu khin ADC0809; iu khin module I2C tch hp trn CHIP AT91SAM9260; iu khin module ADC tch hp trn CHIP AT91SAM9260; iu khin module UART tch hp trn CHIP AT91SAM9260; (...); CHNG I: DN NHP. 9

N TT NGHIP

1.6.

TNH HNH NGHIN CU

Trong nc: Hin nay c rt nhiu gio trnh nghin cu su vo nguyn l hot ng ca h thng nhng c v phn cng ln phn mm. Nhng quyn gio trnh ny ch yu trnh by nhng l thuyt chung chung khng i c th vo mt h thng no. Chnh v th sau khi nghin cu xong, ngi hc kh c th p dng ngay vo thc t m i hi phi c mt qu trnh nghin cu chuyn su v h thng . Trn cc knh truyn thng cng c nhiu din n bn lun v ti lp trnh phn mm h thng nhng trn kit, nhng a s nh l v khng theo trnh t logic t d n kh. iu ny khin cho ngi mi bt u mun nghin cu v vit c mt ng dng phi tri qua qu trnh th sai tng hp t nhiu ngun thng tin khc nhau. Thm ch cn c th i sai hng nghin cu. Ngoi nc: Bn v lp trnh h thng nhng, c nhiu sch xut bn t rt lu. Nhng ni dung c trnh by rt phong ph, ngi c cn phi c kin thc chuyn mn su, nht l kin thc trong lnh vc ngoi ng chuyn ngnh mi c th c v lnh hi ht kin thc bn trong. iu ny i hi sinh vin nghin cu phi c kh nng tm hiu v vn ngoi ng di do. Cc gio trnh c a s trnh by nhng v d tng qut theo hng tt c cc h thng u c th thc thi. Cha c nhng v d v lp trnh phn cng iu khin cc thit b ngoi vi c th. ti c nghin cu nhm khc phc nhng nhc im trn. Nghin cu mt i tng c th s gip cho ngi hc ng dng ngay nhng g lnh hi vo thc tin. T khc su l thuyt, c th p dng vo nhng h thng tng t.

1.7.

NGHA THC TIN.

Lp trnh h thng nhng l mt lnh vc mi c trin vng ca nc ta trong nhng nm gn y. Thc y s pht trin trong lnh vc ny ngoi vic thu ht u t th vic pht trin i ng k s c kinh nghim l iu quan trong nht. ti c bin son vi nhng bi thc hnh xen k l thuyt c sp sp theo tng mc gip cho ngi hc khng ch nm vng l thuyt m cn c th thao tc CHNG I: DN NHP. 10

N TT NGHIP iu khin trn mch phn cng. V a s cc h thng nhng hot ng trn nn h iu hnh linux u theo mt chun chung nn khi tip xc vi cc h thng khc ngi hc c th t mnh nghin cu tm hiu. ti c thit k theo kit KM9260, l kit th nghim lp trnh nhng c tch hp nhiu ngoi vi v cc chn giao tip vo ra, thun li cho vic kt ni vi cc b th nghim khc hoc lp t vo cc b phn chuyn bit. iu ny lm tic kim chi ph thit k, tn dng nhng b th nghim hin c, ng dng lp trnh thnh cng c th p dng vo d n nhanh chng. ti khi c p dng vo chng trnh ging dy s gp phn lm ph bin thm mn lp trnh h thng nhng cho nhng sinh vin ang theo hc ti cc trng i hc. Gip h c c nhng kin thc nn tng, nh hng am m ban u tip tc nghin cu trong cc mi trng chuyn nghip sau ny.

CHNG I: DN NHP.

11

CHNG II

LP TRNH NHNG CN BN

Li u chng
Lp trnh nhng l mt vn tng i kh, i hi ngi nghin cuhc tp phi c s kin nhn v lng am m tht s mi c th hiu v tin xa trong lnh vc ny. Vi mc ch nh hng cho ngi hc c s am m ban u trong mn lp trnh h thng nhng, nhm thc hin ti trnh by mt cch chi tit nhng ni dung ct yu v cn thit sao cho ngi hc c th ng dng ngay nhng gi hc vo thc t, trnh trng hp l thuyt sung qu tng qut, nhm to s hng th trong qu trnh hc tp. Trong chng IILp trnh nhng cn bn, nh tn gi ca n, chng ny trnh by nhng kin thc rt cn bn v phn cng h thng nhng c lin quan n kit th nghim KM9260 nh: Vi iu khin AT91SAM9260, cu trc cc linh kin, h iu hnh nhng linux, cc phn mm h tr lp trnh, ... nghin cu nhng ni dung trong chng ny dt hiu qu cao nht, ngi hc phi c nhng kin thc v k nng nn tng sau: Kin thc tng qut v k thut s, l thuyt vi x l, hiu v s dng thnh tho mt loi vi x l n gin (chng hn 89x51, PIC, ...). S dng thnh tho nhng thao tc c bn trong PC tng ng trnh A. Kin thc tng qut v l thuyt h thng nhng, h iu hnh, ...

Chng ny c trnh by theo cu trc tng bi hc, mi bi hc c th ngn hoc di ty theo ni dung kin thc trnh by. Ni dung kin thc trong mi bi l mt vn ring bit nhm gip cho ngi hc lnh hi mt cch chc chn vai tr ca bi hc trong qu trnh tm hiu nghin cu lp trnh chng trnh ng dng trong h thng nhng. Cu trc cc bi hc bao gm: Bi 1: Tng quan v vi iu khin AT91SAM9260; Bi ny cung cp cho ngi hc nhng kin thc v vi iu khin ARM, s chn, bn vng nh ca vi iu khin s dng trong kit KM9260. y l nhng kin thc quan trng, gip cho ngi hc hiu c nguyn l kt ni phn cng, cch s dng v khai bo a ch vng nh trong phn mm, ... c cp trong nhng bi hc khc. Bi 2: Mt s thao tc c bn trn h iu hnh Linux; H iu hnh Linux c trnh by trong bi ny l mt h iu hnh dnh cho my tnh PC v cng c mt s c dim ging vi h iu hnh chy trn h thng nhng. Mc ch l cung cp cho ngi hc nhng kin thc v qun l b

nh, cc thao tc t n gin n phc tp trong mi trng shell ca h iu hnh Linux v mt s cc phn mm h tr bin son chng trnh ng dng khc. Bi 3: H thng phn cng v phn mm nhng trong kit KM9260; Bi ny gii thiu mt s vn v cu trc phn cng v phn mm trong kit KM9260 nhm gip cho ngi hc hiu r tn, v tr, vai tr ca tng linh kin, s chn kt ni, ... bn cnh l nguyn l v vai tr hot ng ca tng thnh phn trong h thng phn mm nhng, ... Nhng kin thc ny c vai tr quan trng trong lp trnh giao tip phn cng v sa cha h thng trong qu trnh hot ng nu pht sinh ra li. Bi 4: Phn mm h tr lp trnh nhng; Cung cp cho ngi hc k nng s dng nhng chng trnh h tr qu trnh lp trnh nhng nh: Chng trnh my tnh o, chng trnh h tr np chng trnh thng qua cng USB, thit b hin th u cui qua cng COM, phn mm giao tip mng. Cc phn mm ny h tr vic ng nhp, lp trnh, bin dch, v thc thi chng trnh ng dng trong kit. Bi 5: Thao tc trn phn mm h thng nhng KM9260; Sau khi nghin cu Bi 4, ngi hc s thc hnh s dng nhng thao tc c hc thao tc bin dch v np cc thnh phn trong h thng phn mm nhng bao gm rootfilesystem, uboot, kernel, driver v phn mm ng dng cc thnh phn ny c th chy n nh trn phn cng h thng nhng kit KM9260. Nhng vn c trnh by trong chng ny khng nhm gii thch chuyn su v nguyn l hot ng ca h thng nhng m cung cp cho ngi hc nhng kin thc c th c lin quan n kit KM9260, phc v cho vic lp trnh cc ng dng thc t giao tip gia kit vi cc thit b ngoi v trong chng sau. Do tnh ring bit trong tng bi hc, nn ngi hc c th b qua mt s bi khi cm thy nm vng cc ni c gii thiu trong mi bi hc. Hoc c th lm ti liu tham kho khi cha nm vng mt ni dung no . Sau y chng ti s trnh by ln lt tng ni dung c lit k.

BI 1

TNG QUAN V VI IU KHIN AT91SAM9260


Thnh phn quang trng nht cu to nn mt h thng nhng chnh l vi x l, vi iu khin. Vi x l,vi iu khin quyt dnh n tnh nng, hiu qu ng dng ca h thng nhng. V vy trc khi nghin cu v h thng nhng th chng ta phi c mt kin thc cn bn v vi x l ca h thng nhng. Kit nhng KM9260 c xy dng da trn nn vi iu khin AT91SAM9260. L vi iu khin 32 bit thuc h ARM9 tit kim nng lng. Trong phn ny s trnh by s lc cc kin thc v AT91SAM9260. V lp trnh cho h thng nhng khng t nng kin thc v cu trc ca vi x l. Nn trong phn ny ch trnh by nhng kin thc cn thit cho qu trnh s dng kit sau ny nh: s chn ca AT91SAM9260, ngun cung cp cho AT91SAM9260, bn qun l vng nh ca AT91SAM9260. Trong vi iu khin c tch hp nhiu module ngoi vi khc nhau, kin thc v tng module s c trnh by trong mi bi th nghim vi cc thit b ngoi vi khc nhau.

I.

H vi iu khin ARM:

Cu trc ARM (vit tt t tn gc l Acorn RISC Machine) l mt loi cu trc vi x l 32bit kiu RISC c s dng rng ri trong cc thit k nhng. Do c c im tit kim nng lng, cc b CPU ARM chim u th trong cc sn phm in t di ng, m vi cc sn phm ny vic tiu tn cng sut thp l mt mc tiu thit k quan trng hng u. Ngy nay, hn 75% CPU nhng 32bit l thuc h ARM, iu ny khin ARM tr thnh cu trc 32bit c sn xut nhiu nht trn th gii. CPU ARM c tm thy khp ni trong cc sn phm thng mi in t, t thit b cm tay (PDA, in thoi di ng, my a phng tin, my tr chi cm tay, v my tnh cm tay) cho n cc thit b ngoi vi my tnh ( a cng, b nh tuyn bn.) Mt nhnh ni ting ca h ARM l cc vi x l Xscale ca Intel. Vic thit k ARM c bt u t nm 1983 trong mt d n pht trin ca cng ty my tnh Acorn. Nhm thit k, dn u bi Roger Wilson v Steve Furber, bt u pht trin mt b vi x l c nhiu im tng ng vi K thut MOS 6502 tin tin. Acorn tng sn xut nhiu my tnh da trn 6502, v vy vic to ra mt chip nh vy l mt bc tin ng k ca cng ty ny. Nhm thit k hon thnh vic pht trin mu gi l ARM1 vo nm 1985, v vo nm sau, nhm hon thnh sn phm thcgi l ARM2. ARM2 c tuyn d liu 32bit, khng gian a ch 26bit tc cho php qun l n 64 Mbyte a ch v 16 thanh ghi 32bit. Mt trong nhng thanh ghi ny ng vai tr l b m chng trnh vi 6 bit cao nht v 2 bit thp nht lu gi cc c trng thi ca b vi x l. C th ni ARM2 l b vi x l 32bit kh dng n gin nht trn th gii, vi ch gm 30.000 transistor (so vi b vi x l lu hn bn nm ca Motorola l 68000 vi khong 68.000 transistor). S n gin nh vy c c nh ARM khng c vi chng trnh (m chim khong 1/4 n 1/3 trong 68000) v cng ging nh hu ht cc CPU vo thi , khng h cha cache. S n gin ny a n c im tiu th cng sut thp ca ARM. Th h sau ARM3 c to ra vi 4KB cache v c chc nng c ci thin tt hn na. Vo nhng nm cui thp nin 80, hng my tnh Apple Computer bt u hp tc vi Acorn pht trin cc th h li ARM mi . Cng vic ny tr nn quan trng n ni Acorn nng nhm thit k tr thnh mt cng ty mi gi l Advanced RISC Machines. V l do bn thng c gii thch ARM l ch vit tt ca Advanced RISC

Machines thay v Acorn RISC Machine. Advanced RISC Machines tr thnh cng ty ARM Limited khi cng ty ny c a ra sn chng khon London v NASDAQ nm 1998. Kt qu s hp tc ny l ARM6. Mu u tin c cng b vo nm 1991 v Apple s dng b vi x l ARM 610 da trn ARM6 lm c s cho PDA hiu Apple Newton. Vo nm 1994, Acorn dng ARM 610 lm CPU trong cc my vi tnh RiscPC ca h. Tri qua nhiu th h nhng li ARM gn nh khng thay i kch thc. ARM2 c 30.000 transistors trong khi ARM6 ch tng ln n 35.000. tng ca nh sn xut li ARM l sao cho ngi s dng c th ghp li ARM vi mt s b phn ty chn no to ra mt CPU hon chnh, mt loi CPU m c th to ra trn nhng nh my sn xut bn dn c v vn tip tc to ra c sn phm vi nhiu tnh nng m gi thnh vn thp. Th h thnh cng nht c l l ARM7TDMI vi hng trm triu li c s dng trong cc my in thoi di ng, h thng video game cm tay, v Sega Dreamcast. Trong khi cng ty ARM ch tp trung vo vic bn li IP, cng c mt s giy php to ra b vi iu khin da trn li ny. Dreamcast a ra b vi x l SH4 m ch mn mt s tng t ARM (tiu tn cng sut thp, tp lnh gn ) nhng phn cn li th khc vi ARM. Dreamcast cng to ra mt chip x l m thanh c thit k bi Yamaha vi li ARM7. Bn cnh , Gameboy Advance ca Nintendo, dng ARM7 TDMI tn s 16,78 MHz. Hng DEC cng bn giy php v li cu trc ARM (i khi chng ta c th b nhm ln v h cng sn xut ra DEC Alpha) v sn xut ra th h Strong ARM. Hot ng tn s 233 MHz m CPU ny ch tiu tn khong 1 watt cng sut (nhng i sau cn tiu tn t cng sut hn na). Sau nhng kin tng, Intel cng c chp nhn sn xut ARM v Intel nm ly c hi ny b sung vo th h gi ci i960 ca h bng Strong ARM. T , Intel pht trin cho chnh h mt sn phm chc nng cao gi tn l Xscale.

Bng 2.1: Cc h vi x l ARM H Li ARM7TDMIS ARM710T ARM7TDMI ARM720T ARM740T ARM7EJS ARM9TDMI ARM9TDMI ARM920T ARM922T ARM940T ARM946ES ARM966ES ARM9E ARM968ES ARM926EJS ARM996HS ARM1020E ARM10E ARM1022E ARM1026EJS ARM1136J(F)S ARM11 ARM1156T2(F)S ARM1176JZ(F)S ARM11 MPCore CortexA8 Cortex CortexR4 CortexM3 80200/IOP310/IOP315 XScale 80219 IOP321 1 GHz 600 MHz 100MHz V5TE V V5TEJ V6 V6T2 V6Z V6 V7A V7M V7R 180 MHz V5TE V V5TEJ 180 MHz V4T Tc x l ti a (MHz) 16.8 MHz 40 MHz 59.8 MHz V4T Kin trc

IOP33x PXA210/PXA250 PXA255 PXA26x PXA27x PXA800(E)F Monahans PXA900 IXC1100 IXP2400/IXP2800 IXP2850 IXP2325/IXP2350 IXP42x IXP460/IXP465 t c mt thit k gn, n gin v nhanh, cc nh thit k ARM xy dng n theo kiu ni cng khng c vi chng trnh, ging vi b vi x l 8bit 6502 tng c dng trong cc my vi tnh trc ca hng Acorn. Cu trc ARM bao gm cc c tnh ca RISC nh sau: Cu trc np/lu tr. Khng cho php truy xut b nh khng thng hng (by gi cho php trong li Arm v6). Tp lnh trc giao. File thanh ghi ln gm 1632bit. Chiu di m my c nh l 32 bit d gii m v thc hin pipeline, t c iu ny phi chp nhn gim mt m my. Hu ht cc lnh u thc hin trong vng mt chu k n. So vi cc b vi x l cng thi nh Intel 80286 v Motorola 68020, trong ARM c mt s tnh cht kh c o nh sau: Hu ht tt c cc lnh u cho php thc thi c iu kin, iu ny lm gim vic phi vit cc tiu r nhnh cng nh b cho vic khng c mt b d on r nhnh. 1.25 GHz 624 MHz 400 MHz

Trong cc lnh s hc, ch ra iu kin thc hin, ngi lp trnh ch cn sa m iu kin. C mt thanh ghi dch ng thng 32bit m c th s dng vi chc nng hon ho vi hu ht cc lnh s hc v vic tnh ton a ch. C cc kiu nh a ch theo ch s rt mnh. C h thng con thc hin ngt hai mc u tin n gin nhng rt nhanh, km theo cho php chuyn tng nhm thanh ghi.

II. Vi iu khin AT91SAM9260: 1. c im chnh: AT91SAM9260 c li l b vi x l ARM926EJS thuc h ARM9E h tr tp lnh Thumb (tp lnh nn t 32 bit xung 16 bit) v ARM v c th hot ng vi tc 180Mhz. - B nh: Giao din bus 32 bit h tr 4 bank SDRAM, b nh tnh, CompactFlash, NandFlash. C 2 SRAM c tch hp bn trong chp hot ng tc cao. Mi SRAM c dung lng 4 Kbyte. C 1 ROM bn trong chp c dung lng 32 Kbyte cha chng trnh h thng phc v cho vic khi ng h thng nhng do nh sn np sn, - Ngoi vi: Bn trong chip tch hp 4 knh ADC 10 bit. C 2 b truyn d liu khng ng b UART (Universal Asynchronous Receive/Transmitter) C 4 b truyn d liu khng ng b/ng b USART (Universal Synchronous Asynchronous Receive/Transmitter). Mt giao din truyn nhn d liu theo chun I2C (chun hai dy). Mt b iu khin ni tip ng b. Hai giao tip SPI h tr hai ch Master/Slaver. Mt giao din SD/MMC (dng c th nh). Mt b iu khin 10/100 Mbps Ethernet MAC. Mt b iu khin truyn nhn USB v mt b truyn nhn USB Device. Ba b Timer/Counter. - H thng:

C 22 knh DMA (Direction Memory Access). Khi ng t NAND Flash, SDCard, DataFlash hoc Serial DataFlash. C b iu khin Reset. Ma trn bus AHB 6 lp 32 bit hot ng tn s 90Mhz. Mt PLL (b nhn tn s) cho h thng v mt cho USB. Hai tn hiu xung ng b ngoi c th lp trnh c. C b iu khin ngt cao cp v sa li. Tch hp b dao ng ni RC. Cho php chn tn s tit kim nng lng 32,768 Khz v b dao ng chnh 3 n 20 Mhz. Cho php ci t ch timer, watchdog timer, realtime timer. Khi xut nhp: Ba b iu khin Input/Output song song 32 bit. C 96 ng Input/Output a mc ch. 2. S chn ca AT91SAM9260: - AT91SAM9260 c b ngoi hnh vung, c hai dng s chn: mt dng 208 chn v mt dng 217 chn. - Dng 208 chn: Cc chn c a ra xung quanh ca gi nha bc li v c t tn theo s t 1 n 208. Hnh dng c minh ha nh sau:

Hnh 2.1: S chn ca AT91SAM9260 208 chn - Dng 217 chn: cc chn c a ra pha di ca gi nha bc li. Hnh dng c minh ha nh sau:

Hnh 2.2: S chn ca A91SAM9260 217 chn V tr ca cc chn ny c xc nh bng cch ghp cc ch ci ca hng vi cc s ca ct v chn gn vi chm en lm du trn thn ca chp l chn A1. V s lng chn ca chip rt ln nn trong gio trnh ny khng trnh by c th chc nng ca tng chn. Nu ngi hc mun tm hiu thm v s chn ca AT92SAM9260 th c th tham kho Datasheet ca AT91SAM9260. 3. Ngun cp cho AT91SAM9260: c tnh tit kim nng lng l mt trong nhng th mnh ca h vi x l ARM. tit kim c nng lng, bn cnh mt kin trc li tit kim nng lng th vi iu khin cn c thit k c nhiu ngun cp vi cc mc in p khc nhau. AT91SAM9260 cn c hai ngun cp vi cc mc in p 1,8V v 3,3V. Hai ngun cp ny c cung cp ti cc chn ngun ca chp c th cp ngun cho tng modun tch hp trong chip. C th nh sau: - Chn VDDCORE: chn ny cp ngun nui li vi x l vi in p l 1,8V. - Chn VDDIOM: cung cp ngun cho b giao tip Input/Output m rng. in p cp n chn ny l 1,8 V hoc 3,3 V c chn bi phn mm. - Chn VDDIOP0: cung cp cho b giao tip Input/Output ngoi vi (USB, Micro SD) vi in p 3,3V. - Chn VDDBU: cung cp in p cho b dao ng chm (dao ng ni RC v thch anh 32,768 Khz) vi in p 1,8V. - Chn VDDPLL: cung cp in p cho b dao ng chnh v b nhn tn s vi in p l 1,8V. - Chn VDDANA: cung cp in p cho b ADC vi in p 3,3V. 4. Bng vng nh ca AT91SAM9260: AT91SAM9260 c th qun l mt vng nh ln n 4Gbyte a ch, vng nh ny c phn thnh 16 bank vi mi bank l 256Mbyte a ch. Mi bank ny s qun l b

nh ca mt thit b nh nht nh hoc mt vng nh nht nh. Mc d thit b nh hoc vng nh khng cha d liu hoc khng ng dng trong h thng, nhng AT91SAM9260 vn dnh vng nh cho thit b nh hoc vng nh ca n. C th s c trnh by trong hnh sau:

Hnh 2.3: Bng qun l vng nh ca AT91SAM9260 Theo hnh trn th chng ta c th thy bng vng nh ca AT91SAM9260 c chia ra thnh nhiu bank qun l. Bank trn cng l bank 0, tip theo l bank 1, cho

n cui cng l bank 15. Cc a ch nm bn tri cc ct chnh l cc a ch vt l. Bn phi cc ct l dung lng ca vng nh tng ng. Chng ta c th thy rng mi thit b nh hoc vng nh u c vi x l qun l trong mt khong a ch nht nh. Nu thit b nh c qun l bi bank 1 th nh u tin ca thit b nh (c a ch l 0x0000000) s c vi x l c vi a ch l 0x10000000 , nh th hai (c a ch 0x00000001) s c c vi a ch l 0x10000001. Tng t th nh cui cng ca thit b nh (c a ch 0x0FFFFFFF) c vi x l c vi a ch l 0x1FFFFFFF. Nh vy, chng ta c th thy a ch thc t ca nh c vi x l c vi mt a ch hon ton khc. thun tin cho vic tm hiu sau ny v trnh nhm ln v a ch chng ta s tm hiu v cc loi a ch: a ch vt l: l a ch m vi x l gn cho vng nh cn c qun l. Theo hnh trn th a ch vt l chnh l cc a ch nm bn tri cc ct. a ch on: l a ch vt l ti nh u tin ca vng nh. Theo hnh trn th a ch on ca bank 1 l 0x10000000. a ch offset: l khong cch tnh t nh ang xt n a ch on. Nh vy a ch offset c th hiu l a ch thc t ca thit b nh. a ch offset ca nh th nht ca thit b nh l 0x00000000, ca nh th hai l 0x00000001 v ca nh cui cng l 0x0FFFFFFF. Bank 0 dng qun l b nh ni ca ca vi x l. ROM c qun l vi a ch vt l t 0x00100000 n 0x00108000 vi dung lng l 32Kbyte. Tng t vng nh SRAM0 cng c qun l t 0x00200000 n 0x00201000 , cc vng nh reserved l cc vng nh d tr. T Bank 1 n bank 8 dng qun l cc thit b nh bn ngoi. C th, bank 2 qun l SDRAMC vi chn chn chip l NCS1. Bank 4 qun l NandFlash vi chn chn chip l NCS3/NANDCS. Khi vi x l truy cp cc thit b nh ny th vi x l s a tn hiu chn vng nh ra cc chn NCS0 n NCS7 chn chip tng ng. Bank 15 qun l qun l vng nh ca cc thit b ngoi vi. Cc vng nh c mu m l cc vng nh d tr hoc l cha s dng n. III. Kt lun: AT91SAM9260 l mt vi x l c tc hot ng cao 180 Mhz, nhiu ngoi vi, tit kim nng lng. Vi iu khin ny s dng hai ngun in p l 1,8V v 3,3V cho cc modun khc nhau. Ngoi ra vi iu khin ny c th qun l mt vng nh ln n 4Gbyte v c chia thnh nhiu vng qun l ng vi cc vng nh khc nhau.

Nh vy, sau khi c xong chng ny ngi hc c mt nn kin thc v vi iu khin AT91SAM9260. Cc kin thc ny s b tr cho qu trnh lp trnh ng dng sau ny ca ngi hc.

BI 2

MT S THAO TC C BN TRN H IU HNH LINUX. A-TNG QUAN V LINUX


H iu hnh Linux l mt h iu hnh m ngun m v cn kh non tr so vi h iu hnh Window. Nhng vi nhng u im ca mnh: min ph, linh hot, uyn chuyn, an ton cao, thng nht trn cc h thng phn cng, m ngun m Linux pht trin mnh m, a dng v chim c s tin tng ca cc lp trnh vin. Cc h thng nhng hin nay a s chy trn h iu hnh Linux. V vy mun ng dng c h thng nhng th iu tin quyt l ngi dng phi bit s dng h iu hnh Linux. Phn ny s trnh by v cc khi nim v phn vng a, cch truy xut a trong Linux, gii thiu cc th mc h thng, mng hnh terminal, tp lnh c bn ca h iu hnh Linux. y l cc kin thc c bn u tin ngi hc cn c bc vo th gii k diu ca Linux.

I.
1.

Qun l b nh trong Linux:


Phn vng a: Trong cc my vi tnh hin nay, a cng l thit b lu tr c s dng ph bin

nht. a cng l mt loi a t, ra i sau a mm, c dung lng ln 32GB, 80GB v vi k thut tin tin nh hin nay th dung lng ca a cng t n n v TB. V dung lng ca a cng ln nn thun li trong vic qun l ni dung lu trn a, ng thi tng hiu sut s dng a cng th a cng s c chia thnh nhiu phn vng hay cn gi l Partition. C hai loi Partition l Primary Partition v Extended Partition. Primary Partition l phn vng chnh, phn vng ny thng c dng ci h iu hnh. Theo nguyn tc th trn mt a cng ta chia c ti a l 4 Primary Patition. Nh vy vi mt a cng th ta ch c th ci ti a l 4 h iu hnh. Lu rng : ta khng th chia Primary Partition thnh cc phn vng nh hn v Primary Partition ngoi vic dng ci t h iu hnh th ta c th dng Primary Partition lu tr d liu. Extended Partition l phn vng m rng. Thc ra Extended Partition ging nh Primary Partition, nhng vi Extended Partition ta c th chia thnh nhiu phn vng nh

hn bn trong Extended Partition v c gi l Logical Partition ( Phn vng logic). Extended Partition thng dng lu tr d liu ca ngi dng.
PrimaryPartition ExtendedPartition

15G Window XP 10 G 5G 5G 15G Linux Hnh 2.4 : Phn vng ca a cng 5G


Cha phn vng

LogicalPartition

Hnh trn minh ha cho vic phn vng cc Partition trn mt a cng 60G. Theo hnh trn, phn vng mu xanh dng 15G v mu xanh l cy 15G l cc Primary Partition. Hai phn vng ny cha h iu hnh. Mi Primary Partition ch c cha mt h iu hnh, hai h iu hnh c th tn ti trn cng mt a cng nu chng c ci t trn hai Primary Partition khc nhau v dung lng a cho php. Phn vng mu trng 25G l Extended Partition thng c dng lu tr d liu ca ngi dng. Phn vng ny c chia thnh 4 phn vng nh khc l cc Logical Partition c dung lng ln lc l 10G, 5G, 5G, 5G. Phn vng mu xanh l l vng a cha c phn vng. Thng thng i vi cc phn vng ny th h thng mc nh l Extended Partition. Nh vy i vi a cng trn th ta c 2 Primary Partition, 2 Extended Partition, 4 Logical Partition. Mc d ta chia a cng thnh cc phn vng, nhng khi ci h iu hnh ln a cng th mi h iu hnh li nhn din v truy xut cc phn vng ny theo cch khc nhau. V d : h iu hnh Window th nhn din cc phn vng ny l cc a (a C l Primary Partition, a D,E, l cc Logical Partition) v truy xut phn vng ny thng qua cc a ny. Cn i vi h iu hnh Linux th nhn din cc phn vng ny l cc tp tin v vic truy xut cc phn vng ny cng thng qua cc tp tin ny. Kit KM9260 s dng h iu hnh Linux, nn trong gio trnh ny ch cp n cch nhn din v truy xut phn vng trn a cng ca Linux.

2.

Phn vng ca Linux : Nh ni trn, Linux nhn din tt c cc loi a v thit b l cc tp tin nn

vic truy xut cc a v thit b cng thng qua cc tp tin ny. i vi a mm v cc phn vng ca a cng Linux quy c cch t tn nh sau : a mm th nht l fd0, a mm th hai l fd1. a cng th nht l hda, a cng th hai l hdb .Nu c dng USB th l sda, sdb, sdc, .Cc phn vng chnh (Primary Partition hay Extended Partition) c nh s t 1 n 4. Cc phn vng Logical Partition c nh s t 5 tr ln. V d: hda1 l phn vng chnh ca a cng th nht, hda2 l phn vng m rng ca a cng th nht. Cn hda5, hda6, hda7 l cc phn vng Logical Partition trong Extended Partition. Cc tp tin truy xut phn vng ny thng c Linux lu trong th mc /dev. Chng ta lu n k t / trong Linux. Linux quy c k hiu / l Primary Partition ca h thng, l phn vng cha nhn h iu hnh Linux. Tt c cc ng dn trong Linux u phi c bt u bi k hiu ny. Nh vy, cc tp tin truy xut phn vng v a nm trong th mc /dev c ngha l th mc dev nm trong Primary Partition, cc tp tin fd0, fd1, , hda0, hda1 nm trong th mc dev nhng khi truy xut cc tp tin ny l ta truy xut cc phn vng tng ng trn a cng ch khng phi ch truy xut Primary Partition. K hiu / cn c dng lm du phn cch th mc. V d: ta c ng dn: /home/Nhan/Kernel. Theo ng dn ny ta thy th mc home nm trong th mc gc (Primary Partition) v trong th mc home c th mc Nhan, trong th mc Nhan c th mc Kernel. phn cch gia cc th mc ta dng k hiu /. 3. Cch truy xut a trong Linux: Trong Linux khng c khi nim a nh trong Window. Nn vic truy xut cc phn vng Linux s dng php gn (mount) tn a vi tn mt th mc bt k. Khi khi ng h iu hnh, Linux gn cho phn vng chnh (Primary Partition) k hiu /, cc thng tin ca phn vng khc c Linux t vo trong th mc /dev ca phn vng chnh. Nu mun truy xut cc phn vng ny th ta thc hin thao tc kt gn bng lnh mount. V d: Trong th mc /dev c cc tp tin: fd0: mm th nht hda1: Primary Partition

hda5, hda6, hda7: Logical Partition th nht, th hai, th 3 nm trong Extended Partition. Trong th mc /home c cc th mc: diamem odiachinh odiaphu1 odiaphu2 odiaphu3 Mun truy xut cc phn vng v a th ta phi dng lnh sau: mount mount mount mount mount /dev/fd0 /home/diamem /dev/hda1 /home/odiachinh /dev/hda5 /home/odiaphu1 /dev/hda6 /home/odiaphu2 /dev/hda7 /home/odiaphu3

Lc ny cc thao tc sao chp, ct, dn file vo trong cc th mc diamem, odiachinh, odiaphu1, odiaphu2, odiaphu3 cng tng dng vi vic truy xut d liu tng ng vo a mm, Primary Partition v cc Logical Partition. Khi khng mun s dng phn vng na ta c th dng lnh umount tho kt gn: umount diamem umount odiachinh umount odiaphu1 umount odiaphu2 umount odiaphu3 4. Cc th mc trn Linux: Khi ci t h iu hnh xong th ta s thy trong Primary Partition c rt nhiu th mc. Cc th mc ny c cc chc nng v mc ch s dng nht nh. C bn mt h thng Linux thng c cc th mc sau: /bin: Th mc ny cha cc file chng trnh thc thi (dng nh phn) v file khi ng ca h thng. /boot: Cc file nh (image file) ca kernel dng cho qu trnh khi ng thng t trong th mc ny. /dev: Th mc ny cha cc file thit b. Trong th gii Linux cc thit b phn cng c xem nh l cc file.

/ect: Th mc ny cha cc file cu hnh ton cc ca h thng. C th c nhiu th mc con trong th mc ny nhng nhn chung chng ch cc file script khi ng hay phc v cho mc ch cu hnh chng trnh trc khi chy. /home: Th mc ny cha cc th mc con i din cho mi user khi ng nhp. Ni y ta nh ngi nh ca ngi dng. Khi ngi qun tr to ti khon cho bn, h cp cho bn mt th mc con trong /home. Bn hon ton c quyn sao chp, xa file, to th mc con trong th mc home ca mnh m khng nh hng n cc ngi dng khc. /lib: Th mc ny cha cc file th vin .so hoc .sa. Cc th vin C v cc th vin lin kt ng cn cho chng trnh khi chy v cho ton h thng. /lostfound: Khi h thng khi ng hoc khi chy chng trnh fsck, nu tm thy mt chui d liu no b tht lc trn a cng khng lin quan n tp tin, Linux s gp chng li v t trong th mc ny nu cn bn c th c v gi li d liu b mt. /mnt: Th mc ny cha cc th mc kt gn tm thi n cc a hay thit b khc. Bn c th thy trong /mnt cc th mc con nh cdrom hoc floppy. /sbin: Th mc ny cha cc file hay chng trnh thc thi ca h thng thng ch cho php s dng bi ngi qun tr. /tmp: Th mc ny cha cc file tm m chng trnh s dng ch trong qu trnh chy. Cc file trong th mc ny s c h thng dn dp nu khng cn dng n na. /usr: Th mc ny cha rt nhiu th mc con nh /usr/bin hay /usr/sbin. Mt trong nhng th mc con quan trng trong /usr l /usr/local, bn trong th mc local ny bn c cc th mc con tng t ngoi th mc gc nh sbin, lib, bin,. Nu bn nng cp h thng th cc chng trnh bn ci t trong usr/local vn gi nguyn v bn khng s chng trnh b mt mt. Hu ht cc ng dng Linux u thch ci chng trnh vo trong /usr/local. /var: Th mc ny cha cc file bin thin bt thng nh cc file d liu t nhin tng kch thc trong mt thi gian ngn sau li gim kch thc xung cn rt nh. in hnh l cc file dng lm hm i cha d liu cn a ra my in hoc cc hng i cha mail. /usr/include hoc /usr/local/include: cha cc file khai bo hm (header) cn dng khi bin dch chng trnh ngun s dng cc th vin ca h thng. /usr/src: Cha m ngun.

/usr/man: Cha ti liu hng dn.

II.

Mn hnh terminal:

Ngy nay vi s pht trin hin i ca cng ngh sn xut chp v s tin b trong vic lp trnh h diu hnh th chng ta rt l quen thuc vi cc h iu hnh c h tr ha nh Window XP, Window 7, Linux Ubutu. Vi chc nng h tr ha ca mnh, cc h iu hnh ny gip cho ngi s dng thun tin trong vic thc hin cc thao tc (ch cn dng chut thc hin lnh) v to ra giao din tng tc thn thin i vi ngi dng. Ngi dng khng cn phi bit tp lnh ca h iu hnh m ch cn bit thao tc thc hin. V d: sao chp mt tp tin trong Ubutu, ngi dng khng cn phi bit lnh sao chp ca h iu hnh l g, m ch cn bit tho tc sao chp file l c: click chut phi vo file, chn copy, sau n vng cn copy ti, click chut phi v chn past into folder. Tuy nhin trong thc t khng phi h iu hnh no cng c h tr ha v khng phi h thng no nhng no cng c h tr ha. V vy m hu ht cc h iu hnh hin nay vn cn gi phng thc giao tip vi ngi s dng thng qua cc dng lnh. Tn ti song song vi phng thc giao tip qua ha, phng thc giao tip thng qua cc dng lnh pht huy tc dng trong cc h thng nhng nh KIT KM9260, cc trng hp s c m chc nng ha khng th hot ng c. Trong Linux Ubutu hay cc phin bn Linux c h tr ha th phng thc giao tip thng qua cc dng lnh c thc hin trn mn hnh Terminal

Hnh 2.5: Mn hnh Terminal ca Linux

KIT KM9260 s dng h iu hnh Linux khng c h tr ha, v vy m vic giao tip thng qua cc dng lnh l ht sc quang trng. Khi khi ng th mn hnh Terminal ca Linux s t ng c kch hot.

III. Tp lnh c bn ca Linux:


ls find cp cat vi man mv rm mkdir rmdir clear cd chmod uname pwd ps kill gunzip gzip tar env export echo Nhm lnh h thng: C php ls <th mc> find <tn file> cp file1 file2 cat > <tn file> cat <tn file> vi <tn file> man <t kha> mv file1 file2 rm file rm r <tn th mc> mkdir <tn th mc> rmdir <tn th mc> clear cd <ng dn> chmod <tham s><tn file> uname r pwd ps kill <s PID > gunzip <tn file> gzip <tn file> tar <tham s> <tn file> env export <tn bin>= <ni dung ca bin> echo <tn bin> In chui ra mn hnh Tm file Sao chp file To file vn bn mi Hin th ni dung file Son tho ni dung file Hng dn v lnh i tn file, th mc, di chuyn file Xa file Xa cy th mc To th mc mi Xa th mc rng Xa mn hnh Di chuyn n th mc khc i thuc tnh file, th mc Xem phin bn ca h iu hnh Xem ng dn th mc hin hnh Xem thng tin v tin trnh Hy tin trnh Gii nn file Nn file Nn v gii nn file Xem thng tin v bin mi trng Thit lp bin mi trng Chc nng Lit k ni dung tp tin th mc Lnh

df fsck

df fsck

Xem dung lng a Kim tra a v h thng file

Bng 2.2: Cc lnh h thng ca Linux Nhm lnh qun l ti khon ng nhp: Lnh Useradd Userdel Groupadd Groupdel C php user <tn ti khon> userdel <tn ti khon> groupadd <tn nhm> groupdel <tn nhm> Chc nng Thm ti khon ngi dng Xa ti khon ngi dng To nhm mi Xa nhm

Bng 2.3: Cc lnh qun l ti khon ca Linux Cch s dng chi tit cc lnh ny s c trnh by k trong phn tip theo l: cc thao tc c bn trn h iu hnh Linux.

IV. Kt lun:
Linux qun l cc vng nh bng cc tp tin trong th mc /dev. Ngi dng truy xut cc vng nh ny bng cch kt gn cc tp tin ny vi th mc bt k trong Linux. Trong Linux chng ta thao tc cc lnh thng qua mn hnh terminal hoc chng trnh giao din X-Window. Nhng thao tc lnh thng qua mn hnh terminal c s dng nhiu hn i vi cc h thng nhng khng h tr ha nh Kit nhng KM9260.. Nh vy, sau khi c xong phn ny ngi hc phn no c khi nim v h iu hnh Linux. Cc kin thc ny s l nn tn cho ngi hc trong nhng phn sau. Trong phn tip theo chng ta s tm hiu k hn v cc lnh trong Linux.

A-CC THAO TC C BN
Nh nu trong phn trc, ngi dng thng thao tc vi h iu hnh Linux trn cc Kit nhng thng qua mn hnh terminal bng cch ra lnh cho h iu hnh. V vy dng c Linux th chng ta phi bit c cc lnh trong Linux. Trong phn ny s trnh by cc lnh ca Linux h tr cho cc thao tc c bn nh: lit k th mc tp tin, to, xa th mc tp tin, sao chp th mc tp tin, di chuyn v i tn th mc tp tin, kt gn a, thay i th mc hin hnh, v mt s lnh ca h thng..

I.
1. 2.

Ni dung:
Khi ng li (reset) h thng v tt h thng: khi ng li h thng ta dng lnh:
$ reset

tt h thng ta dng lnh:


$ poweroff

S dng ti liu hng dn man:

Man l mt chng trnh c sn trong Linux c chc nng d tm cc thng tin m bn ng nhp vo t dng lnh (gi l kha hay keyword). Nu tm thy, ni dung chi tit m t v kha hoc nhng thng tin lin quan n kha s c hin th y bn tham kho. Bn c th gi trnh man theo c php sau: /$ man <keyword> thot khi ti liu man chng ta c th g q v nhn Enter V d: tm hiu v ni dung v cch s dng lnh ls chng ta g /$ man ls Khi ti liu man v lnh ls s hin ra

Hnh 2.6: Trnh man hng dn lnh ls Trong ti liu man s lit k tn, c php, chc nng ca lnh m ta cn tm. Ngoi ra, ti liu man cn lit k ra cc tham s c th i cng vi lnh. V d: nh lnh ls th ta c th thy ti liu man lit k ra hai tham s l a v A. Nu chng ta dng lnh /$ ls a Th chng trnh s lit k tt c tp tin v th mc c trong th mc gc v hai du . v .. . Cn nu ta dng lnh /$ ls A Th chng trnh s lit k tt c cc tp tin v th mc c trong th mc gc nhng s khng lit k hai du . v .. Mc 1 2 3 4 5 6 7 8 Trnh man phn cc hng dn ra lm thnh tng on (session) vi nhng ch khc nhau gm: Tn mc User command System call Subroutines Devices File format Games Miscell Sys. Admin Ni dung Cc lnh thng thng ca h iu hnh Cc hm kernel ca h thng Cc hm th vin Cc hm truy xut v x l file thit b Cc hm nh dng file Cc lnh lin quan n tr chi Cc hm linh tinh Cc lnh qun tr h thng

Bng 2.4: Cc nhm lnh trnh man h tr Thng thng nu chng ta gi man v khng ch nh thm g c ngoi t kha cn tm th man s tm t kha trong phn on 1 (user command). Tuy nhin chng ta c th yu cu man tm trong mt phn on khc. V d t kha printf va l mt lnh ca h iu hnh va l mt hm ca C. Nu chng ta mun tm printf lin quan n h iu hnh (user command) chng ta s g: /$ man printf Hoc /$ man 1 printf Khi trnh man s lit k thng tin ca lnh printf lin quan n h iu hnh nh sau:

Hnh 2.7: Trnh man hng dn lnh printf ca h iu hnh Cn nu chng ta g: /$ man 3 printf Th man s lit k cc thng tin ca printf lin quan n hm th vin C nh sau :

Hnh 2.8: Trnh man hng dn lnh printf trong lnh C 3. Lit k th mc tp tin: lit k th mc con v tp tin trong mt th mc th ta dng lnh ls. C php ca lnh ls nh sau : /$ ls <ng dn v tn th mc cn lit k th mc con v ni dung> Ngoi ra lnh ls cn c h tr thm tham s : /$ ls l <ng dn v tn th mc cn lit k th mc con v ni dung> ( lit k cc th mc con v tp tin theo dng danh sch chi tit)

Hnh 2.9: Lnh ls lit k th mc tp tin 4. To v xa th mc tp tin: to th mc ta dng lnh mkdir /$ mkdir <ng dn v tn th mc cn to> xa th mc th ta dng lnh rmdir /$ rmdir <ng dn v tn th mc cn xa>

V d: ang ng a gc, to th mc /home/nhan/kernel, sau xa ln lc th mc kernel v nhan. Trc tin l ta phi to th mc nhan trong th mc home. V th mc home l th mc c sn trong Linux nn ta khng cn phi to li na. Sau ta to th mc kernel nm trong th mc nhan v xa hai th mc va to. Trnh t dng lnh nh sau : /$ mkdir /home/nhan /$ mkdir /home/nhan/kernel /$ rmdir /home/nhan/kernel /$rmdir /home/nhan to ra mt tp tin th ta dng lnh cat /$ cat > <ng dn v tn tp tin mun to> xa mt tp tin th ta dng lnh rm /$ rm <ng dn v tn tp tin mun xa> xem ni dung mt tp tin th ta dng /$ cat < ng dn v tn tp tin mun xem> V d : ng th mc gc to mt tp tin /home/nhan/app/test1, sau xa tp tin ny. Th t dng lnh nh sau : /$ mkdir /home/nhan /$mkdir /home/nhan/app /$ cat > /home/nhan/app/test1 Lc ny chng ta c th nhp ni dung cho tp tin test1. Nu mun thot khi tp tin th ta nhn CtrlD xem nt dung ca tp tin va to th ta dng /$ cat /home/nhan/app/test1 Ta xa tp tin test1 /$ rm /home/nhan/app/test1 Lu : trong qu trnh to th mc v tp tin th chng ta c th dng lnh ls kim tra xem tp tin hay th mc c to hay cha. 5. Kt gn a v th mc: Nh ni cc phn trc, truy xut c cc thit b lu tr hoc cc phn vng th chng ta phi kt gn thit b lu tr hay phn vng ny vi file tng ng trong Linux. lm c vic ny th ta dng lnh mount. Lnh mount c c php nh sau:

/$ mount t vfstype devicefile mdir Trong , devicefile l ng dn n file m Linux nhn din thit b. Ty chn -t s kt gn theo kiu h thng file trn thit b do vfstype qui nh. mdir l ng dn kt ni vo h thng th mc ca Linux. Hin nay Linux c th c c rt nhiu h thng file, vsftype c th bao gm nhng kiu h thng file thng dng sau : Msdos : h thng file v th mc theo bng FAT16, FAT32 ca DOS Ntfs: nh dng h thng file NTFS ca Window NT Ext2: nh dng h thng file chun ca Linux v Unix Nfs: nh dng h thng file truy xut qua mng Iso9660: h thn file theo chun ISO tho kt gn ta dng lnh umount: /$ umount mdir V d1: kt gn a A trong Linux c cc file theo h thng bng FAT ca DOS. Trc tin l ta to th mc kt gn /$ mkdir /dos Gi lnh mount kt gn th mc /$ mount t msdos /dev/fd0 /dos Nu kt gn thnh cng th k t by gi tt c nhng g chng ta ghi vo th mc /dos cng tng ng nh chng ta ghi vo a A. tho kt gn ta dng lnh /$ umount /dos V d 2 : Kt gn a CD-ROM vo th mc /mycdrom /$ mkdir /mycdrom /$ mount t iso9660 /dev/cdrom /mycdrom 6. Thay i th mc hin hnh: Th mc hin hnh l th mc m con tr chng trnh ang . Th mc hin hnh c xc nh bi th mc trc du $ trn dng lnh. V d: Nu bt u dng lnh l du /$ th mc hin hnh l th mc gc Nu bt u dng lnh l /home$ th th mc hin hnh l th mc /home thay i th mc hin hnh th ta dng lnh cd. C php lnh cd nh sau:

/$ cd <ng dn v tn th mc mun lm th mc hin hnh> V d: Ta ang th mc hin hnh l th mc gc, ta thay i th mc hin hnh l /home/nhan, gi s cc th mc c to sn. Ta lm nh sau: /$ cd /home/nhan /home/nhan$ Ta thy rng phn bt u dng lnh thay i /$ thnh /home/nhan$ ngha l th mc hin hnh c thay i. thay i th mc hin hnh l home th ta lm nh sau: /home/nhan$ cd /home Hoc /home/nhan$ cd .. 7. Sao chp tp tin v th mc: Lnh cp ca Linux dng sao chp file. C php ca lnh cp nh sau : $ cp <ng dn v tn file cn sao chp> <ng dn v tn file mun sao chp n> V d : trong th mc /home/nhan/app c tp tin test1, chp tp tin test1 sang th mc /home/nhan/test vi tn test2. Gi s cc th mc c to trc . Th t cc dng lnh nh sau: /$ cp /home/nhan/app/test1 /home/nhan/test/test2 Lnh cp cn dng sao chp cy th mc. sao chp cy th mc th ta thm ty chn R vo lnh cp. V d: sao chp th mc /home/nhan/app sang th mc /home ta lm nh sau: /$ cp R /home/nhan/app /home Lc ny trong th mc /home c thm th mc app 8. Di chuyn v i tn tp tin, th mc: Chng ta dng lnh mv di chuyn hoc i tn file. C php lnh mv nh sau : /$ mv <ng dn v tn file cn di chuyn hoc i tn> <ng dn v tn file mi> V d : Di chuyn file /home/nhan/app/test1 sang th mc /home. Ta lm nh sau: /$ mv /home/nhan/app/test1 /home

Di chuyn file /home/nhan/app/test1 sang th mc /home vi tn test2. Ta lm nh sau:

/$ mv /home/nhan/app/test1 /home/test2 i tn file /home/nhan/app/test1 thnh /home/nhan/app/test3. Ta lm nh sau: /$ mv /home/nhan/app/test1 /home/nhan/app/test3 Lnh mv cn dng di chuyn th mc. /$ mv /home/nhan/app/ /home 9. Phn quyn bo v v truy xut trn tp tin: Mt tp tin hay th mc trong Linux c cc thuc tnh sau: r: ch cho c w: cho php ghi vo tp tin x: cho php thc thi chng trnh -: khng cho php y l cc thuc tnh v quyn truy xut m h iu hnh dng bo v file v th mc. Chng ta c 3 quyn chnh trn mt file hay th mc nh nu trn. Mc d vy cc quyn ny c ch nh cho 3 i tng na l: ngi s hu tp tin (owner), nhm s hu tp tin (group), nhng ngi s dng tp tin thng thng (other user). Tm li tp tin ca chng ta c kim sot bi 3 quyn v truy xut bi 3 i tng khc nhau. Khi chng ta dng lnh /$ ls l Th Linux s lit k cc thuc tnh ca file v th mc trong th mc gc u cc dng V d: di chuyn th mc /home/nhan/app ra th mc /home ta lm nh sau:

Hnh 2.10: Lnh ls lit k chi tit th mc tp tin trong th mc gc Trn thuc tnh phn quyn ca file, i tng c chia thnh 3 nhm t tri sang phi, mi nhm cha 3 phn quyn y nh sau:
rwxrwxrwx

t tnh file user group C u tin cho bit t tnh ca file, thng khng quan trng. Nu l c Hnh 2.11: thuc tnh phn quyn ca tp tin th mc ngha l tp tin thng thng. Trng hp th mc th chng ta s thy c ny k hiu l d. Cn 3 c tip theo l cc thuc tnh tng ng vi 3 nhm. Nu ti v tri ca thuc tnh m c du th c ngha l thuc tnh khng c kch hot cho tp tin hay th mc ny. Cn nu l ch th thuc tnh c kch hot.

Chng ta c th thay i vic kch hot hay khng kch hot cc thuc tnh ny bng lnh chmod. C php ca lnh chmod nh sau: /$ chmod <cc thuc tnh> <tn file hoc th mc>

V d: ta c th mc /home/nhan c cc file v th mc c lnh /$ ls l lit k nh sau:

Hnh 2.12: V d lnh chmod 1 Ta thy cc th mc s c ch d c u tin cn tp tin test th l du -. Tp tin test khng c thuc tnh x cho nhm user, group, other, thuc tnh w cho nhm group v other. By gi chng ta s thm thuc tnh x cho nhm user nh sau:

Hnh 2.13: V d lnh chmod 2 By gi ta thm thuc tnh w v x cho nhm group:

Hnh 2.14: V d lnh chmod 3 Ta c th b kch hot tt c cc thuc tnh ca group nh sau:

Hnh 2.15: V d lnh chmod 4 10. Nn v gii nn tp tin, th mc: Trong Linux chng ta c th nn v gii nn cc file nh *.gz, *.bz2, *.tar nn v gii nn mt file trong Linux chng ta dng lnh tar. Ta dng lnh tar gii nn file *.bz2 nh sau : /$ tar -jxvf *.bz2 Trong : tar l tn lnh j l tham s dng khi nn hoc gii nn file *.bz2 x l tham s dng khi gii nn mt file v l tham s yu cu hin chi tit cc thng tin trong qu trnh nn hay gii nn file f c tc dng ch nh file cn gii nn hay cn nn l *.bz2 cui dng lnh. *.bz2 l file chng ta cn nn hoc gii nn. Ta dng lnh tar gii nn file *.gz nh sau /$ tar zxvf *.gz Trong : z l tham s dng khi nn hoc gii nn file *.gz Ta dng lnh tar gii nn file *.tar nh sau: /$ tar xvf *.tar Ta dng lnh tar xem ni dung mt file *.bz2, *.gz, *.tar nh sau: /$ tar tf <tn file> Trong : t l tham s dng khi ta mun xem ni dung file nn. Ta dng lnh tar nn file *.bz2 nh sau: /$ tar -jcvf *.bz2 <file1> <file2>

Trong : c l tham s chng ta dng khi nn mt file. Ta dng lnh tar nn file *.gz nh sau: /$ tar zcvf *.gz <file1> <file2> Ta dng lnh tar nn file *.tar nh sau : Ngoi ra, nn vi gii nn file *.gz chng ta cng c th dng lnh gzip v lnh gunzip : /$ gzip <file cn nn> /$ gunzip <file *.gz cn gii nn> 11. Bin dch mt chng trnh ng dng: Khi chng ta lp trnh mt ng dng bng ngn ng C trn Linux th chng ta phi bin dch ra file thc thi ng dng . Trong Linux chng ta bin dch mt file ng dng nh sau : /$ gcc <tn file cn bin dch> -o <tn file mun xut ra> Trong : gcc l tn lnh dng bin dch mt chng trnh vit bng ngn ng C. -o l tham s yu cu chng h iu hnh to ra file thc thi vi tn file m ta mun c vit ngay sau o. Nu chng ta khng dng tham s ny th h iu hnh s t ng bin dch ra file a.out. 12. Ci t cc thng s cho chun truyn nhn d liu Ethernet: Ethernet l chun truyn nhn d liu ph bin hin nay. Trong Linux c h tr cc lnh ngi dng c th s dng chun truyn nhn d liu ny. xem a ch IP ca h thng ta dng lnh : $ ifconfig ci t a ch IP tnh cho h thng ta dng lnh : $ ifconfig eth0 <a ch IP tnh> ngng kch hot ch chuyn Ethernet ta dng lnh : $ ifconfig eth0 down Khi ta ngng kch hot ch truyn Ethernet th nu dng lnh $ ifconfig H thng s thng bo khng c kt ni. /$ tar cvf *.tar <file1> <file2

Hnh 2.16 : Thng bo cng Ethernet khng c kt ni kch hot ch truyn Ethernet ta dng lnh : $ ifconfig eth0 up Khi h thng s thng bo sn sn kt ni

Hnh 2.17 : Thng bo cng Ethernet sn sn kim tra h thng c kt ni vi h thng khc hay khng ta dng lnh : $ ping <a ch IP ca h thng khc> Nu thy c kt ni th h thng s truyn nhn 64 byte d liu lin tc cho my c kt ni

Hnh 2.18 : H thng truyn nhn 64 byte d liu khi thc hin lnh ping ngng qu trnh truyn nhn ny chng ta dng t hp phm CtrlC. 13. To mt ti khon ngi dng : xem chng ta ang ng nhp vi ti khon ngi dng no, chng ta dng lnh : $ whoami Chng ta ch to c ti khon ngi dng khi chng ta hot ng trong ti khong root. to ra mt ti khon mi ta dng lnh : $ useradd <tn ti khon mun to> chuyn sang ti khon ngi dng khc ta dng lnh : $ su <tn ti khon ngi dng> V d : ta to mt ti khon tn user1 v ta chuyn sang ti khong user1, ri ta chuyn sang ti khon root. Ta lm nh sau :

Hnh 2.19 : V d v to ti khon ngi dng Ta thy trong ti khon user1 ta thc hin lnh ls b li v cc th mc tp trong th mc gc khng cho cc user khc truy cp. Khi quay tr li ti khon root th chng ta phi nhp password l root00. V trong ti khon root th ta thc hin c lnh ls.

14. Cc thao tc vi bin mi trng ca h thng: H thng Linux c rt nhiu bin mi trng phc v cho qu trnh hot ng ca h thng. xem cc bin mi trng ca h thng ta dng lnh sau : $ env in ni dung ca mt bin mi trng xc nh ra mn hnh ta dng lnh : $ echo $<tn bin mi trng> ci t bin mi trng ta dng lnh sau : $ export <tn bin mi trng> = <ni dung bin> thm ni dung vo bin mi trng ta dng lnh : $ export <tn bin mi trng> = $<tn bin mi trng> <ni dung mun thm vo> Sau khi thm ni dung vo bin mi trng chng ta c h dng lnh echo kim tra. G b bin mi trng : $ unset <tn bin mi trng>

II. Kt lun:
H iu hnh Linux h tr cc thao tc c bn v cn thit trong qu trnh ngi dng tng tc vi h iu hnh. Trong phn ny trnh by hu ht cc lnh cn bn nht cn thit cho ngi hc s dng Linux. Nh vy, sau khi c xong phn ny th ngi hc cn bn s dng c h iu hnh Linux. Nhng trn y ch l nhng lnh cn bn nht ca h iu hnh Linux, Linux cn c rt nhiu lnh khc m ngi son gio trnh khng th lit k ht c. Tuy nhin cc lnh m c trnh by trong gio trnh ny cng ngi hc thao tc vi Linux trong qu trnh hc sau ny.

B- TRNH SON THO VI


Nu chng ta dng h iu hnh Window th chc hn ai cng quen vi trnh son tho Notepad. Trong Linux cng c trnh son tho c tch hp sn trong cc gi h iu hnh Linux l trnh son tho VI. Cng ging nh Notepad, trnh son tho VI dng ngi dng son d liu, vit chng trnh v lu li di dng tp tin. Trong phn ny s hng dn cch s dng trnh son tho VI.

I.

Gii thiu:

VI l chng trnh son tho chun trn cc h iu hnh Unix. N l chng trnh son tho trc quan, hot ng di 2 ch : Ch lnh (command line) v ch son tho (input mode) son tho tp tin mi hoc xem, sa cha tp tin c ta dng lnh: /$ vi <tn tp tin> Khi thc hin, VI s hin ln mn hnh son tho ch lnh. ch lnh, ch c th s dng cc phm thc hin cc thao tc nh: dch chuyn con tr, lu d liu, m tp tin...Do , bn khng th son tho vn bn. Nu mun son tho vn bn, bn phi chuyn t ch lnh sang ch son tho. Ch son tho gip bn s dng bn phm son tho ni dung vn bn.

II.
1. -

Cc lnh thao tc trong VI:


Chuyn ch trong VI: chuyn sang ch son tho chng ta c th dng mt trong hai phm sau trn bn phm: i con tr s gi nguyn v tr. a con tr s dch sang phi mt k t.

2.

chuyn ngc li mode command ta dng phm ESC thc hin cc lnh trong trnh son tho VI th trnh son tho VI phi ch lnh Nhm lnh di chuyn con tr : h sang tri 1 k t e n k t cui cng ca t gn nht bn phi w n k t u tin ca t gn nht bn phi b n k t u tin ca t gn nht bn tri k ln 1 dng

j xung 1 dng ) cui cu ( u cu } u on vn { cui on vn 3. Nhm lnh xa: dw xa 1 t d^ xa k t t con tr n u dng d$ xa k t t con tr n cui dng 3dw xa 3 t dd xa dng hin hnh 5dd xa 5 dng x xa 1 k t Cc t c cch nhau bi khong trng. 4. Nhm lnh thay th: cw thay th 1 t 3cw thay th 3 t cc dng hin hnh 5cc 5 dng 5. Nhm lnh copy, past, undo: y$ copy t v tr hin ti ca cursor n cui cng yy copy ton b dng ti v tr cursor 3yy copy 3 dng lin tip u Undo li thao tc trc 6. Thao tc trn tp tin : :x lu v thot khi ch son tho :wq lu v thot khi ch son tho :w lu vo tp tin mi :q thot nu ko c thay i :q! thot khng lu Sau khi g cc lnh trn th nhn Enter thc thi lnh. copy ta dng lng y v paste ta dng lnh p

III. Kt lun:
VI l trnh son tho ca Linux, VI c hai ch lm vic l ch lnh v ch son tho. Cc thao tc trn VI rt khc so vi cc tc ca cc trnh son tho quen thuc nn lm cho ngi dng cm thy kh khn trong vic son tho d liu vi VI. V tnh phc tp ca trnh son tho VI, nn trong thc t trnh son tho VI ch dng vo mc ch son tho tp tin c ni dung ngn hoc l sa ni dung tp tin trong trng hp cn sa mt cch nhanh chng trong h iu hnh Linux. Cn i vi vic son cc tp tin c ni dung phc tp, di th cc lp trnh vin vn thng dng cc trnh son tho quen thuc ca Window nh Notepad, Wordpad, Microsoft Word,. Nh vy, trong bi ny chng ta lm quen vi h iu hnh Linux, mt trong nhng h iu hnh c s dng ph bin hin nay. Hiu bit v Linux s to nn tn cho chng ta tm hiu su v h thng nhng. Trong bi sau chng ta s tm hiu v h thng nhng l kit nhng KM9260.

BI 3

H THNG PHN CNG V PHN MM TRONG KIT NHNG KM926 A-Phn cng h thng nhng trong kit KM9260:
Mt h thng nhng bao gm hai phn: phn cng v phn mm. Trong phn cng l nn tn, l iu kin cn mt h thng nhng c th tn ti. c th s dng c mt h thng nhng th chng ta phi hiu c phn cng ca n Trong h thng nhng ngoi vi x l l nng ct th bn cnh cn c nhiu kinh kin khc: chp nh, cc thit b ngoi vi, Trong phn ny chng ta s tm hiu phn cng ca Kit KM9260 gm nhng linh kin no, chc nng ca cc linh kin, v tr ca tng linh kin trn board. V phn cng h thng nhng a s l do cc cng ty sn xut thit k, thi cng nn vi t cch l mt ngi nghin cu s dng th trong gio trnh ny chng ta khng i su vo mch nguyn l ca kit nhng. Hnh dng ca board Kit KM9260

Hnh 2.20 : Hnh dng kit KM9260 Cc thnh phn trn board bao gm: STT 1 2 J3 J7 K HIU Cng USB (loi A) Cng USB Devices (loi B) TN

3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 I. II.

U2 J17 J10 U8 J5 U9 U1 J12 U5 RJ1 S1, S2, S3, S4 U10 U11 J12 J16 J14 Cpu (C1):

MT48LC16M16A2, SDRAM 256Mb (32MB) 133Mhz Kt ni m rng SCI Cng truyn d liu ni tip BD9 K9F2G08UOM, NAND Flash (256MB) Giao tip JTAG ICE Serial dataflash (512kB) AT91SAM9260, 16/32 bit ARM926EJ-S 180Mhz Jack ngun 5VDC DM9161EA, Ethernet 10/100 Full-Duplex Cng Giao tip Ethernet (RJ45) Cc nt nhn Khe th nh MicroSD I2C EEPROM Cng tt ngun Kt ni m rng Uart, Adc, Twi Kt ni m rng SPI Bng 2.5: Cc linh kin trn kit KM9260

S dng vi iu khin AT91SAM9260 c gii thiu trong phn trc. B nh: 1. Sdram (U2):

Hnh 2.21 : S kt ni SDRAM

- B nh chnh s dng SDRAM bus 133Mhz, SDRAMC c cu hnh vi bus data 16 bit. - Bng sau trnh by thng s bng vng nh ca SDRAM trong h thng. M s linh kin Chn chn chip a ch logic Dung lng MT48LC16M16A2 TC75 NCS1 0x20000000 0x2000000 (32MB) Bng 2.6: Thng s ca SDRAM - M s linh kin l s c in trn thn ca chip, m s ny do nh sn xut quy nh. - Chn chn chip l NCS1 c ngha l chn CS ca chip c ni vi chn SDCS_NCS1 ca vi x l. - a ch logic l a ch m vi x l gn cho chip tng ng vi NCS1. - Dung lng ca SDRAM l 32 MB 2. Serial dataflash (U9):

Hnh 2.22 : S kt ni Serial DataFlash - Board s dng chp nh serial dataflash kt ni qua ng SPI0 (slot CS1). - AT91Bootstrap, cc bin mi trng (U-Boots Environment Variables), U-Boot c lu tr trong serial dataflash. Cc phn vng cha cc bootloader c th hin bi bng sau:

M s linh kin Chn chn chip a ch logic Dung lng Offset 0x00000000 0x00004200 0x00008400

AT45DB041D-SU NCS2 0xD0000000 0x80000 (512kB) Phn Vng 0 1 2 Phn mm lu Bootstrap Environment U-Boot

Bng 2.7: Thng s ca Serial DataFlash 3. Nand flash (U8):

Hnh 2.23 : S kt ni NAND FLASH - NAND Flash (256MB) dng cha nhn Linux v root file system. 3MB vng nh u tin dnh cho vic cha kernel Linux, phn vng cn li cha root file system ca h thng, bng sau th hin thng s memory map ca NAND Flash.

M s linh kin Chn chn chip a ch logic Dung lng Offset 0x00000000 0x00300000

K9F2G08UOM NCS3 0x40000000 0x10000000 (256MB) Phn Vng 0 1 Phn mm lu Kernel Rootfs (JFFS2)

Bng 2.8: Thng s ca NAND FLASH 4. Th nh MicroSD (U10):

Hnh 2.24 : Khe cm th nh Micro SD - Do c h tr microSD, c th thay th vai tr ca NAND Flash cho vic lu tr kernel Linux v rootfs. Phn vng u tin (first partition) c format theo nh dng FAT, phn vng th 2 c nh dng theo ext2 hoc ext3 dng cha rootfs. load kernel Linux t MicroSD vo SDRAM i hi U-Boot phi h tr mmc sub system command set. MicroSD thng c dng boot Linux c roofs dung lng ln, v d nh Debian distribution. III. Kt ni ngoi vi: 1. Cng USB (J13):

Hnh 2.25 : Cng USB

Cng USB tc truy xut 2.0, tng t MicroSD, h thng c th boot Linux thng qua a di ng USB.. 2. Cng thit b USB (J7):

Hnh 2.26 : Cng USB Device Vi USB device connector, ta c th bin board nhng thnh cc thit b USB. MCU AT91SAM9260 cho php ta truy xut n tt c cc vng nh trong h thng thng qua chng trnh ng dng trn my tnh SAMBA, khi dy cable USB ny c dng n. 3. Cng truyn d liu ni tip BD9 (J10):

Hnh 2.27 : Cng truyn d liu ni tip DB9 AT91SAM9260 c tch hp cng RS232. KM9260 dng cng RS232 ny cho vic hin th, xut nhp vi console chnh ca Linux. 4. Cng kt ni Ethernet (RJ1):

Hnh 2.28 : Cng kt ni Ethernet

AT91SAM9260 c th kt hp vi chp Fast Ethernet PHY DM9161AEP mang li cho h thng tnh nng mnh m v cc ng dng mng. KM9260 c th s dng nh h thng webserver nhng, s dng trong h thng thu thp o lng, iu khin t xa 5. Kt ni m rng SCI (J17):

Hnh 2.29 : Khe cm kt ni m rng SCI S CHN 1 3 5 7 9 TN HIU GND GND TK0 TD0 RK0 CHN VXL 23 (PB16) 27 (PB18) 163 (PB20) S CHN 2 4 6 8 10 TN HIU 5V 3V3 TF0 RD0 RF0 CHN VXL 26 (PB17) 28 (PB19) 164 (PB21)

Bng 2.9: S chn ca khe cm kt ni m rng SCI Connector cho php ta c th m rng kt ni vi cc thit b I2S audio codec, truyn nhn d liu 32bit stream (High-speed Continuous Data Stream)... 6. Kt ni m rng SPI (J14):

Hnh 2.30 : Khe cm kt ni m rng SPI

S CHN TN HIU 1 3 5 7 9 GND SPI1_MISO SPI1_SPCK SPI1_NPCS1 GPIO

CHN VXL 9 (PB0) 11 (PB2 67 (PC5) 63 (PC6)

S CHN TN HIU 2 4 6 8 10 3V3 SPI1_MOSI SPI1_NPCS0 SPI1_NPCS2 GPIO

CHN VXL 10 (PB1) 12 (PB3) 62 (PC4) 64 (PC7)

Bng 2.10: S chn ca khe cm kt ni m rng SPI Connector m rng cho SPI, bao gm 3 ng chip select tng ng cho 3 slot CS0, CS1, CS2. 7. Kt ni m rng Uart, Adc, Twi (J16):

Hnh 31: Khe cm kt ni m rng Uart, Adc, Twi S CHN 1 3 5 7 9 11 13 15 17 19 TN HIU 5V AVDD AGND AD0 IRQ1 CHN VXL 158 (PC0) 127 (PC15) S CHN 2 4 6 8 10 12 14 16 18 20 TN HIU 3V3 GND VREFP AD1 UART_TXD0 UART_TXD1 UART_TXD2 UART_TXD3 TWD GPIO CHN VXL 159 (PC1) 15 (PB4) 17 (PB6) 19 (PB8) 161 (PB10) 208 (PA23) 23 (PB16)

UART_RXD0 16 (PB5) UART_RXD1 18 (PB7) UART_RXD2 20 (PB9) UART_RXD3 162 (PB11) TWCK 1 (PA24)

Bng 2.11: S chn ca khe cm kt ni m rng Uart, Adc, Twi

Connector m rng cho cc cng giao tip serial bao gm UART, TWI, b chuyn i ADC, GPIO, ngt ngoi IRQ1. 8. Giao tip JTAG ICE (J5) :

Hnh 2.32: Khe cm giao tip JTAG ICE S CHN 1 3 5 7 9 11 13 15 17 19 TN HIU 3V3 NTRST TDI TMS TCK RTCK TDO NRST NC NC CHN VXL S CHN 35 30 31 34 37 29 36 2 4 6 8 10 12 14 16 18 20 TN HIU 3V3 GND GND GND GND GND GND GND GND GND CHN VXL -

Bng 2.12: S chn ca khe cm giao tip JTAG ICE Cng JTAG ICE theo chun 20 pin cho php np chng trnh v debug h thng.

IV. Nt nhn: 1. Nt Reset (S2):

Hnh 2.33: Nt reset Reset h thng, tch cc mc thp. 2. Nt Wake up (S1):

Hnh 2.34: Nt Wake up Nt c tc dng nh thc h thng t trng thi power down. 3. Nt ng dng 1 (S3):

Hnh 2.35: Nt ng dng 1 User button, kt ni vi PC15 (chn 127) ca AT91SAM9260 MCU. Tch cc mc thp. 4. Nt ng dng 2 (S4):

Hnh 2.36: Nt ng dng 2 User button, kt ni vi PC8 (pin 61) ca AT91SAM9260 MCU. Tch cc mc thp. V. Led hin th: 1. TN LED LED1 LED2 D6 Led hin th trng thi ca h thng: CHC NNG Shutdown Power Duplex TRNG THI On Off On Off On Off NGHA VXL Trng thi Power down VXL khng hot ng Bt ngun Tt ngun Ethernet PHY full-duplex Ethernet PHY half-duplex

Bng 2.13: ngha ca cc Led hin th trng thi ca h thng 2. Led ng dng:

K hiu l D4, c ni vi chn PA6 (chn 185). Tch cc mc thp. VI. Jumper : 1. K HIU J15 J13 Jumper chn chp : CHC NNG Chn chip Serial dataflash Chn chip NAND Flash Hnh 2.37: Serial DataFlash v Jumper chn Serial DataFlash Jumper chn chip c thit k h tr cho vic khi phc boot loader sau khi ngi dng ghi chng trnh khng ph hp vo vng Bootstrap hoc U-Boot ca h thng 2. K HIU J1 Jumper chn cu hnh h thng: CHC NNG V TR Chn tn s hot ng 1-2 2-3 NGHA Dng dao ng ni RC Dng thch anh 32,768Khz MC NH 2-3

Bng 2.14: Chc nng ca J13 v J15

J2

Chn ngun cho vi x l

1-2 2-3

Dng ngun pin Dng ngun chnh 1,8 V

1-2

Bng 2.15 : Chc nng ca J1 v J2 3. Cc Jumper lin quan n jtag S mch FTAG INTERFACE bao gm cc jumper lin quan n JTAG nh sau :

Hnh 2.38: S kt ni ca giao tip JTAG ICE V tr ca cc Jumper J1, J2, J6, J8, J9, J13 c th hin hnh sau :

Hnh 2.39: Cc jumper J1, J2, J6, J8, J9, J13 VII. Tng kt: Phn cng h thng nhng gm nhiu thnh phn : vi x l, chp nh, ngoi vi, nt nhn, led bo, jump c kt ni vi nhau to thnh mt th thng nht. Mi thnh phn u c mt chc nng ring.

thun li cho vic tm hiu su hn v kit KM9260 th ngi hc ssau khi c phn ny nn c gng nhn din c cc linh kin trn kit, xc nh c v tr, chc nng ca tng linh kin. Nh ni phn trn, chng ta s khng tm hiu su v phn cng ca kit KM9260. Thay vo chng ta s tm hiu k hn v cc phn mm h thng nhng trong phn tip theo ca gio trnh.

B-Phn mm h thng nhng trong kit KM9260:

CHNG III

LP TRNH NHNG NNG CAO

N TT NGHIP

Li u chng
Sau khi nghin cu chng II-Lp trnh nhng cn bn chng ta c c nhng kin thc cn thit tin su hn vo th gii lp trnh phn mm h thng nhng Linux y th v. Trc khi i vo nghin cu nhng ni dung trong chng III, ngi hc phi c nhng kin thc nn tng sau y: S dng c cc lnh trong ngn ng lp trnh C nh: if, if...else, if...else if..., switch...case, ...; hiu v vn dng c cc khi nim trong ngn ng lp trnh C nh: Con tr, cu trc, mng, ... vo chng trnh; Hiu mt cch tng qut cc kin thc c s l thuyt v h iu hnh ni chung. Phi gii thch c cc khi nim v tin trnh, tuyn, chia khe thi gian, ...trong h iu hnh. V mt s nhng k nng cn thit nh bin dch chng trnh ng dng, driver vit bng ngn ng lp trnh C trong Linux; S dng thnh tho cc lnh trong mi trng shell ca Linux; Trong chng III-Lp trnh nhng nng cao chng ta s c tm hiu l thuyt v hai lp trong h thng phn mm nhng l user application v kernel driver cng nh mt s nhng thao tc lp trnh xy dng chng trnh trong hai lp ny. Phn lp trnh nhng nng cao c bin son vit hon chnh cc driver v chng trnh ng dng cho mt s nhng thit b ngoi vi ph bin thng c s dng trong vic dy hc nh: LED n, LED 7 on, LED ma trn, LCD, ADC, ...Do nhng kin thc c trnh by trong chng ny ch l nhng kin thc cn thit phc v cho vic lp trnh d n iu khin cc thit b ngoi vi trn. Nhng kin thc chuyn su khc ngi hc s t tm hiu trong nhng ngun thng tin sch c chng ti gii thiu trong phn ti liu tham kho. Cc bi luyn tp trong quyn sch ny bao gm: Phn A: Lp trnh user application; Phn ny trnh by v d v cch vit chng trnh ng dng trong user, nhc li cch bin dch v thc thi chng trnh trong h iu hnh. Bn cnh cc bn s tip xc vi h thng thi gian thc trong Linux thng qua cc hm tr hon thi gian, cc hm thao tc vi thi gian thc, cc hm to tn hiu nh thi theo chu k. Chng ta cng s ________________________________________________________________________________CH NG II: LP TRNH NHNG NNG CAO 6

N TT NGHIP nghin cu v lp trnh a tin trnh, a tuyn v nguyn l hot ng v cch s dng vo cc chng trnh ng dng thi gian thc. Phn B: Cn bn lp trnh driver; Sau khi lp trnh chng trnh ng dng trong lp User thnh tho, chng ta s tip tc lm vic vi lp su hn l Driver. Qua , ngi hc s hiu vai tr ca Driver, cch phn phi nhim v gia Driver v Application sao cho t hiu qu cao nht. Cc lnh lp trnh driver, cc thao tc ci dt v s dng driver cng s c chng ti trnh by trong chng ny. Trn y l ni dung tng qut ca phn II-Lp trnh h thng nhng nng cao. Mi bi luyn tp iu bao gm trnh by l thuyt v chng trnh v d, cc chng trnh u c gii thch r rng tng dng lnh ng thi cng c a ra kt qu thc thi chng trnh trong h thng. Ngi hc khng nhng ch c m cn phi kim tra kt qu thc thi bng cch lm li cc chng trnh v d c nu trong tng bi hc c th hiu c vai tr ca bi hc trong gio trnh.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

N TT NGHIP

PHN A

LP TRNH USER APPLICATION

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

N TT NGHIP BI 1

CHNG TRNH HELLOWORLD


I. M u: Hello world! l mt chng trnh quan trng v cn bn u tin khi bc vo th gii ca bt k mt ngn ng lp trnh no. Mc d n gin nhng bi ny s cho chng ta lm quen vi cc bc lp trnh, bin dch v thc thi mt chng trnh ng dng trong h thng Linux. Hc bi ny chng ta c dp n li nhng thao tc bin dch chng trnh c hc trong phn lp trnh h thng nhng cn bn. II. Ni dung: 1. Hm printf: a. M t lnh:
int printf ( const char* format, , <parameter_n>, );

b. Gii thch chc nng: Hm printf() dng in mt thng tin cn hin th ra mn hnh u cui. Thng thng nhng thng tin ny l thng bo ca ngi lp trnh v qu trnh x l ca chng trnh ang i n u, c xy ra li hay khng. Hm tr v mt s kiu integer. Nu qu trnh hin th thnh cng, hm tr v mt s dng. Ngc li s tr v s m. Tham s const char* format l nh dng chui thng tin cn hin th. Ty theo chui thng tin cn hin th, th <parameter_n> l mt gi tr thuc dng no . c. V d:
#include <stdio.h> int main() { if ( printf(Characters %d: %c, %c, %c, %c\n, 1, A, 65, B, printf(Display error!\n); } else { printf(Display no error!\n); } } 66) == -1) {

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

N TT NGHIP Kt qu xut ra mn hnh nh sau:


Characters 1: A, A, B, B Display no error!

**Chng ta thy trong cu lnh printf() u tin, ta xut chui Characters ra mn hnh. Chui ny c nh dng hin th ban u l mt s nguyn (%d), tip theo l 4 k t (%c). Mc d cc tham s khng phi lc no cng l nhng k t thun ty, nhng hm printf cng vn hiu l nhng k t-v hm ny dc nh dng phi hiu l mt k t. Ta ghi 65, hm s t ng chuyn s ny thnh k t A trong m ascii. Tng t cho cc tham s khc. Hm thc thi khng c li, v vy in ra cu thng bo
Display no error!.

2. Hm exit: d. M t lnh:
exit (int n);

**Hm cha trong th vin stdlib.h a. Gii thch chc nng: Hm exit(n) dng thot khi mt chng trnh dang thc thi. Thng thng hm ny dng cho trng hp khn cp, ngi lp trnh mun thot khi chng trnh mt cch t ngt khi pht sinh ra mt li no c d on trc. Trong trng hp xy ra li, ngi lp trnh mun bit l li g th s thm vo thng tin cho n. n l mt s nguyn integer do ngi lp trnh nh ngha, cho bit thng tin km theo khi thc hin lnh exit(n); Lnh exit(n) thng t cui chng trnh, gi tr tr v n c gn bng 0, cho bit l chng trnh thc thi khng bi li. b. V d:
#include <stdio.h> #include <stdlib.h> int main() { if ( printf(Characters %d: %c, %c, %c, %c\n, 1, A, 65, B, 66) printf(Display error!\n); exit(1); //Bo li thot l 1 ________________________________________________________________________________CH == -1) {

NG II: LP TRNH NHNG NNG CAO

10

N TT NGHIP
} else { printf(Display no error!\n); }

/*Chng trnh thc thi khng b li, tr v m li l 0*/


exit (0); }

3. Chng trnh helloworld: a. M chng trnh: /*Khai bo th vin chun vo ra-do s dng lnh printf*/
#include <stdio.h> #include <stdlib.h>

/*Chng trnh chnh*/


int main() {

/*In ra chui Hello world!*/


printf (Hello world!);

/*Thot khi chng trnh, tr v m li l 0*/


exit(0); }

b. Bin dch v chy chng trnh: Chp chng trnh hon thnh vo my Linux o; Bin dch chng trnh dng lnh sau:

arm-none-Linux-gnueabi-gcc HelloWorld.c -o HelloWorld

**Lnh ny s dng chng trnh bin dch cho trong chng trnh h tr bin dch cho ARM. ngha ca lnh ny l bin dch mt tp tin chng trnh c tn l HelloWorld.c, kt qu cho ra mt tp tin m my c th chy c trn ARM c tn l HelloWorld. **Ch trc khi s dng lnh ny cn phi khai bo bin mi trng PATH trong Linux, sao cho tr n ni cha cc tp tin thc thi gcc cho ARM. Chp tp tin bin dch HelloWorld vo kit; Tin hnh chy chng trnh bng dng lnh sau:

./HelloWorld

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

11

N TT NGHIP Khi nhn enter d chy chng trnh, h thng Linux s xut hin thng bo li nh sau:
-sh: ./HelloWorld: Permission denied.

Nguyn nhn xy ra li l do tp tin chng trnh HelloWorld va chp qua khng c quyn thc thi trong h thng Linux. sa li ny chng ta cn phi cho php tp tin chng trnh HelloWorld thc thi c bng dng lnh sau:
chmod 777 HelloWorld

Sau tin hnh chy chng trnh, chng trnh chy thnh cng. Lc ny mn hnh hin th chui k t Hello World! c lp trnh trc .
./HelloWorld Hello world!

c. Gii thch chng trnh: y l mt chng trnh n gin, nhim v ca chng trnh l in ra chui Hello
world! ra mn hnh hin th (console).

Phn u ca chng trnh l khai bo hai th vin chun <stdio.h> v


<stdlib.h> dng cho cc hm printf v exit.

Tip theo l khai bo v nh ngha phn chng trnh chnh main(). Hm main() c kiu d liu tr v l int v hm ny khng c tham s. Trong hm int main(), ta s dng hai hm printf v exit. Hm printf (nh ngha trong th vin stdio.h) dng xut mt chui k t c nh dng ra mn hnh. Hm exit(n) (nh ngha trong th vin stdlib.h) dng thot chng trnh chnh v tr v m li l 0. III. Tng kt: Sau bi hc ny chng ta bit cch xy dng cho mnh mt chng trnh ng dng Linux n gin xut k t ra mn hnh hin th. S dng thnh tho hn nhng thao tc bin dch chng trnh. Chng ta cn bit cch cho php mt tp tin trong Linux c quyn thc thi khc phc li permission denied trong h thng Linux. K thut s dng hm printf() rt quan trong trong vic thng bo li trong qu trnh lp trnh ng dng, phc v cho vic g li lp trnh. Chng ta cng bit cch s dng hm
exit(n) trong vic by li chng trnh.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

12

N TT NGHIP Trong bi tip theo, chng ta s i vo tm hiu nhng lnh v tr hon thi gian trong h thng Linux. Cc lnh ny rt quan trng trong qu trnh lp trnh nhng ng dng c lin quan n dnh thi chnh xc v thi gian, hay ni ng hn l nhng cng vic mang tnh chu k.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

13

N TT NGHIP BI 2

TR HON THI GIAN TRONG USER APPLICATION


I. Kin thc ban u: Tr hon thi gian (delay), l mt trong nhng thao tc quan trong nht trong qu trnh lp trnh ng dng giao tip vi cc thit b ngoi vi, lp trnh hot ng mang tnh cht chu k. Trong cc ng dng, chng ta s dng lnh delay lm nhng cng vic nh: nh thi gian cp nht thng tin v ngy-thng-nm hin ti, thng tin v nhit hin ti, hay nh thi gian kim tra tnh trng hot ng ca mt b phn no trong h thng nhm iu khin nhng ng vo ra thch hp. Cc thit b ngoi vi (nh LCD, cc thit b lu tr ( a VCD, a cng, th nh, ) )thng thng c thi gian p ng thp hn rt nhiu ln so vi tc lm vic ca CPU. Nhm mc ch dng b ha hot dng gia CPU v cc thit b ngoi vi, mt trong nhng bin php n gin nht l tr hon hot ng ca CPU, lm cho CPU phi ch cc thit b lm vic xong ri mi tip tc cng vic tip theo. **Trong thc t ngi ta dng bin php khc hiu qu hn rt nhiu. l dng ngt iu khin hot dng ca CPU. Thay v bt CPU phi ch, CPU s tin hnh lm cng vic khc. Khi thit b ngoi vi thc thi xong nhim v n pht sinh ra mt tn hiu bo cho CPU bit CPU nhn thng tin hay ra lnh tip theo cho thit b hot ng. Vn ngt s c trnh by trong nhng phn tip theo ca quyn sch ny. Tr hon thi gian trong h thng Linux khc vi tr hon thi gian thng thng chng ta hiu l trong lc tr hon thi gian, CPU khng lm g c ngoi vic tiu tn thi gian trong vic ch i. Trong h iu hnh Linux ni ring v cc h iu hnh khc ni chung, iu c mt c ch qun l thi gian hot ng ca tng tin trnh v tng tuyn. Ngha l cc tin trnh v tuyn c cho php hot ng song song trong h thng. (**nh ngha tin trnh v tuyn s c trnh by trong nhng bi tip theo). Khi mt tin trnh s dng lnh tr hon thi gian, CPU khng tiu tn thi gian hot ng cho vic ch i, m n s thc hin tin trnh khc, khi thc hin xong tt c nhng tin trnh , n quay tr li tin trnh c c tr hon thi gian v kim tra xem lnh tr hon thi gian c hon thnh hay cha. Nu cha hon thnh, h iu hnh tip
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

14

N TT NGHIP tc thc hin nhng tin trnh khc. Nu hon thnh, h iu hnh s thc hin nhng lnh tip theo trong tin trnh hin ti. Qu trnh chia khe thi gian vn tip tc. Hot ng ca h iu hnh cng tng t khi c nhiu tin trnh s dng hm tr hon thi gian. Trong h iu hnh nhng Linux dng cho Kit KM9260, lnh tr hon thi gian s dng hot dng ca timer dnh thi. Khi mt lnh tr hon thi gian c khi ng, timer s c gn mt gi tr cng vi nhng thng s ci t ph hp sao cho c kh nng tr hon ng bng khong thi gian mong mun. Timer bt u chy, khi t n iu kin nh thi, timer sinh ra mt ngt bo cho CPU bit tin hnh thot khi lnh khi hon hin ti. Bi ny s gii thiu cho chng ta nhng phng php tr hon thi gian c bn thng c s dng trong qu trnh lp trnh ng dng cho mt h thng nhng. Cc u v nhc im khi dng tng phng php ngi lp trnh c th la chn cho mnh phng php hiu qu nht ph hp vi yu cu ng dng. Bn cnh chng ta s c tm hiu cc lnh v Realtime trong h iu hnh Linux. Nhng kin thc ny c vai tr quan trong trong vic thit k ng dng iu khin LCD sau ny v nhng ng dng c lin quan n thi gian thc khc; C hai lp chng ta c th thc hin nhng lnh v thi gian thc, lp driver v user application. y trong phn lp trnh ng dng chng ta ch cp nhng lnh thi gian thc trong lp user application. Cn nhng lnh thi gian thc trong driver s c cp trong phn lp trnh driver ca quyn sch ny. II. Ni dung: 1. Hm sleep: a. C php:
#include <unitstd.h> void sleep (unsigned int seconds);

hay
unsigned int sleep(unsigned int seconds);

b. Gii thch: Hm sleep lm nhim v tr hon mt khong thi gian, c n v l giy. Tr hon y khng phi l tiu tn thi gian lm vic ca CPU trong vic ch i thi gian tr hon kt thc m h iu hnh vn tip tc chia khe cho CPU thc hin nhng cng vic
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

15

N TT NGHIP khc. Ngha l trong lc tr hon, CPU vn lm nhng cng vic khc do h iu hnh phn cng thay v ch ch di ht thi gian. Hm sleep c mt i s v d liu tr v. i s unsigned int seconds l khong thi gian cn tr hon, tnh bng n v giy. Hm sleep tr v gi tri 0 khi thi gian tr hon ht, tr v s giy cn li khi cha kt thc thi gian tr hon. Chng ta c th khng cn s dng d liu tr v ca hm, bng cch dng trng hp th nht void sleep (unsigned int seconds); Hm sleep c dng trong nhng trng hp tr hon thi gian khng i hi tnh chnh xc cao. Thng thng l nhng khong thi gian ln, v n v tr hon nh nht l giy. c. V d: on chng trnh sau s minh ha cho chng ta cch s dng hm sleep().
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { printf (Delay in 10s \n); sleep(10); printf (Delay finished.\n); exit(0); }

Chng trnh ny lm nhim v in ra chui Delay in 10s thng bo rng hm sleep bt u thc thi. Sau khong thi gian tr hon 10s, chng trnh tip tc in ra chui Delay finished. thng bo rng hm sleep chm dt thc thi. Chng ta tin hnh bin dch chng trnh trn np vo kit. Kt qu khi thc thi chng trnh nh sau:
Delay in 10s (Chng trnh tr hon 10s) Delay finished.

2. Hm usleep: a. C php:
#include <unistd.h> void usleep (unsigned long usec); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

16

N TT NGHIP hay
int usleep (usigned long usec);

b. Gii thch: Cng tng t nh hm sleep(), hm usleep cng lm nhim v tr hon mt khong thi gian theo yu cu ca ngi lp trnh. Tuy nhin c mt im khc bit l n v thi gian tr hon tnh bng micr giy. Ngha l phn gii nh hn 1 triu ln. Hm usleep ng dng trong vic tr hon thi gian mt cch chnh xc cao v khng di (nh hn 1 giy). Hm usleep() c hai dng s dng. Mt dng khng c gi tr tr v v mt dng c gi tr tr v. Gi tr tr ca hm usleep l 0 nu hon tt thi gian tr hon, ngc li s tr v thi gian tr hon cn li. i s ca hm usleep l mt s nguyn khng du c ln l 4 bytes (dng unsigned long) chnh l s micr giy cn tr hon. c. V d:
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main() { printf (Delay in 10us \n); usleep(10); printf (Delay finished.\n); exit(0); }

Chng trnh ny lm nhim v in ra chui Delay in 10us thng bo rng hm usleep bt u thc thi. Sau khong thi gian tr hon 10s, chng trnh tip tc in ra chui Delay finished. thng bo rng hm sleep chm dt thc thi. Chng ta tin hnh bin dch chng trnh trn np vo kit. Kt qu khi thc thi chng trnh nh sau:
Delay in 10us (Chng trnh tr hon 10us) Delay finished.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

17

N TT NGHIP Do thi gian tr hon l rt ngn nn chng ta ch thy hai dng ch xut hin cng mt lc. Nu mun nhn thy hai dng ch trn xut hin tun t, chng ta tin hnh thay i thng s nh sau: usleep(1000000); th h thng s tr hon 1s. 3. Hm nanosleep: a. C php:
#include <time.h> int nanosleep (const struct timespec *req, struct timespec *rem);

b. Gii thch: hiu cch s dng ca hm nanosleep trc tin chng ta phi hiu r cu trc
timespec trong th vin <time.h>.

Cu trc struct timespec c Linux nh ngha nh sau:


struct timespec { __kernel_time_t tv_sec; long tv_nsec;

/* seconds */ /* nanoseconds */

}; Cu trc timespec bao gm c hai phn t con, __kernel_time_t tv_sec v


long tv_nsec. timespec l cu trc thi gian trong Linux, bao gm c giy (tv_sec)

v nano giy (tv_nsec) ca giy hin ti. V d to mt khong thi gian l 1000 nano giy, chng ta lm cc bc nh sau: /*nh ngha bin thuc cu trc timespec*/
struct timespec time_delay;

/*Gn gi tr thi gian cn tr hon cho bin*/


time_delay.tv_sec = 0; time_delay.tv_nsec = 1000;

Nh vy thng qua vic gn gi tr cho cc phn t trong cu trc timespec, chng ta to ra c mt khong thi gian nh thi cn thit cho vic s dng hm nanosleep sau y. By gi chng ta s i vo tm hiu cc tham s trong hm nanosleep. Hm
nanosleep c hai tham s cn quan tm. const struct timespec *req l con tr tr

n a ch ca cu trc timespec c nh ngha trc . Theo nh cc bc lm trc th chng ta nh ngha bin time_delay c thi gian nh thi l 1000 nano
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

18

N TT NGHIP giy. a ch ca bin ny s c gn vo i s th nht ca hm nanosleep. i s th hai ca hm nanosleep cng l mt cu trc thi gian timespec trong Linux, struct
timespec *rem. rem cng l mt con tr tr n a ch ca mt bin cu trc timespec

dnh ngha trc . *rem lm nhim v lu gi tr thi gian cn li khi qu trnh tr hon cha kt thc (kt thc b li). Nu khng mun lu gi tr thi gian ny, chng ta c th khng cn s dng tham s struct timespec *rem ca nanosleep bng cch khai bo trong tham s th hai hng s NULL. Hm nanosleep c gi tr tr v kiu
int, tr v gi tr 0 nu qu trnh tr hon khng c li. Ngc li, tr v gi tr -1. Trong

trng hp ny, gi tr thi gian cn li s c lu vo trong bin con tr *rem nu khai bo trong i s th hai. Ngi lp trnh c th s dng gi tr ny gi mt hm tr hon khc, tr hon phn cn li cha hon thnh. Hm nanosleep c mt u im l thi gian tr hon c phn gii cao hn rt nhiu so vi hm sleep v usleep. Hm nanosleep s dng trong nhng ng dng i hi tr hon vi chnh xc rt cao (tnh bng mt phn t ca giy). c. V d: on chng trnh sau s gip cho chng ta bit cch s dng hm nanosleep.
#include <stdio.h> #include <stdlib.h> #include <time.h> int main() {

/*Khai bo cu trc thi gian dng lu tr gi tr khong thi gian cn tr hon*/


struct timespec rq, rm;

/*Ci t khong thi gian cn tr hon*/


rq.tv_sec = 0; rq.tv_nsec = 1000;

/*In thng bo qu trnh tr hon bt u*/


printf (Delay has just begun \n);

/*Gi hm nanosleep tr hon mt khong thi gian ci t*/


nanosleep (&rq, &rm);

/*In thng bo qu trnh tr hon kt thc*/


printf (Delay has just finished. \n); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

19

N TT NGHIP /*Kt thc chng trnh*/


exit (0); }

Nh vy s dng c hm nanosleep chng ta phi lm theo nhng bc sau: Khai bo bin struct timespec lu gi tr khong thi gian cn tr hon, v bin struct timespec cha gi tr tr v ca hm nanosleep;
struct timespec rq, rm;

Gn gi tr thi gian cn tr hon;

rq.tv_sec = 0; rq.tv_nsec = 1000;

Gi hm nanosleep; Gn a ch ca bin vo cc con tr tham s ca hm;

nanosleep (&rq, &rm);

Bin dch v chy chng trnh trn kit, mn hnh hin th kt qu nh sau:
Delay has just begun

(Chng trnh tr hon 1000ns)


Delay finished.

Do thi gian tr hon rt nh nn hai chui thng tin xut hin gn nh dng thi. C th tng thi gian tr hon bng cch thay i thng s ca tv_sec v tv_nsec, chng hn nh:
req.tv_sec = 1; req.tv_nsec = 0;

th thi gian tr hon s tng ln 1s, lc ny chng ta c th thy 2 dng thng tin xut hin tun t. 4. Hm alarm: a. C php:
#include <unistd.h> unsigned int alarm (unsigned int seconds);

b. Gii thch: Hm alarm() to mt tn hiu c tn l SIGALRM sau mt khong thi gian l


seconds giy, c quy nh bi ngi lp trnh. Nu gi tr seconds bng 0 th hm alarm b v hiu ha. ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

20

N TT NGHIP Hm alarm thng c dng kt hp vi hm x l tn hiu ngt, hm ny lm nhim v thc hin nhng cng vic do ngi lp trnh nh ngha khi tn hiu ngt xy ra. Thng thng chng ta s dng hm sigaction() hay signal() thc hin nhim v trn. c. V d: on chng trnh sau dy s cho chng ta bit cch to mt khong thi gian nh thi cho tn hiu SIGALRM tc ng:
alarm (30); /*Sau mt khong thi gian l 30s, th tn hiu SIGALRM s tc

ng tch cc, cng vic ca chng ta l xy dng mt hm thc thi khi c tn hiu tc ng*/ /*Sau khi tn hiu SIGALRM tc ng th cn phi to li nh thi cho tn hiu ny bng cch gi li hm SIGALRM*/ Hm alarm() dng nh thi to ra mt tn hiu ngt. Thng thng hm ny khng dng nh mt hm ring bit m n phi kt hp vi nhng hm khc. l nhng hm x l tn hiu ngt. 5. Kin thc cn bn v ng h thi gian thc trong h thng Linux: Thi gian thc trong h iu hnh mang mt ngha rt rng. Trong phn ny chng ta ni n thi gian thc vi ng l ng h thi gian thc trong h thng Linux. Trong phn ny chng ta s nghin cu nhng lnh truy xut nhng thng tin v thi gian trong h thng (bao gm ngy, thng, nm, gi, pht, giy, ); Nhng hm truy xut v thi gian c nh ngha trong th vin <time.h>. Cc hm trong th vin <time.h> bao gm: thi; o o o o difftime: Tr v khong cch thi gian gia hai thi im; time: Tr v thi gian hin ti ca h thng; asctime: chuyn i kiu cu trc thi gian tm thnh chui thi gian; ctime: chuyn i kiu d liu thi gian time_t thnh chui thi gian; 21 Hm thao tc vi thi gian thc; o clock: Tr v khong thi gian (n v l ticks) k t khi chng trnh thc

Hm chuyn i thi gian:

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

N TT NGHIP o o time_t; o o localtime: Chuyn i loi d liu thi gian time_t thnh cu trc thi gian strftime: Chuyn cu trc thi gian struct tm thnh chui theo nh dng tm theo thi gian cc b; ca ngi dng; Cc hng s xy dng sn bao gm: o o o o o o 5.1. 5.1.1. CLOCKS_PER_SEC: l khong thi gian 1s tnh bng n v ticks; NULL: Con tr rng; clock_t: Loi d liu thi gian dng xung ticks; size_t; time_t: kiu d liu thi gian; struct tm: cu trc thi gian; Cc loi d liu thi gian chun: clock_t:
clock_t;

gmtime: chuyn i kiu d liu thi gian time_t thnh cu trc thi gian mktime: Chuyn i cu trc thi gian tm thnh loi d liu thi gian

tm theo gi UTC;

Cc loi d liu thi gian chun:

Chng ta s i su tm hiu tng ni dung lit k trn y:

Theo th vin <time.h> th clock_t c nh ngha nh sau:


typedef __kernel_clock_t

/*Trong th vin <types.h>*/ M __kernel_clock_t c nh ngha:


typedef long __kernel_clock_t;

/*Trong th vin <posix_types.h>*/ Nh vy, clock_t thc cht l mt kiu s nguyn long. Nhim v ca bin ny l lu nhng gi tr khong thi gian (tnh bng ticks) do cc hm thao tc trn thi gian tr v. 5.1.2. size_t: Theo th vin <time.h> th size_t c nh ngha nh sau:
typedef __kernel_size_t size_t; ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

22

N TT NGHIP /*Trong th vin <types.h>*/ m __kernel_size_t c nh ngha:


typedef unsigned long __kernel_size_t;

/*Trong th vin <posix_types.h>*/ Nh vy, size_t thc cht l mt kiu s nguyn unsigned long. Nhim v ca bin ny l lu nhng gi tr kch tht ca mt bin no , do hm sizeof, maxsize, tr v. 5.1.3. time_t:

Kiu d liu time_t c nh ngha trong th vin <time.h> nh sau:


typedef __kernel_time_t time_t;

/*Trong th vin <types.h>*/ m __kernel_time_t c nh ngha:


typedef long __kernel_time_t;

/*Trong th vin <posix_types.h>*/ Nh vy, size_t thc cht l mt kiu s nguyn long. Nhim v ca loi bin ny l lu gi tr thi gian c tr v bi cc hm v thi gian nh time, difftime,

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

23

N TT NGHIP

5.1.4.

struct tm:

Trong th vin <time.h> struct tm c nh ngha nh sau:


struct tm {

/* * S giy trong mt pht * gi tr nm trong khong t 0 n 59 */


int tm_sec;

/* S pht trong mt gi, c gi tr t 0 n 59*/


int tm_min;

/* S gi trong mt ngy c gi tr t 0 n 23 */
int tm_hour;

/* S ngy trong mt thng, gi tr trong khong 0 n 31 */


int tm_mday;

/* S thng trong mt nm, gi tr nm trong khong 0 n 11 */


int tm_mon;

/* S nm k t nm 1900 */
long tm_year;

/* S ngy trong tun, c gi tr t 0 n 6 */


int tm_wday;

/* S ngy trong mt nm, tnh t ngy 1 thng 1, c gi tr t 0 n 365 */


int tm_yday; };

Chng ta thy cu trc struct tm l mt cu trc xy dng sn vi tt c nhng thng tin lin quan n thi gian thc: Nm, thng, ngy, gi, pht, giy, ngy trong tun, Cu trc ny dng lm kiu d liu tr v cho cc hm thao tc vi thi gian. Chng ta s nghin cu ngay trong phn sau ca chng. 5.2. 5.2.1. Cc hng s xy dng sn trong <time.h>: CLOCKS_PER_SEC:

y l mt hng s c nh ngha sn quy nh s ticks trong mt giy. Nh vy trong mt giy s c CLOCKS_PER_SEC ticks. Chng ta dng hng s ny quy i
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

24

N TT NGHIP ra giy gi tr tr v ca hm clock(). Hay dng lm hng s qui i ra giy ca tham s ca mt s hm tr hon thi gian tnh bng ticks. 5.2.2. NULL:

NULL l mt hng s quy nh mt con tr rng, hay ni cch khc con tr ny khng tr n bt k mt i tng no c. Hng s ny s dng trong nhng trng hp khi mun v hiu ha mt tham s no ca hm (khi khng mun s dng mt tham s ca hm no ). **Trn y chng ta tm hiu nhng loi d liu, hng s quan trng ca thi gian thc trong Linux. Sau y l nhng hm s dng nhng loi d liu ny. Mi hm chng ta s c mt v d minh ha cch s dng, cc bn cn phi c hiu v bin dch chy trn h thng Linux nhm nm vng thm nguyn l hot ng ca chng. T , s c th ng dng nhng hm ny trong nhng ng dng khc lin quan n thi gian thc. 5.3. 5.3.1. Cc hm thao tc vi thi gian thc: clock: a. C php:
#include <time.h> clock_t clock (void);

b. Gii thch: Hm clock c kiu d liu tr v l clock_t v khng c tham s. Nhim v ca hm clock l tr v khong thi gian tnh t khi chng trnh cha hm clock thc thi cho n khi hm clock c gi. Chng trnh v d sau s cho chng ta bit r cch s dng hm ny hn. c. Chng trnh v d: Mc ch ca chng trnh ny l to ra mt chng trnh tr hon. Thi gian tr hon tnh bng giy do ngi lp trnh quy nh. /*chng trnh tr hon thi gian ng dng hm clock*/ /*Khai bo th vin dng cho hm printf*/
#include <stdio.h>

/*Khai bo th vin dng cho cc hm thi gian*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

25

N TT NGHIP
#include <time.h>

/*To hm wait tr hon thi gian. Hm ny c tham s l seconds giy cn tr hon, khng c gi tr tr v */
void wait (int seconds) {

/*Khai bo bin loi clock_t lu d liu kiu ticks*/


clock_t endwait;

/*Chn khong thi gian kt thc l thi gian hin ti, cng vi khong thi gian l mt giy*seconds*/
endwait = clock () + seconds * CLOCKS_PER_SEC;

/*Ch cho n khi thi gian hin ti ln hn thi gian kt thc th thot*/
while (clock () < endwait) {} }

/*Chng trnh chnh ng dng hm wait(seconds)*/


int main () {

/*Khai bo bin int n lu gi tr m xung*/


int n;

/*In cu thng bo bt u m xung*/


printf (Starting countdown\n);

/*Vng lp for m xung*/


for (n = 10; n>0; n--) {

/*In gi tr hin ti ca n theo di*/


printf(%d\n,n);

/*Gi hm wait c lp trnh trc tr hon mt khong thi gian l 1 giy*/


wait(1); }

/*Sau khi thot khi vng lp, in ra cu thng bo kt thc*/


printf(FIRE!!!\n);

/*Tr v gi tr 0 cho hm main, thng bo l khng c li xy ra*/


return 0; }

ngha tng dng lnh c gii thch rt k trong chng trnh. Chng ta tin hnh bin dch v sao chp vo kt. Sau khi tin hnh thc thi chng trnh chng ta s c kt qu nh sau:
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

26

N TT NGHIP
./Time_0 Starting countdown... 10 9 8 7 6 5 4 3 2 1 FIRE!!!

Nh vy chng ta thc hin thnh cng chng trnh tr hon thi gian s dng hm clock ly thi gian hin ti tnh t lc chng trnh thc thi v s dng hng s CLOCKS_PER_SEC. Tuy nhin mc ch ca chng trnh trn khng phi l to ra mt cch tr hon thi gian khc m ch gip chng ta hiu r cch s dng hm clock. Thc ra, tr hon thi gian theo cch ny khng hiu qu cho nhng ng dng ln, v tiu tn thi gian hot ng ca CPU v ch. 5.3.2. difftime: a. C php:
#Include <time.h> double difftime (time_t time2, time_t time1);

b. Gii thch: Hm difftime c hai i s kiu time_t. i s th nht time_t time2 l thi im ban u, i s th hai time_t time1 l thi im lc sau. Hm difftime c kiu d liu tr v l s thc dng double l chnh lch thi gian tnh bng giy gia hai thi im time2 v time1. c. Chng trnh v d: Chng trnh ny lm nhim v tnh ton thi gian nhp d liu ca ngi dng, s dng hm difftime tm s chnh lch thi gian gia hai ln cp nht (trc v sau khi nhp d liu).
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

27

N TT NGHIP /*chng trnh v d hm difftime*/ /*Khai bo th vin dng cho hm printf v hm gets*/
#include <stdio.h>

/*Khai bo th vin dng cho cc hm v thi gian*/


#include <time.h>

/*Chng trnh chnh*/


int main (void) {

/*Khai bo bin start: lu thi im ban u, end: lu thi im lc sau thuc kiu d liu time_t*/
time_t start, end;

/*Khai bo bin lu tn ngi dng nhp vo, cha ti a 256 k t*/


char szInput [256];

/*Khai bo bin s thc lu gi tr khong thi gian khc bit ca hai thi im start v end*/ /*Cp nht thi gian hin ti, trc khi ngi dng nhp thng tin. S dng hm time(), l hm tr v thi gian hin ti ca h thng, kiu d liu tr v l con tr time_t*/
time (&start);

/*In ra thng bo yu cu ngi s dng nhp thng tin cho h thng.*/


printf (Please, enter your name: );

/*Yu cu nhp vo bin mng szInput*/


gets(szInput);

/*Cp nht thi gian hin ti, sau khi ngi dng nhp thng tin. S dung hm time(time_t *time_val) ly thi gian hin ti*/
time(&end);

/*S dng hm difftime d tnh thi gian chnh lch gia start v end*/
dif = difftime (end,start);

/*In ra thng bo nhn c thng tin ngi dng*/


printf (Hi %s. \n, szInput);

/*In ra thng bo khong thi gian tiu tn khi i nhp d liu*/


printf (It took you %.21f seconds to type your name. \n, dif);

/*Tr v 0 cho hm main bo rng qu trnh thc thi khng b li.*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

28

N TT NGHIP
return 0; }

Tin hnh bin dch v chy chng trnh trn kit, chng ta c kt qu nh sau:
./time_difftime_linux Please, enter your name: Nguyen Tan Nhu Hi Nguyen Tan Nhu. It took you 5.00 seconds to type your name.

Trc khi gi hm gets(), chng ta gi hm time() d ly v thi gian hin ti ca h thng, sau khi ngi s dng nhp xong d liu, ta li gi hm time() cp nht thi gian lc sau. Tip n gi hm difftime ly v khong thi gian sai bit gia hai thi im. Phn sau chng ta s gii thch r hn hot ng ca hm time trong h thng linux. 5.3.3. time: a. C php:
#include <time.h> time_t time(time_t* timer);

b. Gii thch: Hm time dng ly v thi gian hin ti ca h thng linux. Hm time c i s
time_t* time l con tr lu gi tr tr v ca hm. i s ny c th b trng bng cch

in hng NULL lc ny thi gian hin ti s l gi tr tr v ca hm. c. Chng trnh v d: Chng trnh v d sau y s cho chng ta hiu r cch s dng hm time (Chng ta c th tham kho v d trn xem cch s dng hm time). Chng trnh ny s in ra s gi ca h thng k t ngy 1 thng 1 nm 1970. /*Chng trnh v d hm time*/ /*Khai bo cc th vin cn thit cho cc hm s dng trong chng trnh*/
#include <stdio.h> #include <time.h>

/*Bt u chng trnh chnh*/


int main () {

/*Khai bo bin time_t seconds lm gi tr tr v cho hm time*/


time_t seconds; ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

29

N TT NGHIP /*S dng hm time ly v thi gian hin ti ca h thng, l s giy k t ngy 1 thng 1 nm 1970*/
seconds = time (NULL);

/*In ra thi gian hin ti*/


printf (%ld hours since January 1st, 1970\n, seconds/3600);

/*Tr v gi tr 0 cho hm main, thng bo qu trnh thc thi khng c li*/


return 0; }

Bin dch v thc thi chng trnh trn kit, chng ta c kt qu nh sau:
./time_time_linux 366958 hours since January 1, 1970

Nh vy hm time lm nhim v tr v thi gian hin ti ca h thng tnh bng giy k t ngy 1 thng 1 nm 1970. Chng ta c th chuyn thnh dng ngy thng nm, gi pht giy bng cch s dng hm gmtime hay localtime. 5.4. 5.4.1. Cc hm chuyn i thi gian thc: asctime:

a. C php:
#include <time.h> char* asctime (const struct tm * timeptr);

b. Gii thch: Hm asctime c chc nng bin i cu trc thi gian dng struct tm thnh chui thi gian c dng Www Mmm dd hh:mm:ss yyyy. Trong Www l ngy trong tun, Mmm l thng trong nm, dd l ngay trong thng, hh:mm:ss l gi:pht:giy trong ngy, cui cng yyyy l nm. Chui thi gian c kt thc bng 2 k t c bit: k t xung dng \n v k t NULL. Hm c tham s l con tr cu trc struct tm * timeptr, gi tr tr v l con tr k t char * V d sau y s cho chng ta hiu r cch s dng hm asctime. c. Chng trnh v d: Nhim v ca on chng trnh ny l in ra chui thi gian tr v ca hm asctime. /*Chng trnh v d hm asctime*/
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

30

N TT NGHIP /*Khai bo cc th vin cho cc hm dng trong chng trnh*/


#inlcude <stdio.h> #include <time.h>

/*Chng trnh chnh*/


int main () {

/*Khai bo bin time_t rawtime lu thi gian hin ti ca h thng*/


time_t rawtime;

/*Khai bo bin con tr cu trc struct tm lu thi gian*/


struct tm * timeinfo;

/*c v thi gian hin ti ca h thng*/


time ( &rawtime );

/*Chuyn i kiu thi gian time_t thnh cu trc thi gian struct tm*/
timeinfo = localtime ( &rawtime );

/*In thi gian h thng di dng chui*/


printf (The curent date/time is: %s, asctime (timeinfo) );

/*Tr v gi tr 0 cho hm main thng bo khng c li xy ra trong qu trnh thc thi lnh*/
return 0; }

Sau khi bin dch v chy chng trnh trn kit, chng ta c kt qu sau:
./time_asctime_linux The current date/time is: Sat Nov 12 06:04:50 2011

Hm asctime thng dng trong nhng trng hp cn bin mt cu trc thi gian thnh chui k t ascii phc v cho vic hin th trn cc thit b u cui, hay trong cc tp tin cn qun l v thi gian. 5.4.2. ctime: a. C php:
#include <time.h> char * ctime ( const time_t * timer );

b. Gii thch: Hm ctime lm nhim v chuyn thng tin v thi gian dng time_t thnh thng tin v thi gian dng chui k t m ascii. Chui thng tin thi gian ny c dng Www

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

31

N TT NGHIP Mmm dd hh:mm:ss yyyy. Trong Www l ngy trong tun, Mmm l thng trong nm, dd l ngay trong thng, hh:mm:ss l gi:pht:giy trong ngy, cui cng yyyy l nm. Chui thi gian c kt thc bng 2 k t c bit: k t xung dng \n v k t NULL. Hm ctime c tham s l con tr bin thi gian dng time_t * timer, gi tr tr v ca hm l con tr k t char * Chng trnh v d sau y s cho chng ta hiu r cch s dng hm ctime. c. Chng trnh v d: Tng t nh chng trnh v d trn, chng trnh ny cng ly thi gian hin ti ca h thng chuyn sang chui thng tin v thi gian cui cng in ra mn hnh hin th. Nhng ln ny chng ta s dng hm ctime. /*Chng trnh v d hm ctime*/ /*Khai bo cc th vin cn thit cho cc hm s dng trong chng trnh*/
#include <stdio.h> #include <time.h>

/*Chng trnh chnh*/


int main () {

/*Khai bo bin kiu thi gian time_t lu thi gian hin ti ca h thng*/
time_t rawtime;

/*c v gi tr thi gian hin ti ca h thng*/


time ( &rawtime );

/*In chui thng tin thi gian ra mn hnh*/


printf ( The current local time is: %s, ctime (&rawtime) );

/*Tr v gi tr 0 cho hm main, thng bo rng qu rnh thc thi lnh khng c li*/
return 0; }

Bin dch v chy chng trnh trn kit, chng ta c kt qu nh sau:


./time_ctime_linux The current local time is: Sat Nov 12 07:03:28 2011

Kt qu hin th cng tng t nh hm asctime. Nhng hm ctime c nhiu u im hn hm asctime. Chng ta khng cn phi chuyn thng tin thi gian dng time_t
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

32

N TT NGHIP thng dng struct tm ri thc hin chuyn i sang thng tin thi gian dng chui. Hm ctime s chuyn trc tip time_t thnh chui thi gian. 5.4.3. gmtime: a. C php:
#include <time.h> struct tm * gmtime ( const time_t * timer);

b. Gii thch: Hm gmtime lm nhim v chuyn i kiu thi gian dng time_t thnh cu trc thi gian struct tm phc v cho cc hm thao tc vi thi gian thc khc. Hm c tham s l con tr thi gian kiu time_t. D liu tr v l con tr cu trc thi gian dng struct tm. c. Chng trnh v d: Nhim v ca chng trnh v d ny l in ra gi tr thi gian gia cc mui gi khc nhau, s dng hm gmtime tr v cu trc thi gian struct tm. /*Chng trnh v d s dng hm gmtime*/ /*Khai bo cc th vin cn thit cho cc hm s dng trong chng trnh*/
#include <sdtio.h> #include <time.h>

/*Khai bo cc hng s dng trong qu trnh lp trnh*/


#define MST (-7) #define UTC (0) #define CCT (+8)

/*Chng trnh chnh*/


int main () {

/*Khai bo bin time_t lu thi gian hin ti ca h thng*/


time_t rawtime;

/*Khai bo bin con trstruct tm cha d liu tr v sau khi chuyn i */


struct tm * ptm;

/*Cp nht gi tr thi gian hin ti*/


time (&rawtime);

/*Chuyn sang cu trc thi gian tm*/


ptm = gmtime ( &rawtime );

/*In cc gi tr thi gian ra mn hnh*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

33

N TT NGHIP
puts (Current time arround the world); printf (Phoenix, AZ (U.S.): %2d:%2d\n, (ptm->tm_hour+MST)%24, ptm->tm_min); printf (Reykjavik (Iceland): %2d:%2d\n, (ptm->tm_hour+UTC)%24, ptm->tm_min); printf (Beijing (China), AZ (U.S.): %2d:%2d\n, (ptm>tm_hour+CCT)%24, ptm->tm_min);

/*Tr v gi tr 0 cho hm main*/


return 0; }

Bin dch v chy chng trnh trn kit, ta c kt qu sau:


./time_gmtime_linux Current time around the World: Phoenix, AZ (U.S.) : Reykjavik (Iceland) : Beijing (China) : -5:20 2:20 10:20

5.4.4.

mktime:

a. C php:
#include <time.h> time_t mktime ( struct tm * timeptr );

b. Gii thch: Nhim v ca hm mktime l chuyn thng tin thi gian dng cu trc struct tm thnh thng tin thi gian dng time_t; Bn cnh nhng thng tin c lin quan trong cu trc struct tm cha c cp nht cng s c thay i ph hp vi ngy thng nm thay i. C th nh th no s c trnh by trong v d s dng hm mktime. Hm mktime c tham s l con tr cu trc struct tm * l thi gian mun chuyn i. Gi tr tr v l thi gian dng time_t. Sau y l v d v cch s dng hm mktime. c. Chng trnh v d: Nhim v ca chng trnh v d ny, ngi s dng s nhp thng tin v ngy thng nm, chng trnh s cho bit ngy l th my. /*Chng trnh v d hm mktime*/ /*Khai bo cc th vin cho cc hm s dng trong chng trnh*/
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

34

N TT NGHIP
#include <stdio.h> #include <time.h>

/*Chng trnh chnh*/


int main () {

/*Khai bo bin kiu time_t lu thng tin thi gian*/


time_t rawtime;

/*Khai bo bin cu trc lu cu trc thi gian cn chuyn i*/


struct tm * timeinfo;

/*Khai bo bin lu cc ngy trong tun*/


char * weekday[] = { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday);

/*Khai bo cc s nguyn lu thng tin nhp t ngi dng*/


int year, month, day;

/*Yu cu nhp thng tin t ngi dng*/


printf (Enter year: ); scanf (%d,&year); printf (Enter month: ); scanf (%d,&month); printf (Enter day: ); scanf (%d,&day);

/*Cp nht thi gian hin ti*/


time (&rawtime );

/*Chuyn thnh cu trc thi gian*/


timeinfo = localtime ( &rawtime );

/*Cp nht thi gian do ngi dng nh ngha*/


timeinfo->tm_year = year 1900; timeinfo->tm_mon = month 1; timeinfo->tm_mday = day;

/*Khi gi hm mktime th nhng thng tin cn li nh tm_wday s c h thng t ng cp nht*/


mktime ( timeinfo ); printf ( That day is a %s. \n, weekday[timeinfo->wday]);

/*Tr v gi tr 0 cho hm main, thng bo khng c li xy ra trong qu trnh thc thi lnh*/
return 0; }

Khi bin dch v chy chng trnh, chng ta s c kt qu nh sau:


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

35

N TT NGHIP
./time_mktime Enter year: 2011 Enter month: 11 Enter day: 17 That day is a Thursday.

5.4.5.

localtime:

a. C php:
#include <time.h> struct tm * localtime ( const time_t * timer );

b. Gii thch: Hm localtime dng chuyn i thng tin thi gian dng time_t thnh thng tin thi gian dng struct tm. Hm localtime c tham s l con tr n bin thi gian const time_t timer cn chuyn i. Gi tr tr v ca hm l con tr cu trc struct tm *. c. Chng trnh v d: Sau y l chng trnh v d s dng hm localtime. Chng trnh ny s cp nht thi gian hin ti dng time_t, chuyn sang cu trc struct tm, cui cng in ra man hnh di dng chui thi gian bng hm asctime. /*Chng trnh v d hm localtime*/ /*Khai bo cc th vin cho cc hm s dng trong chng trnh*/
#include <stdio.h> #include <time.h>

/*chng trnh chnh*/


int main () {

/*Khai bo bin thi gian dng time_t lu thi gian hin ti*/
time_t rawtime;

/*Khai bo con tr cu trc thi gian struct tm lu thng tin thi gian sau khi chuyn i*/
struct tm * timeinfo;

/*Cp nht thng tin thi gian hin ti*/


time ( &rawtime); timeinfo = localtime ( &rawtime ); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

36

N TT NGHIP /*Chuyn i cu trc thi gian thnh chui sau in ra mn hnh*/


printf (Current local time and date: %s, asctime ( timeinfo ));

/*Tr v gi tr 0, thng bo qu trnh thc thi lnh khng b li*/


return 0; }

Sau khi bin dch v thc thi chng trnh, chng ta c kt qu sau:
./time_localtime_linux Current local time and date: Thu Nov 17 11:54:42 2011

5.4.6.

strftime:

a. C php:
#include <time.h> size_t strftime ( char * ptr, size_t maxsize, const char * format, const struct tm * timeptr );

b. Gii thch: Hm strftime lm nhim v chuyn thng tin thi gian dng cu trc struct tm thnh thng tin thi gian dng chui c nh dng do ngi lp trnh nh ngha. Hm strftime c 4 tham s: char * ptr, l con tr k t dng lu chui thng tin thi gian tr v ca hm sau khi nh dng; size_t maxsize, l kch tht ti a ca chui thng tin thi gian tr v; const char * format, l nh dng chui thng tin thi gian mong mun (tng t nh phn nh dng thng tin xut ra trong hm printf); cui cng, const struct tm * timeptr, l con tr cu trc ngun cn chuyn i. Cc nh dng c quy nh trong bng sau: K hiu
%a %A %b %B %c %d %H %I

c thay th bng Tn vit tt ca ngy trong tun; Tn y ca ngy trong tun; Tn vit tt ca thng; Tn y ca thng; Chui ngy gi chun Ngy ca thng (01-31) Gi trong ngy (00-23) Gi trong ngy (01-12)

V d
Mon Monday Aug August Thu Aug 07:55:02 17 23 12

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

37

N TT NGHIP
%j %m %M %p %S %U %w %W

Ngy trong nm (001-366) Thng trong nm (01-12) Pht trong gi (00-59) AM hoc PM Giy trong pht (00-61) S tun trong nm (00-53) vi Cha nht l ngy u tin trong tun; S ngy trong tun (0-6), Cha nht: 0 S tun trong nm (00-53) vi th Hai l ngy u tin trong tun; Chui ngy thng nm (dd/mm/yy) Chui gi pht giy (HH:MM:SS) Hai s cui ca nm S Nm hon chnh Tn mi gi K t c bit
1

245 08 45 AM 02 34 4 34 18/11/1 07:32:3 4 11 2011 CDT %

%x %X %y %Y %Z %%

Hm strftime c gi tr tr v l mt s kiu size_t. Bng 0 nu qu trnh chuyn i xy ra li (do kch tht quy nh khng ,). Bng mt s dng kch tht chui k t chp vo con tr char * ptr nu qu trnh chuyn i thnh cng; Chng trnh v d sau s gip cho chng ta hiu r cch s dng hm strftime. c. Chng trnh v d: Chng trnh v d ny c nhim v in ra chui thng tin v gi pht giy hin ti theo dng 12H, c thm AM v PM pha sau. /*Chng trnh v d hm strftime*/ /*Khai bo cc th vin cho cc hm s dng trong chng trnh*/
#include <stdio.h> #include <time.h>

/*Chng trnh chnh*/


int main () { ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

38

N TT NGHIP /*Khai bo bin kiu time_t lu thi gian hin ti ca h thng*/


time_t rawtime;

/*Khai bo con tr cu trc thi gian lm tham s cho hm strftime*/


struct tm * timeinfo;

/*Khai bo vng nh c kch tht 80 k t lu chui thng tin thi gian*/


char buffer [80];

/*c thi gian hin ti ca h thng*/


time (&rawtime);

/*Chuyn thng tin thi gian dng time_t thnh thng tin thi gian dng cu trc struct tm, theo thi gian cc b*/
timeinfo = localtime ( &rawtime );

/*Thc hin chuyn i cu trc thi gian struct tm thnh chui thi gian theo nh dng ngi dng*/
strftime (buffer, 80, Now its %I:%M%p., timeinfo);

/*Tr v gi tr 0 thng bo qu trnh thc thi lnh khng xy ra li*/


return 0; }

Bin dch v chy chng trnh chng ta c kt qu sau:


./time_strftime Now it's 08:02AM.

Nh vy n y chng ta c th to ra mt chui thng tin v thi gian vi nh dng linh ng, ph hp vi mc ch ngi dng, thay v s dng dnh dng c sn ca nhng hm chuyn i thi gian khc. III. Tng kt: Tr hon thi gian l mt trong nhng vn quan trng trong lp trnh ng dng iu khin cc thit b ngoi vi. Trong chng ny chng ta tm hiu nhng lnh cn bn nt v tr hon thi gian. Ty theo tng ng dng c th, ngi lp trnh s chn cho mnh cch tr hon thi gian thch hp sao cho khng lm nh hng nhiu n tnh thi gian thc ca chng trnh. Chng ta cng tm hiu lnh alarm to lp nh thi cho tn hiu SIGALRM, nhng lnh thao tc vi thi gian thc trong h thng linux c nh ngha trong th vin time.h.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

39

N TT NGHIP Trong bi sau, chng ta s bc vo nhng vn l th ca h iu hnh Linux ni ring v cc h iu hnh thi gian thc khc ni chung, l cc hm thao tc vi tin trnh v tuyn phc v cho vic thit k cc h thng thi gian thc mt cch d dng hn.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

40

N TT NGHIP BI 3

LP TRNH A TIN TRNH TRONG USER APPLICATION


I. Kin thc ban u: a. nh ngha tin trnh trong Linux: Trong hu ht cc h iu hnh a nhim ta UNIX nh Linux, th kh nng x l ng thi nhiu tin trnh l mt trong nhng c im quan trng. Nh vy tin trnh c nh ngha nh th no trong h thng Linux. Gi s khi chng ta thc hin cu lnh ls l th Linux s tin hnh lit k tt c nhng thng tin v tp tin v th mc c trong th mc hin hnh. Nh vy h iu hnh Linux thc hin mt tin trnh.Cng mt lc hai ngi s dng lnh ls l (chng hn mt ngi ng nhp trc tip v mt ngi ng nhp qua mng) h iu hnh cng s p tt c nhng yu cn trn. Nh vy ta ni rng h iu hnh thc hin song song hai tin trnh. Thm ch ngay c mt chng trnh, cng c th c nhiu tin trnh cng mt lc xy ra. V d nh chng trnh ghi d liu vo a CD, c rt nhiu tin trnh xy ra cng mt lc, mt tin trnh lm nhim v chp ni dung d liu t a cng sang a CD v mt tin trnh tnh ton thi gian cn li hon thnh cng vic hin th trn thanh trng thi Tin trnh v chng trnh l hai nh ngha hon ton khc nhau, nhiu khi cng c th coi l mt. Khi chng trnh c duy nht mt tin trnh x l th lc tin trnh v chng trnh l mt. Nhng khi c nhiu tin trnh cng thc hin hon thnh mt chng trnh th lc tin trnh ch l mt phn ca chng trnh. Mi mt tin trnh trong Linux iu c gn cho mt con s c trng duy nht. S ny gi l nh danh ca tin trnh, PID (Process Identification Number). PID dng phn bit gia cc tin trnh cng tn ti song song trong h thng. Mi mt tin trnh c cp pht mt vng nh lu tr nhng thng tin cn thit c lin quan n tin trnh. Cc tin trnh c iu phi xoay vng thc hin bi h thng phn phi thi gian ca h iu hnh. Cc tin trnh c trao i thng tin vi nhau thng qua c ch giao tip gia cc tin trnh (IPC-Inter Process Communication). Cc c ch giao tip gia cc tin trnh bao gm nhng k thut nh ng ng, socket, message, chuyn hng xut nhp,

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

41

N TT NGHIP hay pht sinh tn hiu (Chng ta s i su tm hiu nhng k thut ny trong nhng bi sau). Nh vy, tin trnh c hiu l mt thc th iu khin on m lnh c ring mt khng gian a ch vng nh, c ngn xp ring l, c bng ch cc s m t tp tin c m cng tin trnh v c bit l c mt nh danh PID (Process Identify) duy nht trong ton b h thng vo thi im tin trnh ang chy. (Theo nh ngha trong sch lp trnh Linux ca nh xut bn Minh Khai) b. Cu trc tin trnh: Phn trn chng ta khi qut c nhng kin thc cn bn nht trong mt tin trnh. Trong phn ny chng ta s i su vo tm hin cu trc ca tin trnh, cch xem thng tin ca cc tin trnh ang chy trong h thng Linux v ngha ca nhng thng tin . Nh inh ngha trong phn trn mi tin trnh c cp pht mt vng nh ring lu nhng thng s cn thit. Nhng thng tin l g? PID Code Data Library FileDes Thng tin u tin l PID (Process Identify). Thng tin ny l s nh danh cho mi tin trnh. Mi tin trnh dang chy trong h thng iu c mt nh danh ring bit khng trng lp vi bt k tin trnh no. S PID c h iu hnh cung cp mt cch t ng. PID l mt s nguyn dng t 2 n 32768. Ring tin trnh init l tin trnh qun l v to ra mi tin trnh con khc c h iu hnh gn cho PID l 1. l nguyn nhn ti sao PID ca cc tin trnh l mt s nguyn dng bt u t 2 n 32768. Thng tin th hai l Code. Code l vng nh cha tp tin chng trnh thc thi cha trong a cng c h iu hnh np vo vng nh (c th y l RAM). V d khi chng ta nh lnh ls l th h iu hnh s chp m lnh thc thi ca lnh ls trong th muc bin ca Root File System vo RAM ni ni ng hn l chp vo vng nh ________________________________________________________________________________CH NG II: LP TRNH NHNG NNG CAO 42

N TT NGHIP Code ca tin trnh. T h iu hnh s chia khe thi gian thc thi on chng trnh trnh ny. Thng tin th ba l Library. Library l th vin cha nhng on m dng chung cho cc tin trnh hay ch dng ring cho mt tin trnh no . Cc th vin dng chung gi l cc th vin chun tng t nh th vin DLLs trong h iu hnh Windows. Nhng th vin dng ring c th l nhng th vin do ngi lp trnh nh ngha trong qu trnh xy dng chng trnh trnh (bao gm th vin lin kt ng v th vin lin kt chun). Thng tin th t l FileDes. FileDes l vit tt ca t ting Anh File Description tm dch l bng m t tp tin. Nh tn gi ca n, bng thng tin m t tp tin cha cc s m t tp tin c m trong qu trnh thc thi chng trnh. Mi mt tp tin trong h thng Linux khi c m iu cha mt s m t tp tin duy nht, bao gm nhng thng tin nh dng dn, cch thc truy cp tp tin (ch c, ch ghi, hay c hai thao tc c v ghi, ). xem nhng thng tin trn, chng ta thc hin lnh shell sau:
ps af

Sau khi thc hin xong chng ta s c kt qu nh sau:


root@:/home/arm/project/application# ps -af UID root PID 2731 PPID 2600 C STIME TTY 0 21:55 pts/2 TIME CMD 00:00:00 ps af

Ct th nht UID l tn ca ngi dng gi tin trnh. PID l s nh danh m h thng cung cp cho tin trnh. PPID l s dnh danh ca tin trnh cha gi tin trnh PID. C l CPU thc hin tin trnh. STIME l thi im tin trnh c a vo s dng. TIME l thi gian chim dng CPU ca tin trnh. TTY l terminal o ni gi thc thi tin trnh. CMD l chi tit dng lnh c triu gi thc thi. Ngoi ra chng ta cng c th dng lnh ps ax xem cc tin trnh ang thc thi ca ton b h thng. II. Ni dung:
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

43

N TT NGHIP Phn ny chng ta s tm hiu nhng hm thao tc vi tin trnh. Nhng hm ny s gip rt nhiu trong vic thit k mt h thng hot ng a tin trnh sao cho hiu qu nht. Mi hm s bao gm 3 phn thng tin. Th nht l c php s dng hm, th hai l ngha cc tham s trong hm, th ba l chng trnh v d cch s dng hm. c th ng dng ngay nhng kin thc hc vo thc t, chng ta phi tin hnh c hiu m lnh, sau lp trnh trn my tnh, bin dch v chy chng trnh, quan st so snh vi d on ban u. Nhng hm lit k s theo th t t d n kh, mang tnh cht k tha thng tin ca nhau. V th nn chng ta phi nghin cu theo trnh t ca bi hc nu cc bn l ngi mi bt u. 1. Hm system(): a. C php:
#include <stdlib.h> int system ( const char *cmdstr);

b. Gii thch: Hm system s thc thi chui lnh cmdstr do ngi lp trnh nhp vo. Chui lnh nhp vo cmdstr l lnh trong mi trng shell, chng hn ls l hay cd <directory> Hm system khi c gi trong mt tin trnh, n s tin hnh to v chy mt tin trnh khc (l tin trnh cha trong tham s) khi thc hin xong tin trnh ny th h thng mi tip phn cng thc hin nhng lnh tip theo sau hm system. Nu tin trnh trong hm system c gn cho hot ng hu tin trnh th nhng lnh theo sau hm system vn thc hin song song vi tin trnh . Chng ta s lm r hn trong phn chng trnh v d. Hm system c tham s const char *cmdstr l chui lnh ngi lp trnh mun thc thi. Hm system c gi tr tr v kiu int. Tr v gi tr li 127 nu nh khng khi ng c shell, m li -1 nu nh gp cc li khc. Nhng trng hp cn li l m li do lnh trong tham s cmdstr tr v. c. Chng trnh v d: Vit chng trnh in ra 10 ln chui helloworld nh sau: /*chng trnh helloworld system_helloworld.c*/
#include <stdio.h> ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

44

N TT NGHIP
int main (void) { int i; for (i = 0; i < 10; i++) { printf("Hello world %d!\n", i); sleep(1); } }

Bin dch v lu tp tin kt xut vi tn system_helloworld;


arm-none-linux-gnueabi-gcc system_helloworld.c o system_helloworld

Vit chng trnh khai bo s dng hm system gi thc thi tin trnh
system_helloworld bin dch:

/*Chng trnh ng dng hm system trng hp 1 system_main_1.c*/


#include <stdio.h>

/*Khai bo th vin s dng hm system*/


#include <stdlib.h> int main (void) {

/*In thng bo hm system bt u thc thi*/


printf ( "System has called a process... \n");

/*Thc thi hm system gi tin trnh system_helloworld c bin dch trc */


system ( "./system_helloworld" );

/*Thng bo tin trnh trong hm system thc thi xong*/


printf ( "Done.\n"); return 0; }

Bin dch v lu tp tin kt xut vi tn system_main;


arm-none-linux-gnueabi-gcc system_main_1.c o system_main_1

Chy chng trnh system_main_1 va bin dch trn kit, ta c kt qu sau:


./system_main_1 System has called a process... Hello world 0! Hello world 1! Hello world 2! Hello world 3! Hello world 4! ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

45

N TT NGHIP
Hello world 5! Hello world 6! Hello world 7! Hello world 8! Hello world 9! Done.

Gii thch chng trnh: chng trnh


system_main_1.c,

hm

system()

gi

tin

trnh

./system_helloworld chng trnh ny c nhim v in ra 10 ln chui Hello world. Chng trnh cha hm system i cho n khi thc hin xong vic in 10 ln chui
Hello world sau mi thc hin tip lnh pha sau hm system. Nh chng ta

thy, chui Done c in pha sau cng tt c cc dng thng tin. Trong trng hp th hai, chng ta s dng hm system gi mt tin trnh chy hu cnh. Ngha l lc ny, nhng cu lnh pha sau hm system s thc thi song song vi tin trnh c gi bi hm system. Vit chng trnh v d sau: /*Chng trnh ng dng hm system trng hp 2 system_main_2.c*/
#include <stdio.h>

/*Khai bo th vin s dng hm system*/


#include <stdlib.h> int main (void) {

/*In thng bo hm system bt u thc thi*/


printf ( "System has called a process... \n");

/*Thc thi hm system gi tin trnh system_helloworld c bin dch trc */


system ( "./system_helloworld &" );

/*Thng bo tin trnh trong hm system thc thi xong*/


printf ( "Done.\n"); return 0; }

Tin hnh bin dch chng trnh:


arm-none-linux-gnueabi-gcc system_main_2.c o system_main_2 ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

46

N TT NGHIP Chy chng trnh system_main_2 va bin dch trn kit, ta c kt qu sau:
./system_main_2 System has called a process... Done. # Hello world 0! Hello world 1! Hello world 2! Hello world 3! Hello world 4! Hello world 5! Hello world 6! Hello world 7! Hello world 8! Hello world 9!

Cng tng t trong chng trnh system_main_1.c nhng trong hm system ta gi tin trnh chy hu cnh system ( "./system_helloworld &" ); kt qu l chui thng tin Done c in ra ngay pha sau dng thng bo System has called a
process... m khng phi nm ti v tr cui nh trng hp 1. Hn na cng trong

trng hp ny, chng ta thy lnh trong hm system thc thi chm hn lnh pha sau hm system. y cng l mt yu im ln nht khi triu gi tin trnh bng hm system l thi gian thc thi chng trnh chm v system gi li shell ca h thng v chuyn giao trch nhim thc thi chng trnh cho lnh shell. Trong cc phn sau, chng ta s hc cch triu gi mt tin trnh thc thi sao cho it tn thi gian hn. 2. Cc dng hm exec: Cc hm to tin trnh dng nh system() thng thng tiu tn thi gian hot ng ca h thng nht. Mi mt tin trnh khi khi to v thc thi, h iu hnh s cp pht ring mt khng gian vng nh cho tin trnh s dng. Khi tin trnh A ang hot ng, gi hm system() to mt tin trnh B. Th h diu hnh s cp pht mt vng nh cho tin trnh B hot ng, iu ny lm thi gian thc hin ca tin trnh B tr nn chm hn. gii quyt trng hp ny, h diu hnh Linux cung cp cho chng ta mt s hm dng exec c th thc hin to lp mt tin trnh mi nhanh chng bng cch to
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

47

N TT NGHIP mt khng gian tin trnh mi t khng gian ca tin trnh hin c. Ngha l tin trnh hin c s nhng khng gian ca mnh cho tin trnh mi to ra, tin trnh c s khng hot ng na. Sau y chng ta s nghin cu hm execlp() phc v cho vic thay th tin trnh. a. C php:
#include <stdio.h> int execlp ( const char *file, const char *arg, , NULL);

b. Gii thch: Hm execlp () c nhim v thay th khng gian ca tin trnh c (tin trnh triu gi hm) bng mt tin trnh mi. Tin trnh mi to ra c ID l ID ca tin trnh c nhng m lnh thc thi, cu trc tp tin, th vin l ca tin trnh mi. Tin trnh c s b mt khng gian thc thi, tt nhin s khng cn thc thi trong h thng na. Hm execlp c cc tham s: const char *file l ng dn n tn tp tin chng trnh thc thi trn a. Nu tham s ny trng, h iu hnh s tm kim trong nhng ng dn khc cha trong bin mi trng PATH; cc tham s khc dng const
char *arg l nhng tn lnh, tham s lnh thc thi trong mi trng shell. Chng hn,

nu chng ta mun thc thi lnh ps ax trong mi trng shell th tham s th hai ca lnh l ps, tham s th ba l -ax. Tham s kt thc l NULL. Hm ny c gi tr tr v l mt s int. Hm tr v m li 127 khi khng triu gi c shell thc thi, -1 khi khng thc thi c chng trnh, cc m li cn li do chng trnh c gi thc thi tr v. c. Chng trnh v d: Thit k chng trnh thc hin cng vic sau: in ra chui Hello world 10 ln. Mi ln in ra cch nhau 1 giy. Chng trnh mu mang tn l: execlp_helloworld.c /*Chng trnh execlp_helloworld.c */
#include <stdio.h> int main (void) { int i; for (i = 0; i < 10; i++) { printf("Hello world %d!\n", i); sleep(1); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

48

N TT NGHIP
} return 0; }

Thc hin bin dch chng trnh vi tp tin ng ra l execlp_helloworld.


arm-none-linux-gnueabi-gcc execlp_helloworld.c o execlp_helloworld

Thit k chng trnh s dng hm execlp gi chng trnh execlp_helloworld va bin dch mang tn execlp_main.c. /*Chng trnh execlp_main.c*/ /*Khai bo th vin cho cc lnh s dng trong chng trnh*/
#include <stdio.h> #include <stdlib.h>

/*Chng trnh chnh*/


int main() {

/*Thng bo hm execlp bt du thc thi*/


printf ("Execlp has just start ...");

/*Tin hnh gi chng trnh execlp_helloworld t th mc hin ti*/


execlp (execlp_helloworld, execlp_helloworld, NULL);

/*In ra thng bo kt thc chng trnh execlp_main, chng ta s khng thy lnh ny thc thi*/
printf ("Done.");

/*Tr v gi tr 0 cho hm main, thng bo qu trnh thc thi chng trnh khng c li*/
return 0; }

Bin dch chng trnh execlp_main.c vi tp tin ng ra l execlp_main, lu vo cng th mc vi chng trnh execlp_helloworld:
arm-none-linux-gnueabi-gcc execlp_main.c o execlp_main

Tin hnh chy chng trnh chng ta c kt qu sau:


./execlp_main Execlp has just start ...

**Chng ta thy chng trnh execlp_helloworld khng th thc thi c. Nguyn nhn v khi gi chng trnh execlp_helloworld h iu hnh s tin hnh kim trong bin mi trng PATH ng dn cha chng trnh ny. M chng trnh
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

49

N TT NGHIP
execlp_helloworld khng cha trong bt k ng dn no trong bin mi trng

m ch cha trong th mc hin tai. chng trnh gi c chng trnh


execlp_helloworld chng ta phi thm dng dn th mc hin hnh vo bin mi

trng bng lnh sau: export PATH=$PATH:. trong shell. Khi tin hnh chy li chng trnh execlp_main th chng trnh
execlp_helloworld s c gi thc thi. Sau y l kt qu: ./execlp_main Execlp has just start ... Hello world 0! Hello world 1! Hello world 2! Hello world 3! Hello world 4! Hello world 5! Hello world 6! Hello world 7! Hello world 8! Hello world 9!

Do cu lnh execlp (execlp_helloworld, execlp_helloworld, NULL); tin hnh thay th khng gian thc thi ca tin trnh hin ti bng tin trnh mi
execlp_helloworld. V th, tt c nhng lnh pha sau hm execlp iu khng thc

thi. Chng ta thy chui Done. khng th no in ra mn hnh c. i khi thay th tin trnh ang chy bng mt tin trnh khc li khng tt. Gi s chng ta mun quay li chng trnh chnh khi chng trnh mi to thnh thc thi xong th sao. H iu hnh Linux cung cp cho chng ta nhng lnh c kh nng lm c nhng cng vic trn. 3. Hm fork(): a. C php:
#include <sys/types.h> #include <unistd.h> pid_t fork();

b. Gii thch:

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

50

N TT NGHIP Hm fork() cng nm trong nhm hm to tin trnh mi trong tin trnh ang thc thi. Hm fork() lm nhim v to mt tin trnh mi l con ca tin trnh ang thc thi. Ngha l ton b khng gian ca tin trnh cha s c sao chp qua khng gian ca tin trnh con, ch khc nhau m lnh thc thi v cc gi tr ID ca chng. Tin trnh con c hai thng s ID, PPID l ID ca tin trnh cha, v PID l ID ca tin trnh con ny. Hm fork() s quay tr v thi im gi hai ln. Ln th nht, hm fork() tr v gi tr 0 bo hiu nhng lnh tip theo sau l thuc v tin trnh con. Ln th hai, hm
fork() tr v mt gi tr khc 0. Gi tr ny chnh l ID ca tin trnh con mi va to

thnh. Hm fork () tr v gi tr -1 khi qu trnh to lp tin trnh con xy ra li. Hm


fork () khng c tham s. Chng ta c th dng c im trn tin hnh to lp mt

tin trnh mi ngay trong mt tin trnh hin ti theo lu sau:

Vi lu trn chng ta c th thit k mt don chng trnh chun thao tc v s dng hm fork() nh sau:
pid_t child_pid; child_pid = fork(); switch (child_pid) { case -1: printf (Cannot create child process.);

/*Thng bo li cho ngi dng khi khng to lp c tin trnh con*/


break; case 0: printf (This is the child process.);

/*Nhng lnh thuc v tin trnh con*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

51

N TT NGHIP
break; default: printf (This is the parent process.);

/*Nhng lnh thuc v tin trnh cha*/


break; }

Sau y l chng trnh v d minh ha cch s dng hm fork() to lp tin trnh. c. Chng trnh v d: Chng trnh v d sau y s lm nhim v to lp mt tin trnh con bn trong tin trnh cha ang thc thi. Tin trnh cha s in ra chui Parent process: Hello 5 ln. Trong khi tin trnh con cng in ra chui thng tin Child process: Hello nhng vi 10 ln. Mi ln cch nhau 1 giy. Thc hin thit k chng trnh vi nhng yu cu trn: /*Chng trnh v d hm fork() fork_main.c*/ /*Khai bo th vin cn thit cho cc hm s dng trong chng trnh*/
#include <stdio.h> //Th vin s dng cho hm printf(); #include <unistd.h>

//Th vin s dng cho hm fork();

#include <sys/types.h> //Th vin s dng cho kiu pid_t;

/*Chng trnh chnh*/


int main(void) {

/*Khai bo bin lu tr id cho tin trnh con*/


pid_t child_pid;

/*Khai bo cc bin s dng m s ln in chui k t*/


int n, m;

/*Thc hin chia tin trnh bng hm fork()*/ /*Chng trnh s quy li y hai ln*/
child_pid = fork();

/*Tch tin trnh bng cch kim tra child_pid*/


switch (child_pid) {

/*Khi chng trnh khng th phn chia tin trnh con*/


case -1: printf ("Cannot create process."); return -1; ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

52

N TT NGHIP /*Nhng lnh trong trng hp ny thuc v tin trnh con*/


case 0: printf ("This is the child"); for (n = 0; n < 10; n++) { printf ("Child process: Hello %d\n", n); sleep (1); } return 0;

/*Nhng lnh trong trng hp ny thuc v tin trnh cha*/


default: printf ("This is the parent"); for (m=0; m < 5; m++) { printf ("Parent process: Hello %d\n", m); sleep(1); } break; } return 0; }

Thc hin bin dch chng trnh vi tp tin chng trnh kt xut l fork_main.
arm-none-linux-gnueabi-gcc fork_main.c o fork_main

Chp tp tin chng trnh fork_main vo kt v tin hnh chy chng trnh. Chng ta c kt qu sau:
./fork_main This is the parentParent process: Hello 0 This is the childChild process: Hello 0 Parent process: Hello 1 Child process: Hello 1 Parent process: Hello 2 Child process: Hello 2 Parent process: Hello 3 Child process: Hello 3 Parent process: Hello 4 Child process: Hello 4 # Child process: Hello 5 Child process: Hello 6 Child process: Hello 7 Child process: Hello 8 ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

53

N TT NGHIP
Child process: Hello 9

Vi kt qu trn, chng ta thy tin trnh cha v tin trnh con chy ng thi vi nhau v trnh t xut ra chui thng tin. Hai tin trnh ny c h iu hnh chia thi gian thc hin ng thi, c lp vi nhau. Do khi tin trnh cha kt thc, tin trnh con vn tip tc thc hin. Chng ta c th kim tra s thc thi ca hai tin trnh trn bng lnh shell sau.
./fork_main & ps -af [1] 3264 This is the parentParent process: Hello 0 This is the childChild process: Hello 0 UID root root root PID 3264 3265 3266 PPID 3173 3173 3264 C STIME TTY 0 19:28 pts/1 8 19:28 pts/1 0 19:28 pts/1 TIME CMD 00:00:00 ./fork_main 00:00:00 ps -af 00:00:00 ./fork_main

Chng ta thy, tin trnh fork_main c gi hai ln trong h thng. Ln th nht l tin trnh cha, s ID l 3264. Ln th 2 l tin trnh con vi s PPID l 3264 cng vi s PID ca tin trnh cha, v s PID l 3266. i khi chng ta mun tin trnh cha trong lc thc thi khi cn thc hin mt nhim v c th s gi mt tin trnh con khc thc hin thay v ch tin trnh con kt thc tin trnh cha mi lm vic tip. Trong trng hp trn th yu cu ny khng thc hin c. Tin trnh cha thm ch kt thc tin trnh con vn tip tc thc hin. Hin tng ny gi l hin tng tin trnh con b b ri. Chng ta khng mun trng hp ny xy ra. H thng Linux cung cp cho chng ta hm wait thc hin cng vic ny. 4. Hm wait(): a. C php:
#include <sys/types.h> #include <sys/wait.h> pid_t wait ( int &stat_loc );

b. Gii thch: Nh trn cp, tin trnh cha v tin trnh con i hi phi c s ng b nhau trong vic x l thng tin. Tin trnh cha phi i tin trnh con kt thc mi tin hnh lm nhng cng vic tip theo, s dng kt qu ca tin trnh con. Hm wait() c s dng vi mc ch ny.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

54

N TT NGHIP Hm wait() c tham s int &stat_loc l con tr lu trng thi ca tin trnh con khi thc hin xong. Hm wait() tr v l s ID ca tin trnh con hon thnh. Chng trnh sau s cho chng ta hiu r cch s dng hm wait(). c. Chng trnh v d: Cng ging nh chng trnh v d trc, chng trnh ny cng to ra hai tin trnh, tin trnh cha v tin trnh con. Nhng ln ny tin trnh cha s i tin trnh con kt thc sau mi thc hin tip cng vic ca mnh khi s dng hm wait().
/*Chng trnh v d hm wait() wait_main.c*/ /*Khai bo th vin cn thit cho cc hm s dng trong chng trnh*/ #include <stdio.h> //Th vin s dng cho hm printf(); #include <unistd.h>

//Th vin s dng cho hm fork(); //Th vin s dng cho hm wait;

#include <sys/types.h> //Th vin s dng cho kiu pid_t; #include <sys/wait.h>

/*Chng trnh chnh*/


int main(void) { /*Khai bo bin lu tr id cho tin trnh con*/ pid_t child_pid;

/*Khai bo cc bin s dng m s ln in chui k t*/


int n, m;

/*Khai bo bin lu trng thi tin trnh con khi thc hin xong*/
int child_status;

/*Thc hin chia tin trnh bng hm fork()*/ /*Chng trnh s quy li y hai ln*/
child_pid = fork();

/*Tch tin trnh bng cch kim tra child_pid*/


switch (child_pid) {

/*Khi chng trnh khng th phn chia tin trnh con*/


case -1: printf ("Cannot create process."); return -1;

/*Nhng lnh trong trng hp ny thuc v tin trnh con*/


case 0: printf ("This is the child"); for (n = 0; n < 10; n++) { ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

55

N TT NGHIP
printf ("Child process: Hello %d\n", n); sleep (1); } return 0;

/*Nhng lnh trong trng hp ny thuc v tin trnh cha*/


default: printf ("This is the parent");

/*Ch tin trnh con kt thc*/


wait (&child_status); for (m=0; m < 5; m++) { printf ("Parent process: Hello %d\n", m); sleep(1); } break; } return 0; }

Bin dch chng trnh v lu tn chng trnh bin dch thnh wait_main
arm-none-linux-gnueabi-gcc wait_main.c o wait_main

Chy chng trnh chng ta c kt qu sau:


./wait_main This is the parent This is the child Child process: Hello 0 Child process: Hello 1 Child process: Hello 2 Child process: Hello 3 Child process: Hello 4 Child process: Hello 5 Child process: Hello 6 Child process: Hello 7 Child process: Hello 8 Child process: Hello 9 Parent process: Hello 0 Parent process: Hello 1 Parent process: Hello 2 Parent process: Hello 3 ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

56

N TT NGHIP
Parent process: Hello 4

Nh vy chng ta thy r rng, tin trnh con thc hin xong ghi 10 ln chui Hello
world th tin trnh cha mi thc hin tip cng vic ca mnh ghi 5 ln chui Hello world tip theo.

Trong hm wait (&child_status); c xut hin bin con tr &child_status, bin ny kt hp vi mt s macro trong th vin <sys/wait.h> s cho chng ta nhng thng tin thc hin tin trnh con. Chi tit v cc macro ny, cc bn hy tham kho trong th vin <sys/wait.h> trong h thng linux. III. Kt lun:

Trong bi ny chng ta hc nhng nh ngha rt cn bn v tin trnh. Tin trnh l mt trong nhng k thut lp trnh hiu qu trong lp trnh ng dng chy trn h iu hnh nhng. hiu v thao tc thnh tho vi tin trnh chng ta cng nghin cu nhng hm nh to lp tin tnh, thay th tin trnh v nhn i tin trnh. Bn cnh chng ta cng tham kho cch s dng hm wait trong vic ng b ha hot ng ca cc tin trnh vi nhau. (Thm gii hn trong bi ny l khng trnh by trao i thng tin gia c tin trnh, tranh chp d liu thc thi ca cc tin trnh vi nhau). Tin trnh l mt k thut hiu qu nhng cha phi l hiu qu nht v thi gian thc thi. V h iu hnh cn phi tn thi gian khi to khng gian thc thi cho mi tin trnh mi to ra. i vi nhng ng dng i hi thi gian thc thi nhanh th tin trnh khng th gii quyt c. Linux cung cp cho chng ta mt k thut lp trnh mi hiu qu hn l k thut lp trnh a tuyn m chng ta s nghin cu ngay trong bi sau y.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

57

N TT NGHIP BI 4

LP TRNH A TUYN TRONG USER APPLICATION


I. Kin thc ban u v tuyn trong Linux: Trong bi trc chng ta hc nhng khi nim c bn nht v tin trnh trong Linux. Trong h thng Linux, cc tin trnh c mt khng gian vng nh ring hot ng c lp nhau, x l mt nhim v c th trong chng trnh. Chng ta c th to lp mt tin trnh mi t tin trnh ang thc thi bng cc hm thao tc vi tin trnh. Tuy nhin chi ph to lp mt tin trnh mi rt ln c bit l thi gian thc thi. V h iu hnh phi to lp mt khng gian vng nh cho chng trnh mi, hn na vic giao tip gia cc tin trnh rt phc tp (chng ta s nghin cu trong cc bi sau). H iu hnh Linux cung cp cho chng ta mt k thut lp trnh mi t tn thi gian hn v hiu qu hn trong lp trnh ng dng. l k thut lp trnh a tuyn. Tuyn l mt thut ng c dch t tuyn. Mt s sch khc cn gi l tiu trnh hay lun. Tuyn c hiu nh l b phn cu thnh mt tin trnh. C cng khng gian vng nh vi tin trnh, c kh nng s dng nhng bin cc b c nh ngha trong tin trnh. Nu nh trong h iu hnh c nhiu tin trnh cng hot ng song song th trong mt tin trnh cng c nhiu tuyn hot ng song song nhau chia s khng gian vng nh ca tin trnh . Tin trnh v tuyn nhiu khi cng tng t nhau. Nu nh trong tin trnh c nhiu tuyn cng hot ng song song th tuyn l mt b phn cu thnh tin trnh. Nu nh trong tin trnh ch c mt tuyn th tuyn v tin trnh l mt. Nh vy n y chng ta c th hiu h iu hnh Linux va lm nhim v chia khe thi gian thc hin tin trnh, va lm nhim v chia khe thc hin tuyn trong tin trnh. Trong bi ny chng ta s nghin cu nhng hm s dng trong lp trnh a tuyn: Cc hm to lp v hy tuyn; Cc hm ch i tuyn thc thi nhm thc hin ng b trnh t thi gian thc thi

lnh gia cc tuyn; II. Ni dung: 1. Hm pthread_create(): a. C php:


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

58

N TT NGHIP
#include <pthread.h> int pthread_create ( pthread_t * thread,

pthread_attr_t * attr, void * (*start_routine) (*void), void *arg );

b. Gii thch: Hm pthread_create () c dng to mt tuyn mi t tin trnh ang chy. Tuyn mi c to thnh c thuc tnh quy nh bi tham s pthread_attr_t * attr, nu tham s ny c gi tr NULL th tuyn mi to ra s c thuc tnh mc nh (Chng ta khng i su vo cc thuc tnh ny do thng thng nn s dng NULL). Khi tuyn c to ra thnh cng, h iu hnh s t ng cung cp mt ID lu trong tham s
pthread_t * thread phc v cho mc ch qun l.

Tuyn mi to ra c tp lnh thc thi cha trong chng trnh con quy nh trong tham s void * (*start_routine) (*void). Chng trnh con ny c tham s cha trong void *arg. thot khi tuyn ang thc thi mt cch t ngt v tr v m li, chng ta sng hm pthread_exit(). Hm ny tng t nh exit () trong tuyn chnh main(). Nu
pthread_exit() hay exit () t cui tuyn th nhim nhim v ca chng l tr v gi

tr thng bo cho ngi lp trnh bit trng thi thc thi lnh ca chng trnh. on m lnh sau s cho chng ta hiu r cch s dng hm pthread_create () v xem cch hm pthread_create () hot ng trong thc t. c. Chng trnh v d: Trong chng trnh v d sau y, chng ta to ra mt chng trnh con. Chng trnh con ny in ra chui thng tin c chung cp t tham s ca n. Chng trnh con ny c c hai tuyn s dng in ra thng tin ca mnh. Chng ta tin hnh lp trnh theo yu cu trn. Sau y l chng trnh mu: /*Chng trnh v d hm pthread_create () pthread_create.c*/ /*Khai bo th vin cn thit cho cc hm s dng trong chng trnh */
#include <stdio.h> //Cho hm printf (); #include <pthread.h> // Cho hm pthread_create();

/*Chng trnh con in ra thng tin t tin trnh triu gi*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

59

N TT NGHIP
void * do_thread ( void * data) {

/*Khai bo b m in d liu ra mn hnh*/


int i;

/*Chp d liu cung cp bi chng trnh triu gi vo vng nh trong hm kiu int*/
int me = (int*)data;

/*In chui thng tin ra mn hnh 5 ln cho mi tin trnh triu gi*/
for ( i=0; i<5; i++) {

/*%d u tin l s cho bit tin trnh no ang triu gi, %d th hai l s ln in thng tin ra mn hnh*/
printf (" '%d' -Got '%d' \n", me, i);

/*Tr hon mt khong thi gian l 1s*/


sleep (1);

} /*Thot khi tuyn c triu gi, khng xut ra d liu thng bo*/
pthread_exit(NULL); }

/*Tuyn chnh triu gi chng trnh con do_thread*/


int main (void) {

/*Khai bo bin lu m li tr v bi hm pthread_create()*/


int thr_id;

/*Khai bo bin lu ID cho tuyn to ra*/


pthread_t p_thread;

/*Bin lu nh danh ca tuyn */


int a = 1; int b = 2;

/* S dng hm pthread_create() to mt tuyn mi Tuyn mi c ID lu vo p_thread, m li tr v thr_id, hm thc thi l do_thread, tham s l a*/
thr_id = pthread_create ( &p_thread, NULL, do_thread, (void *)a);

/*Gi hm do_thread() trong tuyn chnh, tham s l b*/


do_thread ((void*)b);

/*Tr v gi tr 0 thng bo qu trnh thc thi lnh khng c li*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

60

N TT NGHIP
return 0; }

Tin hnh bin dch chng trnh lu vi tn l pthread_create bng lnh sau: **Ch y l chng trnh c s dng a tuyn nn chng ta phi bin dch c s h tr ca th vin a tuyn ch khng bin dch chng trnh ging nh cch thng thng.
arm-none-linux-gnueabi-gcc lpthread pthread_create.c o pthread_create

Chy chng trnh trn h thng chng ta c kt qu sau:


./pthread_create '2' -Got '0' '1' -Got '0' '2' -Got '1' '1' -Got '1' '2' -Got '2' '1' -Got '2' '2' -Got '3' '1' -Got '3' '2' -Got '4' '1' -Got '4'

Hai tuyn, mt xut pht t tuyn chnh main(), v mt xut pht t hm


pthread_create, chy song song nhau, cng in ra mn hnh chui thng tin. Trong mi

ln in tuyn 2 lun thc hin trc tuyn 1, nguyn nhn l v tuyn 2 c gi thc thi trc tin trong h thng. Chng trnh con do_thread mc d ch c mt nhng c kh nng chy ng thi trn nhiu tin trnh. Thc ra mi thi im CPU ch thc thi mt tuyn theo s phn chia thi gian ca h iu hnh do khng xy ra s xung t trong vic s dng hm. 2. Hm pthread_join(): Trong thc t, chng ta cn thc hin ng b ha hot ng ca gia cc tuyn vi nhau. Gi s tuyn chnh triu gi mt tuyn ph thc hin mt cng vic no , tuyn chnh ch tuyn ph thc hin song, tr v gi tr no th tuyn chnh mi thc hin nhng cng vic tip theo. Linux cng cung cp cho chng ta hm pthread_join() thc hin nhng cng vic trn.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

61

N TT NGHIP a. C php:
#include <pthread.h> int pthread_join ( pthread_t th, void *thread_return);

b. Gii thch: Hm pthread_join () cung cp cho chung ta mt cong c ng b ha trnh t hot ng ca cc tuyn. Hm pthread_join () c hai tham s. Tham s th nht pthread_t th l ID ca tuyn mun i. Tham s th hai void *thread_return l gi tr tuyn tr v t hm
pthreate_exit(data) khi c s dng cui chng trnh.

Hm pthread_join () c gi tr tr v l int, tr v 0 nu nh hm thc thi thnh cng, tr v gi tr khc 0 l m li thc thi hm. c. Chng trnh v d: Chng trnh v d sau cho chng ta hiu c cch s dng hm pthread_join() trong chng trnh. Chng trnh thread_join.c c hai tuyn to thnh. Tuyn chnh to ra tuyn ph gi chng trnh con in ra chui thng tin cn thit v ch cho tuyn ph kt thc, tuyn chnh tip tc thc hin in thng bo tuyn ph kt thc v thot chng trnh thc thi. M chng trnh mu: /*Chng trnh v d cch s dng hm pthread_join, chng trnh thread_join.c */ /*Khai bo th vin cn thit cho cc hm s dng trong chng trnh*/
#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <pthread.h>

/*Khai bo bin ton cc s dng lm d liu chung cho c hai tuyn*/ /*Cc tuyn nm trong cng mt tin trnh c th s dng chung bin ny*/
char message[] = "Hello world!";

/*Chng trnh con dng cho to lp tuyn*/


void * do_thread (void *data) {

/*Bin dng cho vic m thng tin xut ra mn hnh*/


int i;

/*Np thng tin trong tham s hm cho b nh trong tuyn*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

62

N TT NGHIP
int me = (int *)data;

/*In ra thng bo tuyn ang thc thi*/


printf ("Thread function is executing ...\n");

/*In ra gi tr ca bin message trc khi b thay i*/


printf ("Thread data is %s\n", message);

/*Tr hon in cc thng tin th nghim cho ngi dng quan st*/
for ( i=0; i<5; i++) { printf (" '%d' got '%d'\n", me, i); sleep (1); }

/*Thay i ni dung ca bin ton cc message*/


strcpy(message,"Goodbye!");

/*Xut ra thng tin tr v cho tham s ca hm pthread_join */


pthread_exit("Thanks for your using me!"); }

/*Tuyn chnh*/
int main(void) {

/*Khai bo bin lu ID ca tuyn to ra*/


pthread_t a_thread;

/*Bin int lu m li ca chng trnh*/


int res;

/*nh danh cho tuyn*/


int a = 1;

/*Khai bo con tr tr d liu v khi i tuyn hon thnh xong nhim v*/
void * thread_result;

/*Thc hin to tuyn mi t tuyn chnh vi nhng thuc tnh mc nh, Hm thc thi l do_thread, tham s cho hm l bin int a*/
res = pthread_create (&a_thread, NULL, do_thread, (int *)a);

/*Thng bo khi c li xut hin*/


if (res != 0) { perror ("Thread cresated error."); exit (EXIT_FAILURE); }

/*In thng bo np mt tuyn vo danh sch i*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

63

N TT NGHIP
printf ("Wait for thread to finish ...\n");

/*Tin hnh np tuyn vo danh sch i*/


res = pthread_join(a_thread, &thread_result);

/*Thng bo m li trong qua trnh thc thi hm pthread_join*/


if (res != 0) { perror ("Thread wait error."); exit (EXIT_FAILURE); }

/*Thng bo tuyn ph hon thnh nhim v, xut kt qu tr v*/


printf ("Thread completed, it returned %s\n", (char *)thread_result);

/*In ra bin message sau khi b thay i bi tuyn ph*/


printf ("Message is now: %s\n", message);

/*Tr v gi tr 0 cho tuyn main() thng bo qu tr nh thc thi khng c li*/


return 0; }

Bin dch chng trnh lu vi tn thread_join bng dng lnh sau:


arm-none-linux-gnueabi-gcc thread_join.c o thread_join lpthread

Tin hnh chy chng trnh chng ta c kt qu sau:


./thread_join Wait for thread to finish ... Thread function is executing ... Thread data is Hello world! '1' got '0' '1' got '1' '1' got '2' '1' got '3' '1' got '4' Thread completed, it returned Thanks for your using me! Message is now: Goodbye!

Chng ta c th to ra nhiu tuyn hot ng cng mt lc v tuyn chnh cng c th ch i nhiu tuyn cng mt lc. Bng cch np cc tuyn cn ch i vo danh sch ch i khi dng hm pthread_join(), tuyn no c np vo hng i trc s c hon thnh trc nht nu cc tuyn c cng thi gian thc thi.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

64

N TT NGHIP Cc tuyn c th s dng chung cc bin ton cc nh ngha, y cng l mt u im ca lp trnh a tuyn so vi lp trnh a tin trnh. Tuy nhin lp trnh a tuyn c mt yu im l tnh khng bn vng trong qu trnh thc thi lnh. Trong qu trnh thc thi mt tin trnh c nhiu tuyn chy ng thi, nu c mt tuyn b li th ton b tin trnh s b li. Cn lp trnh a tin trnh th khng nh th, khi mt tin trnh b li, cc tin trnh khc iu hot ng bnh thng. Chng ta phi bit tn dng c hai u im ca hai phng php lp trnh trn. ng thi khc phc nhc im ca chng. Bng vic phn cng ph hp nhim v ca tng tc v trong khi lp trnh. III. Kt Lun: n y chng ta bit cch khi to mt tuyn ph chy song song vi mt tuyn chnh ang thc thi bng hm pthread_create (). Chng ta cng bit cch ng b ha hot ng gia cc tuyn vi nhau, tuyn chnh c th thc hin i cho mt hay nhiu tuyn khc thc hin xong vic x l thng tin sau mi tip tc cng vic x l ca mnh, bng cch dng hm pthread_join(). n y chng ta kt thc phn lp trnh ng dng trong lp user application ca phn mm h thng nhng. Trong phn sau chng ta s nghin cu cch vit chng trnh trong mt mi trng khc l kernel driver, y l mt lp trung gian giao tip gia h iu hnh v phn cng h thng.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

65

N TT NGHIP

PHN B

CN BN LP TRNH DRIVER

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

66

N TT NGHIP BI 1

DRIVER V APPLICATION TRONG H THNG NHNG


I. Khi qut v h thng nhng: H thng nhng (embedded system) c ng dng rt nhiu trong cuc sng ngy nay. Theo nh ngha, h thng nhng l mt h thng x l v iu khin nhng tc v c trng trong mt h thng ln vi yu cu tc x l thng tin v tin cy rt cao. N bao gm phn cng v phn mm cng phi hp hot ng vi nhau, ty thuc vo ti nguyn phn cng m h thng s c phn mm iu khin ph hp. i khi chng ta thng nhm ln h thng nhng vi my tnh c nhn. H thng nhng cng bao gm phn cng (CPU, RAM, ROM, USB, ...) v phn mm (Application, Driver, Operate System, ...). Th nhng khc vi my tnh c nhn, cc thnh phn ny c rt gn, thay i cho ph hp vi mt mc ch nht nh ca ng dng sao cho ti u ha thi gian thc hin p ng yu cu v thi gian thc (Real-time) theo tng mc . Bi ny s i su vo tm hiu cu trc bn trong phn mm ca h thng nhng nhm mc ch hiu c vai tr ca driver v application, phn phi nhim v hot ng cho hai lp ny sao cho t hiu qu cao nht v thi gian. II. Cu trc ca h thng nhng: H thng nhng thng thng bao gm nhng thnh phn sau: Phn cng: B vi x l trung tm, b nh, cc thit b vo ra; Phn mm: Cc Driver cho thit b, H iu hnh v cc chng trnh ng dng. Mi lin h gia cc thnh phn c minh ha trong s hnh x_y. Thnh phn th nht trong h thng nhng l phn cng. y l thnh phn quan trong nht trong h thng. Lm nhim v thc t ha nhng dng lnh t phn mm yu cu. Phn cng ca h thng nhng thng bao gm nhng thnh phn chnh sau: B x l trung tm, lm nhim v tnh ton thc thi cc m lnh c yu cu, c xem nh b no ca ton h thng. Cc b x l trong h thng nhng, khng ging nh h thng my vi tnh c nhn l nhng con vi x l mnh chuyn v x l d liu, l nhng dng vi iu khin mnh, c tch hp sn cc module ngoi vi gip cho vic thc thi lnh ca h thng c thc hin nhanh chng hn. Hn na tp lnh ca vi
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

67

N TT NGHIP iu khin cng tr nn gn nh hn, t tn dung lng vng nh hn ph hp vi c im ca h thng nhng. Vi nhng vi iu khin tch hp sn nhng ngoi vi mnh, a dng th kch tht mch phn cng trong qu trnh thi cng s gim rt nhiu. y l u im ca h thng nhng so vi cc h thng a nhim khc.

Thnh phn th hai l cc thit b lu tr: Cc thit b lu tr bao gm c RAM, NAND Flash, NOR Flash, ... mc d bn trong vi iu khin tch hp sn ROM v RAM, nhng nhng vng nh ny ch l tm thi, dung lng ca chng rt nh, gip cho vic thc thi nhng lnh c nhanh hn. lu tr nhng m lnh ln nh: Kernel, Rootfs, hay Application th i hi phi c nhng thit b lu tr ln hn. RAM lm nhim v cha chng trnh thc thi mt cch tm thi. Khi mt chng trnh c triu gi, m lnh ca chng trnh c chp t cc thit b lu tr khc vo RAM, t y tng cu lnh c bin dch s ln lt i vo vng nh cache bn trong vi x l thc thi. Cc loi ROM nh NAND Flash, NOR Flash, ... thng c dung lng ln nht trong h thng nhng, dng cha nhng chng trnh ln (h iu hnh, rootfs, bootstrapcode, ... ) lu di s dng trong nhng mc ch khc nhau khi ngi dng (h iu hnh v user) cn s dng n. Chng tng t nh a cng trong my tnh c nhn. Cc thit b vo ra: y l nhng module c tch hp sn bn trong vi iu khin. Chng c th l ADC module, Ethenet module, USB module, ... cc thit b ny c vai tr giao tip gia h thng vi mi trng bn ngoi.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

68

N TT NGHIP Thnh phn quan trng th hai trong mt h thng nhng l phn mm. Phn mm ca h thng nhng thay i theo cu trc phn cng. H thng ch hot ng hiu qu khi phn mm v phn cng c s tng thch nhau. i t thp ln cao thng thng phn mm h thng nhng bao gm cc lp sau: Driver thit b, h iu hnh, chng trnh ng dng. Cc driver thit b (device driver): y l nhng phn mm c vit sn trc tip iu khin phn cng h thng nhng. Mi mt h thng nhng c cu to t nhng phn cng khc nhau, nhng vi iu khin vi nhng tp lnh khc nhau, nhng module khc nhau ca cc hng khc nhau c c ch giao tip khc nhau, device driver lm nhim v chun ha thnh nhng th vin chung (c m lnh ging nhau), phc v cho h iu hnh v ngi vit chng trnh lp trnh d dng hn. Chng hn, nhiu h thng c giao thc truy xut d liu khc nhau, nhng device driver s quy v 2 hm duy nht mang tn read v write c v nhp thng tin cho h thng x l. phn bit gia cc thit b vi nhau, device driver s cung cp mt ID duy nht cho thit b nhm mc ch thun tin cho vic qun l. **Device driver s c trnh by rt r trong nhng bi khc. H iu hnh: y cng l mt phn mm trong h thng nhng, nhim v ca n l qun l ti nguyn h thng. Bao gm qun l tin trnh, thi gian thc, truy xut vng nh o v vng nh vt l, cc giao thc mng, ... Chng trnh ng dng: Cc chng trnh ng dng l do ngi dng lp trnh. Thng thng trong h thng nhng, cng vic lp trnh v bin dch khng nm trn chnh h thng . Ngc li c nm trn mt h thng a nhim khc, qu trnh ny gi l bin dch cho (cross-compile). Sau khi bin dch xong, chng trnh bin dch c chp vo bn trong ROM lu tr phc v cho qu trnh s dng sau ny. Cc chng trnh s s dng nhng dch v bn trong h iu hnh (to tin trnh, to tuyn, tr hon thi gian, ...) v nhng hm c nh ngha trong device driver (giao tip thit b u cui, truy xut IO, ...) tc ng n phn cng ca h thng. **Quyn sch ny ch yu trnh by su v phn mm h thng nhng. Trong phn u chng ta nghin cu s lc v cch lp trnh ng dng, lm th no tr hon
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

69

N TT NGHIP thi gian, to tin trnh, to tuyn, ... Phn ny s i su vo lp cui cng trong phn mm l Device driver. III. Mi quan h gia Device drivers v Applications: Application (chng trnh ng dng) v Device drivier (Driver thit b) c nhng im ging v khc nhau. Tiu ch so snh da vo nguyn l hot ng, v tr, vai tr ca tng loi trong h thng nhng. Application v Device driver khc nhau cn bn nhng im sau: V cch thc mi loi hot ng, a s cc Application n nhim va v nh hot ng xuyn sut t cu lnh u tin cho n cu lnh kt thc mt cch tun t k t khi c gi t ngi s dng. Trong khi , Device driver th hon ton khc, chng c lp trnh vi theo dng tng module, nhm mc ch phc v cho vic thc hin mt thao tc ca Application c gn nh v dng hn. Mi module c mt hay nhiu chc nng ring, c lp trnh cho mt thit b c trng v c ci dt sn trn h iu hnh sn sng hot ng khi c gi. Sau khi c gi, module s thc thi v kt thc ngay lp tc. Mt cch khi qut, chng ta c th xem: Nu Application l chng trnh phc v ngi dng, th Device driver l chng trnh phc v Application. Ngha l Application l ngi dng ca Device driver. Mt im khc bit gia Application v Device driver l vn an ton khi thc thi tc v. Nu mt Application ch n gin thc thi v kt thc, th cng vic ca Device driver phc tp hn nhiu. Bn cnh vic thc thi nhng lnh c lp trnh n cn phi m bo an ton cho h thng khi khng cn hot ng. Ni cch khc, trc khi kt thc, Device driver phi khi phc trng thi trc ca h thng tr li ti nguyn cho cc Device driver khc s dng khi cn, trnh tnh trng xung t phn cng. Mt Application c th thc thi nhng lnh m khng cn nh ngha trc , cc lnh ny cha trong th vin lin kt ng ca h iu hnh. Khi vit chng trnh cho Application, chng ta s tic kim c thi gian, cho ra sn phm nhan hn. Trong khi , Device driver mun s dng lnh no th i hi phi nh ngha trc . Vic nh ngha ny c thc hin khi chng ta dng khai bo #include <linux/library.h>, nhng th vin ny phi thc s tn ti, ngha l cn dng m lnh C cha bin dch. Cc th vin ny cha trong h thng m ngun ca h iu hnh trc khi c bin dch.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

70

N TT NGHIP Mt chng trnh Application dang thc thi nu pht sinh mt li th khng cn hot dng c na. Trong khi , khi mt tc v trong module b li, n ch nh hng n cu lnh gi m thi (ngha l kt qu truy xut s khng ng) cc lnh tip theo sau vn c th tip tc thc thi. Thng thng lc ny chng ta s thot khi chng trnh bng lnh exit(n), m bo d liu x l l chnh xc. Chng ta c hai thut ng mi, user space (khng gian ngi dng) v kernel space (khng gian kernel). Khng gian y chng ta nn hiu l khng gian b nh o, do h thng Linux nh ngha v qun l. Cc chng trnh ng dng Application c thc thi trong user space, cn nhng Device driver khi c bin dch thnh tp tin ko s c lu tr trong kernel space. Kernel space v User space lin h nhau thng qua h iu hnh (operating system). Trong khi hu ht cc lnh trong tng tin trnh v tuyn c thc hin tun t nhau, kt thc lnh ny ri mi thc hin lnh tip theo, trong user space; Th cc module trong device driver c th cng mt lc phc v ng thi nhiu tin trnh, tuyn. Do Device driver khi lp trnh phi m bo gii quyt c vn ny trnh tnh trng xung t vng nh, phn cng trong qu trnh thc thi. IV.Kt lun: Chng ta tm hiu s lc v cu trc tng qut trong h thng nhng, hiu c vai tr chc nng ca tng thnh phn. Bn cnh chng ta cng phn bit c nhng c im khc nhau gia chng trnh trong user space v Device Driver trong kernel space. Nhng kin thc ny rt quan trng khi bc vo lp trnh driver cho thit b. Chng ta phi bit phn cng nhim v gia user application v kernel driver sao cho t hiu qu cao nht. Bi tip theo chng ta s i vo tm hiu cc loi driver trong h thng Linux, cch nhn dng tng loi, cng nh cc thao tc cn thit khi lm vic vi driver. BI 2

PHN LOI V NHN DNG DRIVER TRONG LINUX


I. Tng quan v Device Driver:
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

71

N TT NGHIP Mt trong nhng mc ch quan trng nht khi s dng h iu hnh trong h thng nhng l lm sao cho ngi s dng khng nhn bit c s khc nhau gia cc loi phn cng trong qu trnh iu khin. Ngha l h iu hnh s quy nhng thao tc iu khin khc nhau ca nhiu loi phn cng khc nhau thnh mt thao tc iu khin chung duy nht. V d nh, h iu hnh quy nh tt c nhng a, thit b vo ra, thit b mng iu di dng tp tin v th mc. Vic khi ng hay tt thit b ch n gin l ng hay m tp tin (th mc) cn sau khi thao tc ng hay m h iu hnh lm g l cng vic ca device driver. Trong mt h thng nhng, khng phi ch c CPU mi c th x l thng tin m tt c nhng thit b phn cng iu c mt c cu iu khin c lp trnh sn, c trng cho tng thit b. Mi mt th nh, USB, chut, USB Camera, iu l nhng h thng nhng c lp, chng c tng nhim v ring, m trch mt cng vic x l thu thp thng tin c th. Mi b iu khin ca cc thit b iu cha nhng thanh ghi lnh v thanh ghi trng thi. V iu khin c th chng ta phi cung cp nhng s nh phn cn thit vo thanh ghi lnh, c thanh ghi trng thi cho bit trng thi thc hin. Tng t khi mun thu thp d liu, chng ta phi cung cp nhng m cn thit, theo nhng bc cn thit do nh sn xut quy nh. Thay v phi lm nhng cng vic nhm chn , chng ta s giao cho device driver m trch. Device driver thc cht l nhng hm c lp trnh sn, np vo h iu hnh. C ng vo l nhng giao din chung, ng ra l nhng thao tc ring bit iu khin tng thit b ca device driver . Linux cung cp cho chng ta 3 loi device driver: Character driver, block driver, v network driver. Character driver hot ng theo nguyn tc truy xut d liu khng c vng nh m, ngha l thng tin s di chuyn lp tc t ni gi n ni nhn theo tng byte. Block driver th khc, hot ng theo c ch truy xut d liu theo vng nh m. C hai vng nh m, m ng vo v m ng ra. D liu trc khi di chuyn vo (ra) h thng phi cha trong vng nh m, cho n khi vng nh m y th mi c php xut (nhp). Ngha l d liu di chuyn theo tng khi. Network driver hot ng theo mt cch ring dng socket mng, ch yu dng trong truyn nhn d liu t xa gia cc my vi nhau trong mng cc b hay internet bng cc giao thc mng ph bin. **Trong sut phn ny chng ta ch yu nghin cu v character driver. Mc tiu l c th t mnh thit k mt character driver n gin;
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

72

N TT NGHIP II. Cc c im ca device driver trong h iu hnh Linux: Chng ta bit nh th no l device driver, c im ca tng loi device driver. Th nhng cc loi driver ny c h iu hnh Linux qun l nh th no? Bt k mt thit b no trong h iu hnh Linux cng c qun l thng qua tp tin v th mc h thng. Chng c gi l cc tp tin thit b hay l cc tp tin h thng. Nhng tp tin ny iu cha trong th mc /dev. Trong th mc /dev chng ta thc hin lnh ls l, h thng s cho ra kt qu sau:
crw-rw-rwcrw------crw------crw-rw-rwcrw-rw---crw--w---crw--w---crw-rw-rw 1 root 1 root 1 root 1 root 1 root 1 vcsa 1 vcsa 1 root root root root tty uucp tty tty root 1, 10, 4, 4, 4, 7, 1, 3 Apr 11 1 Apr 11 64 Apr 11 65 Apr 11 1 Apr 11 5 Apr 11 2002 null 2002 psaux 2002 ttys0 2002 ttyS1 2002 vcs1 2002 vcsa1 2002 zero

1 Oct 28 03:04 tty1

7, 129 Apr 11

Ct th nht cho chng ta thng tin v loi device driver. Theo thng tin trn th tt c iu l character driver v nhng k t u tin iu l c, tng t nu l block driver th k t u l b. Chng ta ch n ct th 4 v 5, ti y c hai thng tin cch nhau bng du , hai s ny c gi l Major v Minor. Mi thit b trong h iu hnh iu c mt s 32 bits ring bit qun l. S ny c chia thnh hai thng tin, thng tin th nht l Major number. Major number l s c 12 bit, dng phn bit tng nhm thit b vi nhau, hay ni cch khc nhng thit b cng loi s c chung mt s Major. Cc thit b cng loi c cng s Major c phn bit nhau thng qua thng tin th hai l s Minor. S Minor l s c chiu di 20 bit. Vi hai s Major v Minor, tng cng h iu hnh c th qun l s thit b ti a l 212*220 tng ng vi 232. Trong lp trnh driver, i khi chng ta mun thao tc vi hai thng tin Major v Minor numbers. Kernel cung cp cho chng ta nhng hm rt hu ch thc hin nhng cng vic ny. Sau y l mt s hm tiu biu: #include <linux/types.h> #include <linux/kdev_t.h> int MAJOR (dev_t dev);
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

73

N TT NGHIP int MINOR (dev_t dev); dev_t MKDEV (int major, int minor); Trc khi s dng nhng hm ny, chng ta phi khai bo th vin ph hp cho chng. th vin <linux/types.h> cha nh ngha kiu d liu dev_t, bin kiu ny dng cha s nh danh cho thit b. Th vin <linux/kdev_t.h> cha nh ngha cho nhng hm MAJOR(), MINOR(), MKDEV, Hm MAJOR (dev_t dev) dng tch s Major ca thit b dev_t dev v lu vo mt bin kiu int; Hm MINOR (dev_t dev) dng tch s Minor ca thit b dev_t dev v lu vo mt bin kiu int; Hm MKDEV (int major, int minor) dng to thnh mt s nh danh thit b kiu dev_t t hai s int major, v int minor; i vi kernel 2.6 tr i th s device driver dev_t c 32 bit. Nhng i vi nhng kernel i sau th dev_t c 16 bit. III. Kt lun: Trong bi ny chng ta i vo tm hiu mt cch khi qut vai tr ngha ca tng loi device driver trong h thng Linux, mi device driver iu c nhng u v nhc im ring v ng gp mt phn lm cho h thng chy n nh. Chng ta cng bit cch thc qun l thng tin thit b ca Linux thng qua th mc /dev, mi thit b trong Linux iu c mt s nh danh, ty vo tng h thng m s ny c bao nhiu bit, s nh danh c th c to thnh t hai s ring bit Major v Minor bng hm MKDEV() hoc c th tch ring mt s nh danh dev_t thnh hai s Major v Minor bng hai hm MAJOR() v MINOR (). Nhng hm ny rt quan trong trong lp trnh driver. Trong gii hn v thi gian, quyn sch ny ch trnh by cho cc bn cch lp trnh mt character driver. Trn c s cc bn s t mnh tm hiu cch lp trnh cho cc loi driver khc. Bi sau chng ta s tm hiu su hn v character driver, cu trc d liu bn trong, cc hm thao tc khi to character device,

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

74

N TT NGHIP BI 3

CHARACTER DEVICE DRIVER


I. Tng quan character device driver: Character device driver l mt trong 3 loi driver trong h thng Linux. y l driver d v ph bin nht trong cc ng dng giao tip va v nh i vi lp trnh nhng. Character driver v cc loi driver khc iu c h iu hnh qun l di dng tp tin v th mc. H iu hnh s dng cc hm truy xut tp tin chun giao tip trao i thng tin gia ngi lp trnh v thit b do driver iu khin. Chng hn nhng hm nh
read, write, open, release, close, c dng chung cho tt c cc character

driver, nhng hm ny cn c gi l giao din iu khin gia h iu hnh (c ngi lp trnh ra lnh) v device driver (c h iu hnh ra lnh). Hot ng bn trong giao din ny l nhng thao tc ca tng device driver c trng cho tng thit b . Cng vic lp trnh cc thao tc ny gi l lp trnh driver. Mt character driver mun ci t v hot ng bnh thng th phi tri qua nhiu bc lp trnh. u tin l ng k s nh danh cho driver, s nh danh l s m h iu hnh linux cung cp cho mi driver qun l. Tip theo, m t tp lnh m driver h tr, chng ta c th xem tp lnh l nhng thao tc hot ng bn trong ca driver dng iu khin mt thit b vt l. Sau khi m t tp lnh, chng ta s lin kt cc tp lnh ny vi cc giao din chun m h iu hnh linux h tr, nhm mc ch giao tip gia h iu hnh v cc thit b ngoi v vt l m driver iu khin. Tip theo chng ta nh ngha lin kt cc giao din ny vi cu trc m t tp tin khi thit b c m. Cui cng chng ta thc hin ci t driver thit b vo h thng th mc tp tin linux, thng thng nm trong th mc /dev. Trong phn ny chng ta s tm hiu mt cch chi tit cc bc lp trnh driver nu. II. S nh danh character driver: Th no l s nh danh, c dim v vai tr ca s nh danh ca character driver cng hon ton tng t nh device driver khc m chng ta nghin cu rt k trong bi trc. Chng ta cng bit nhng hm rt quan trng thao tc vi s nh danh

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

75

N TT NGHIP ny. y khng nhc li m thm vo l lm th no to lp mt s nh danh cho thit b no m khng sinh ra li a. Xc nh s nh danh hp l cho thit b mi theo cch thng thng: Mt trong nhng cng vic quan trong u tin cn phi lm trong driver l xc nh s nh danh cho thit b. C hai thng tin cn xc nh l s Major v s Minor. Trc ht chng ta phi bit s nh danh no cn trng trong h thng cha c cc thit b khc s dng. Thng tin v s nh danh c linux s dng cha trong tp tin Documentation/devices.txt. Tp tin ny cha s nh danh, tn thit b, thi gian to lp, loi thit b, c linux s dng hay s dng cho nhng mc ch c bit no . c ni dung trong tp tin ny, chng ta s tm c s nh danh ph hp, v cng vic tip theo l ng k s nh danh vo linux. Linux kernel cung cp cho chng ta mt hm dng ng k s nh danh cho thit b, hm l:
#include <linux/fs.h> int register_chrdev_region (dev_t first, unsigned int count, char *name);

s dng c hm, chng ta phi khai bo th vin <linux/fs.h>. Tham s th nht dev_t first l s nh danh thit b u tin mun ng k vi s Major l s hp l cha c s dng, Minor thng thng cho bng 0. Tham s th hai unsigned int
count l s thit b mun ng k, chng hn mun ng k 1 thit b th ta nhp 1, lc

ny chi c mt thit b mang s nh danh l dev_t first c ng k. Tham s th ba char *name l tn thit b mun ng k. Hm register_chrdev_region () tr v gi tr kiu int l 0 nu qu trnh ng k thnh cng. V tr v s m li m khi qu trnh ng k khng thnh cng. Tt c nhng thng tin khi ng k thnh cng s c h iu hnh cha trong tp tin /proc/devices v sysfs khi qu trnh ci dt thit b kt thc. Cch ng k s nh danh trn c mt nhc im ln l ch p dng khi ngi ng k ng thi l ngi lp trnh nn driver v th h s bit r s nh danh no l cn trng. Khi driver c s dng trn nhng my tnh khc, th s nh danh c chn c th b trng vi cc driver khc. V th vic la chn mt s nh danh ng l cn thit.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

76

N TT NGHIP V s nh danh ng s khng trng vi bt k s nh danh no tn ang tn ti trong h thng. V d, nu mun ng k mt character driver c tn l lcd_dev, s lng l 1, s Major u tin l 2, chng ta tin hnh khai bo hm nh sau: /*Khai bo bin lu tr m li tr v ca hm*/
int res;

/*Thc hin ng k thit b cho h thng*/


res = register_chrdev_region (2, 1, lcd_dev); if (res < 0) { printk (Register device error!); exit (1); }

b. Xc nh s nh danh cho thit b theo cch ngu nhin: Linux cung cp cho chng ta mt hm ng k s nh danh ng cho driver thit b mi.
#include <linux/fs.h> int alloc_chrdev_region (dev_t *dev, unsigned int firstminor, unsigned int count, char *name);

Cng

tng

nh

hm

register_chrdev_region

(),

hm

alloc_chrdev_region () cng lm nhim v ng k nh danh cho mt thit b mi.

Nhng c mt im khc bit l s Major trong nh danh khng cn c nh na, s ny do h thng linux t ng cp v th s khng trng vi bt k s nh danh no khc tn ti. Tham s th nht ca hm, dev_t *dev, l con tr kiu dev_t dng lu tr s nh danh u tin trong khong nh danh c cp nu hm thc hin thnh cng; Tham s th hai, unsigned int first minor, l s Minor u tin ca khong nh danh mun cp; Tham s th ba, unsigned int count, l s lng nh danh mun cp, tnh t s Major c cp ng v s Minor unsigned int first minor;
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

77

N TT NGHIP Tham s th t, char *name, l tn ca driver thit b mun ng k. V d khi mun ng k thit b tn lcd_dev, s Minor u tin l 0, s thit b mun ng k l 1, s nh danh khi to ra c lu vo bin dev_t dev_id. Lc ny hm
alloc_chrdev_region () khai bo nh sau:

/*Khai bo bin dev_t lu gi tr nh danh u tin tr v ca hm*/


dev_t dev_id;

/*Khai bo bin lu m li tr v ca h thng*/


int res;

/*Thc hin ng k thit b vi nh danh ng*/


res = alloc_chrdev_region (&dev_id, 0, 1, lcd_dev);

/*Kim tra m li tr v*/


if ( res < 0) { printk (Allocate devices error!); return res; }

Tuy nhin vic dng k s nh danh ng cho thit b i khi cng c nhiu bt li. Gi s s nh danh ca thit b cn c s dng cho nhng mc ch khc, v th s nh danh lun thay i khi mi ln ci t driver s sinh ra li trong qu trnh thc thi lnh. kt hp u im ca 2 phng php, chng ta s ng k driver thit b theo cch sau: /*Khai bo cc bin cn thit*/
int lcd_major; //Bin lu tr s Major int lcd_minor; //Bin lu tr s Minor dev_t dev_id; //Bin lu tr s nh danh thit b int result;

//Bin lu m li

/*Nu s Major hp l, tn ti*/


if (lcd_major) { dev = MKDEV(lcd_major, lcd_minor); //To s nh danh

/*ng k thit b vi s nh danh c nh*/


result "lcd_dev"); ________________________________________________________________________________CH = register_chrdev_region (dev, lcd_nr_devs,

NG II: LP TRNH NHNG NNG CAO

78

N TT NGHIP
} else {

/*Nu s Major cha tn ti, thc hin tm kim s Major ng*/


result "lcd_dev"); = alloc_chrdev_region(&dev_id, lcd_minor, lcd_nr_devs,

/*Cp nht li s Major ng cn s dng trong nhng ln sau*/


lcd_major = MAJOR (dev_id); }

/*Kim tra kt qu thc thi ca hai lnh trn*/


if (result < 0) { printk(KERN_WARNING "lcd: can't get major %d\n", lcd_major); return result; }

Nh vy ta c th cp nht li s nh danh ng khi va to ra s dng cho nhng chng trnh lin quan bng k thut nh trong on m lnh trn. Character driver bao gm c nhiu thnh phn, ng k s nh danh ch l mt trong nhng thnh phn . Bn cnh s nh danh character driver cn c nhng b phn nh: Cu trc d liu (data structure) c gi l file_operation, cu trc ny cha nhng tp lnh c ngi lp trnh driver nh ngha; Cu trc m t tp tin (file) cha nhng thng tin c bn ca tp tin thit b; Cu trc tp tin cha thng tin qun l tp tin thit b trong h thng linux. Phn tip theo chng ta s tm hiu cch gn cc hnh vi cho character device driver thng qua vic thao tc vi file_operations. III. Cu trc lnh ca character driver: Cu trc lnh ca character driver (file_operations) l mt cu trc dng lin kt nhng hm cha cc thao tc ca driver iu khin thit b vi nhng hm chun trong h iu hnh gip giao tip gia ngi lp trnh ng dng vi thit b vt l. Cu trc file_operation c nh ngha trong th vin <linux/fs.h>. Mi mt tp tin thit b c m trong h iu hnh linux iu c h iu hnh dnh cho mt vng nh m t cu trc tp tin, trong cu trc tp tin c rt nhiu thng tin lin quan phc v cho vic thao tc vi tp tin (chng ta s nghin cu k trong phn sau). Mt trong nhng thng tin ny l file_operations, dng m t nhng hm m driver thit b ang c m
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

79

N TT NGHIP h tr. C th ni mt cch khc mi tp tin thit b trong h thng linux tng t nh mt vt th v file_operation l nhng cng dng ca vt th . Cu trc file_operations l mt thnh phn trong cu trc file_structure khi tp tin thit b c m. Mi thnh phn trong file_operations bao gm nhng lnh cn bn theo chun do h iu hnh nh ngha, nhng nhng lnh ny cha c nh ngha thao tc c th, y l nhim v ca ngi lp trnh driver. Chng ta phi lin kt nhng thao tc mun lp trnh vi nhng dng hm chun ny. Sau y chng ta s tm hiu mt s nhng thnh phn quan trong trong cu trc file_structure:
struct module *owner

y khng phi l mt lnh trong driver m ch con tr cho bit tn driver no qun l nhng lnh c lin kt. Thng tin ny c thit lp thng qua macro THIS_MODULE nh ngha trong th vin <linux/module.h>.
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);

Hm chun ny dng yu cu nhn d liu t thit b vt l. Nhn d liu nh th no s do ngi lp trnh quyt nh, ph hp vi quy nh ca tng thit b. Tham s th nht, struct file *, l con tr n cu trc tp tin ang m trong h iu hnh, dng phn bit thit b ny vi thit b khc. Tham s th hai, char __user *, l con tr c khai bo trong user space, cha thng tin c c t thit b. Tham s th ba, size_t l kch thc d liu mun c (tnh bng byte). Tham s th t, loff_t *, l con tr ch v tr d liu trong thit b cn c v, nu trng th mc nh l v tr u tin. Hm c gi tr tr v l kch thc d liu c v thnh cng.
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

Hm ny dng ghi thng tin ca ngi dng vo thit b vt l. Cc thao tc ghi c th s do ngi lp trnh quyt nh ty theo tng thit b phn cng. Tham s th nht,
struct file *, l con tr n cu trc tp tin ang m trong h iu hnh, dng

phn bit thit b ny vi thit b khc khi s dng nhiu thit b. Tham s th hai, char
__user *, l con tr c khai bo trong user space, cha thng tin mun ghi t ngi

s dng. Tham s th ba, size_t l kch thc d liu mun ghi (tnh bng byte). Tham s th t, loff_t *, l con tr ch a d liu trong thit b cn ghi thng tin, nu
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

80

N TT NGHIP trng th mc nh l v tr u tin. Hm c gi tr tr v l kch thc d liu ghi thnh cng.


int (*open) (struct inode *, struct file *);

y l hm lun c thc thi khi thao tc vi driver. Hm c gi khi ta s dng lnh m tp tin driver thit b s dng. Chng ta khng cn thit phi lp trnh thao tc cho lnh ny. Trong cu trc lnh c th t gi tr NULL, nh vy khi driver s khng c cnh bo khi thit b c m. Mc d khng quan trng nhng chng ta nn khai bo lnh open_device trong chng trnh s dng m li tr v khi cn thit.
int (*release) (struct inode *, struct file *);

Hm chun ny dc thc thi khi driver thit b khng cn s dng, thot khi h thng linux. Cng tng t nh hm open, hm release c th khng cn khai bo trong cu trc tp lnh file_operation. Tuy nhin thun li trong qu trnh lp trnh, chng ta nn khai bo hm release_device trong driver c th tr v m li nu cn thit.
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);

ioctl l mt hm rt mnh trong cu trc tp lnh file_operations. Hm ny c th tch hp nhiu hm khc do ngi lp trnh driver nh ngha. Nhng hm khc nhau c phn bit thng qua cc tham s ca hm ioctl. Tham s th nht, struct inode
*, l cu trc tp tin trong h thng th mc linux (chng ta s nghin cu trong phn

sau). Tham s th hai, struct file *, l cu trc tp tin ang m trong h thng linux. Tham s th ba, unsigned int, l s unsigned int phn bit nhng lnh khc nhau, c th gi y l s nh danh lnh. tham s th ba, dng unsigned long, l tham s ca hm tng ng vi s nh danh lnh. Chng ta s nghin cu su cc s dng hm trong nhng bi sau. Sau y l mt v d cho thy cch gn chc nng cho cc hm s dng trong tp lnh ca character device driver. /*Khai bo cu trc lnh cho driver*/
struct file_operations lcd_fops = {

/*Tn ca module s hu tp lnh ny*/


.owner = THIS_MODULE,

/*Gn lnh c lcd_read vo hm chun read*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

81

N TT NGHIP
.read = lcd _read,

/*Gn hm ghi d liu vo hm chun write*/


.write = lcd _write,

/*Gn hm lcd_ioctl vo hm chun ioctl*/


.ioctl = lcd _ioctl,

/*Gn hm khi ng thit b vo hm chun, c th t gi tr NULL*/


.open = lcd _open,

/*Gn hm thot thit b vo hm chun, c th t gi tr NULL*/


.release = }; lcd _release,

Tip theo chng ta s nghin cu cu trc khc ln hn trong character device driver. Cu trc ny cha nhng thng tin thao tc tp tin cn thit khi tp tin ang m trong c cu trc tp lnh file_operations. IV. Cu trc m t tp tin ca character driver: Cu trc m t tp tin (file_structure), nh ngha trong th vin <linux/fs.h> l cu trc quan trng th hai trong character device driver. Cu trc ny khng xut hin trong h thng th mc tp tin ca Linux. M ch xut hin khi tp tin c m, s dng trong h thng. Khi mt tp tin c m, linux s cung cp mt khng gian vng nh lu tr nhng thng tin quan trng phc v cho qu trnh lp trnh s dng tp tin. Nhng thng tin l:
mode_t f_mode;

Thng tin ny quy nh ch truy xut tp tin thit b. Mt tp tin khi c m trong h thng s c th ch c php c, ch c php ghi, hay c hai bng cch s dng cc bit c FMODE_READ v FMODE_WRITE. Chng ta nn kim tra ch truy xut ca tp tin thit b khi s dng hm ioclt hay open. Nhng khi s dng hm read v write thi khng cn thit. V trc khi thc thi cc hm ny h thng s t ng kim tra cc c hp l hay khng, nu khng h thng s b qua khng thc thi.
loff_t f_pos;

L thng tin lu v tr truy cp tp tin, phc v cho thao tc read v write. y l s c 64 bits, kh nng truy xut rt rng. Ngi lp trnh driver c th tham kho thng tin
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

82

N TT NGHIP ny bit v tr hin ti ca con tr truy cp tp tin. Tuy nhin nn hn ch thay i thng tin ny. thay i thng tin ny, chng ta c th thay i trc tip bng cch thay i tham s filp -> f_pos hoc c th s dng nhng hm chun trong linux.
unsigned int f_flags;

y l nhng c th hin ch truy cp tp tin, bao gm nhng gi tr c th nh,


O_RDONLY, O_NONBLOCK, O_SYNC trong nhng thng tin ny th O_NONBLOCK c s

dng nhiu nht kim tra lnh thc hin c phi l lnh truy xut theo block hay khng. Cn nhng thng tin truy xut khc thng thng c kim tra thng qua
f_mode. Cc nh ngha cho gi tr bit c cha trong th vin <linux/fcnt.h> struct file_operations *f_op;

Thng tin ny cha nh ngha cc tp lnh tng ng ca tng tp tin thit b. Thng tin ny c gii thch r trong phn trn.
void *private_data;

y l con tr n vng nh dnh ring cho ngi s dng driver. Vng nh ny c xa khi tp tin c m, nhng vn tn ti khi tp tin c ng, v th chng ta phi tin hnh gii phng vng nh ny trc khi thot.
struct dentry *f_dentry;

Cha thng tin v tp tin ngun c m, mi tp tin c m trong h thng linux iu bt ngun t mt tp tin no lu trong b nh. Ngi vit driver thng dng thng tin ny hn l thng tin v i_node ca thit b qun l v tr tp tin thit b c m trong h thng. Trong thc t mt tp tin tng qut c m trong h thng c th c nhiu hn nhng thng tin nu trn. Nhng i vi tp tin driver th nhng thng tin khng cn thit. Tt c nhng driver iu thao tc trn c s nhng cu trc tp tin c xy dng sn. V. Cu trc tp tin ca character driver: Cu trc tp tin (inode structure) c kernel s dng c trng cho mt tp tin driver thit b. Cu trc ny hon ton khc vi cu trc file structure c gii thch trong phn trc, iu ny c ngha l c th c nhiu file structure biu th cu trc tp tin ang m nhng tt c nhng file structure ny iu c ngun gc t mt inode structure duy nht.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

83

N TT NGHIP Kernel dng cu trc file structure ny biu din mt tp tin thit b trong cu trc h thng ca mnh (hay ni c th hn l cu trc cy th mc). Chng ta c th m tp tin ny vi nhiu ch d truy xut khc nhau, mi ch truy xut s tng ng vi mt cu trc file structure. Cu trc inode structure cha rt nhiu thng tin v tp tin thit b, trong cng vic lp trnh driver chng ta ch quan tm n nhng thng tin sau y:
dev_t i_rdev;

Mi mt cu trc inode structure i din cho mt tp tin thit b, thng tin ny trong inode structure cha s nh danh thit b m chng ta to trong phn trc.
struct cdev *i_cdev; struct cdev l kiu cu trc lu tr thng tin ca mt tp tin lu tr trong kernel.

V thng tin i_cdev l con tr n cu trc ny. Linux cung cp cho chng ta hai hm chun tm s nh danh Major v Minor ca thit b biu th bng inode structure. Hai hm l:
unsigned int iminor(struct inode *inode); unsigned int imajor(struct inode *inode);

Chng ta nn dng hm ny ly thng tin v s nh danh thit b bn cnh vic truy cp trc tip thng tin dev_t i_rdev trong cu trc inode structure. VI. Ci t character device driver vo h thng Linux: Sau khi ng k s nh danh thit b, thit lp lin kt vi file_operations, gn file_operations vi file_structure, v nh ngha mt inode_structure, chng ta hon thnh c bn mt character device driver. Cng vic cui cng l tin hnh ci t character driver ny vo h iu hnh v s dng. Phn ny s trnh by cho chng ta cc bc ci t nhng cu trc trn vo kernel tr thnh mt character driver hon chnh. Nhng hm c gii thiu sau y c nh ngha trong th vin
<linux/cdev.h>.

Trc khi ci t thng tin vo kernel chng ta phi khai bo cho kernel dnh ra mt khng gian vng nh ring, chun b cho qu trnh ci t. C hai cch thc hin cng vic ny. Cch 1: Khai bo cu trc trc khi nh ngha thng tin.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

84

N TT NGHIP
struct cdev *my_cdev = cdev_alloc(); my_cdev->ops = &my_fops; ... (Tng t cho nhng trng khc)

u tin chng ta khai bo con tr cu trc dng struc cdev cha con tr struct cdev trng do hm cdev_alloc() tr v. Tip theo, nh ngha tng thng tin lin quan cho cu trc va to ra. Chng hn, trong cu lnh trn, chng ta cp nht con tr cu trc lnh cho cdev ny bng lnh gn c bn my_cdev->ops = &my_fops; trong
&my_fops l cu trc lnh c to thnh t trc c gn vo trng ops ca cu

trc my_cdev. Cch 2: Thc hin nh ngha thng tin trc khi khai bo cho kernel.
struct cdev *my_cdev; my_cdev->ops = &my_ops; ... (Tip theo cho nhng trng khc) cdev_init ( my_cdev, my_ops);

Nh vy, sau khi nh ngha xong cc trng cn thit cho cu trc struct cdev, chng ta tin hnh gi hm cdev_init (); thng bo cho kernel dnh ra mt vng nh ring lu tr cdev mi va to ra. Cu trc ca hm cdev_init () nh sau:
void cdev_init(struct cdev *cdev, struct file_operations *fops);

Vi struct cdev *cdev l con tr cu trc lu thng tin driver c khai bo,
struct file_operations *fops l cu trc tp lnh ca driver.

Sau khi khai bo cho kernel dnh mt vng nh lu tr cu trc driver, cng vic cui cng l triu gi hm cdev_add () ci t cu trc ny vo kernel. Cu trc ca hm cdev_add nh sau:
int cdev_add(struct cdev *dev, dev_t num, unsigned int count);

Trong , struct cdev *dev l con tr cu trc driver cn ci t. dev_t num l s nh danh thit b u tin mun ci t vo h thng, s nh danh ny c xc nh ph hp vi h thng thng qua cc hm c trng. Tham s cui cng, unsigned int
count, l s thit b mun ci t vo kernel. ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

85

N TT NGHIP Hm ny s tr v gi tr 0 nu qu trnh ci t driver vo kernel thnh cng. Ngc li s tr v m li m. Kernel ch c th gi c nhng hm trong driver khi n c ci t thnh cng vo h thng. i khi chng ta mun tho b cu trc device driver ra khi h thng, linux cung cp cho chng ta hm cdev_del() thc hin cng vic ny. Cu trc ca hm nh sau:
void cdev_del(struct cdev *dev);

Vi cdev *dev l cu trc driver mun tho b, khi driver c tho b, th kernel khng th s dng nhng hm nh ngha trong kernel c na.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

86

N TT NGHIP VII. Tng kt:

Trn y chng ta tm hiu rt k nhng thnh phn cu to nn mt character driver do h thng linux nh ngha v qun l. Chng ta cng bit cch kt ni nhng trng c lin quan trong tng cu trc vi nhng hm c nh ngha v cch ci t nhng cu trc vo kernel. tm hiu hn v nguyn tc giao tip gia driver v user, trong bi sau chng ta s bn v cc giao din chun trong cu trc lnh ca character device driver, l cc hm
read(), write() v ioctl();

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

87

N TT NGHIP BI 4

CC GIAO DIN HM TRONG DRIVER


I. Tng quan v giao din trong cu trc lnh file_operations: Cu trc lnh file_operations l mt trong 3 cu trc quan trng ca character device driver, bao gm mt s nhng hm chun gip giao tip gia chng trnh ng dng trong user v driver trong kernel. Chng trnh ng dng cha nhng yu cu thc thi t ngi dng chy trong mi trng user(user space). Driver cha nhng hm chc nng iu khin thit b vt l c lp trnh sn chy trong mi trng kernel(kernel spcae). nhng yu cu t user c nhn ra v iu khin c phn thit b vt l th cn phi c mt giao din iu khin. Nhng giao din iu khin ny thc cht l nhng hm read(), write(), v ioctl(), ... c linux nh ngha sn, bn thn n khng c chc nng c th, chc nng c th c nh ngha bi ngi lp trnh driver. Chng hn, hm read() c chc nng tng qut l c thng tin t driver n mt vng nh m trong user (ca mt chng trnh ng dng ang chy), nhng driver mun ly c thng tin cung cp cho user th phi qua nhiu thao tc iu khin cc thanh ghi lnh thanh ghi d liu ca thit b vt l c vit bi ngi lp trnh driver, d liu thu c khng th truyn qua user mt cch trc tip m phi thng qua cc hm h tr trong giao din khc nh copy_to_user(). Trong phn ny, chng ta s tm hiu nguyn l hot ng ca nhng giao din ny, lm c s vit hon chnh mt character driver trong nhng bi sau. II. Giao din read() & write(): Do hm read() v write() ni chung iu c cng mt nhim v l trao i thng tin qua li gia user (application) v kernel (driver). Nu hm read() dng chp d liu t driver qua applcation, th ngc li hm write() dng chp d liu t application sang driver. Hn na hai hm ny iu c nhng tham s tng t nhau. V th chng ta s nghin cu hai hm ny cng lc. a. Cu trc lnh:
ssize_t read(struct file *filp, char __user *buff, size_t count, loff_t *offp); ssize_t write(struct file *filp, const char __user *buff, size_t count, loff_t *offp); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

88

N TT NGHIP b. Gii thch: Trong c hai hm trn, filp l con tr tp tin thit b mun truy xut d liu; count l kch thc mun truy xut tnh bng n v byte. buff l con tr n nh khai bo trong application lu d liu c v trong trng hp l hm read(), trong trng hp l hm write() th chnh l con tr n vng nh rng cn ghi d liu n. Cui cng offp l con tr dng long offset lu v tr con tr hin ti ca tp tin ang c truy cp. Sau y chng ta s tm hiu k hn tng tham s trong hm. Con tr const char __user *buff trong hm read(...) v write(...) iu l nhng con tr n mt vng nh trong user space do ngi lp trnh khai bo lu d liu truy xut t driver thit b. Hn na driver hot ng trong mi trng kernel. Gia user space v kernel space c nhng nguyn tc qun l b nh khc nhau. Do , driver, hot ng trong mi trng kernel, khng th giao tip vi con tr ny, hot ng trong mi trng user, mt cch trc tip m phi thng qua mt s hm c bit. Nhng hm giao tip ny c linux nh ngha trong th vin <asm/uaccess.h>. Cc hm ny l: unsigned long copy_to_user (void __user *to, const void *from,
unsigned long count); Cng dng ca hm l chp d liu t kernel space sang user

space; Trong , void __user *to l con tr n vng nh trong user space lu d liu chp t kernel space; const void *from l con tr cha d liu trong kernel space mun chp qua user space; unsigned long count l s bytes d liu mun chp. unsigned long copy_from_user (void *to, const void __user *from,
unsigned long count); Cng dng ca hm l chp d liu t user space sang kernel

space; Trong , void *to l con tr n vng nh trong kernel space lu d liu chp t user space; const void __user *from l con tr cha d liu trong user space mun chp qua kernel space; unsigned long count l s bytes d liu mun chp. Hai hm iu c gi tr tr v kiu unsigned long. Trc khi truyn d liu chng kim tra gi tr con tr vng nh c hp l hay khng. Nu khng hp l, th qu trnh truyn d liu khng th thc hin v hm s tr v m li -EFAULT. Nu trong qu trnh truyn d liu, gi tr con tr cp nht b li, th qu trnh truyn dng ngay ti thi im
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

89

N TT NGHIP , v nh th ch mt phn d liu c chp. Phn d liu truyn thnh cng s c thng bo trong gi tr tr v di dng s byte. Chng ta cn c vo gi tr ny truyn li thng tin nu cn thit. Nu khng c li xy ra, hm s tr v gi tr 0. Chng ta s minh ha nguyn tc hot ng ca hm read() v write() thng qua s hnh x_y:

dev_write

write() copy_from_user()

read()

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

90

N TT NGHIP

Chng ta thy trong s trn c hai khng gian vng nh m, vng nh m bn user space v vng nh m bn kernel space. Chng trnh trong user space gi hm read() hay hm write() th driver chy trong kernel space s tin hnh thc hin nhng thao tc chp d liu bng cch s dng hai hm
copy_to_user() hay copy_from_user() giao tip trao i thng tin gia hai

vng m ny. ng thi cp nht nhng thng tin cn thit phc v theo di qu trnh truyn d liu. Cng vic ny c thc hin bi ngi lp trnh driver. III. Giao din ioctl(): Trn y chng ta tm hiu hai giao din read() v write() dng trao i d liu qua li gia user space v kernel space, hay ni ng hn l gia driver thit b vt l v chng trnh ng dng. Th nhng trong thc t, ngoi vic trao i d liu, mt driver thit b cn phi thc hin nhiu cng vic khc v d: cp nht cc thng s giao tip (tc baund, s bits d liu truyn nhn, ...) ca thit b vt l, iu khin trc tip cc thanh ghi lnh phn cng, ng m cng giao tip, ... Linux cung cp cho mt giao din chun khc phc v cho tt c cc thao tc iu khin trn, l giao din ioctl(). Nh vy, ioclt() c th thc hin nhng chc nng ca hm read() v write(), th nhng ch hiu qu trong trng hp s lng d liu cn truyn khng cao, mang tnh cht ri rc. Trong trng hp d liu truyn theo tng khi, lin tc th s dng hm read() v write() l mt la chn khn ngoan. a. Cu trc lnh: Hm ioctl() c cu trc nh sau:
#include <linux/ioctl.h> int (*ioctl) (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg);

b. Gii thch: Nh trn phn tch, tt c nhng giao din trong character device driver u khng c nhng chc nng c th. Nhng tham s lnh ch mang tnh tng qut, ngi lp trnh driver phi hiu r ngha tng tham s sau s nh ngha c th chc nng tng tham s ny ny a vo s dng ty theo yu cu trong thc t. Sau y chng ta s tm hiu cc tham s trong hm ioctl.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

91

N TT NGHIP struct inode *inode v struct file *filp l con tr inode structure v file structure tng ng vi tng thit b c m trong chng trnh. Hai tham s ny iu cha trong s m t tp tin (file descriptor) gi tt l fd, c tr v khi thc hin m thit b thnh cng bi hm open(). (**Theo nguyn tc, trc khi thc hin giao tip vi cc thit b trong h thng linux, chng ta phi truy cp n cu trc inode ca tp tin thit b trn b nh, kch hot khi ng thit b bng hm open(), hm ny s quy nh ch truy xut tp tin thit b ny, sau khi kch hot thnh cng hm open() s tr v s m t tp tin fd, mang tt c thng tin ca thit b ang c m trong h thng). unsigned int cmd, l s unsigned int do ngi lp trnh driver quy nh. Mi lnh trong ioctl c phn bit nhau thng qua s cmd ny. S unsigned int cmd c 16 bits c chia thnh 2 phn. Phn u tin c 8 bits MSBs c gi l s magic dng phn bit lnh ca thit b ny vi thit b khc. Phn th hai c 8 bit LSBs dng phn bit nhng lnh khc nhau ca cng mt thit b. S nh danh lnh ny tng t nh s nh danh thit b, phi c nh ngha duy nht trong h thng linux. bit c s nh danh lnh no cn trng, chng ta s tm trong tp tin Documentation/ioctl-number.txt. Tp tin ny cha thng tin v cch s dng hm
ioctl() v thng tin v s nh danh lnh c s dng trong h thng linux. Nhim

v ca chng ta l i chiu so snh loi tr nhng s nh danh ny, tm ra s nh danh trng cho thit b ca mnh. Sau khi tm ra khong s nh danh lnh cho mnh, chng ta nn ghi r khong nh danh vo tp tin ioctl-number.txt sau ny thun tin cho vic lp trnh driver mi. Do hm ioctl() tn ti trong c hai mi trng, giao din trong user space v nhng thao tc lnh hot ng trong kernel space nn cc s nh danh lnh ny phi quy nh chung trong c hai mi trng. i vi cc chng trnh application v driver c s dng giao din ioctl, vic u tin trong on m chng trnh l nh ngha s nh danh lnh, mi s nh danh lnh c mt ch truy xut d liu khc nhau. Nhng ch ny c gii thch trong tp tin ti liu Documentation/ioctl-number.txt. S nh danh thit b c nh ngha theo dng thc sau:

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

92

N TT NGHIP /*nh ngha s magic cho s nh danh lnh l B trong bng m ascii l 66 thp phn*/ /*Phn nh ngha s nh danh thit b c t u mi chng trnh hoc bn trong mt <tp tin.h> th vin*/
#define IOC_GPIODEV_MAGIC 'B'

/*nh ngha lnh th nht tn GPIO_GET, vi m s lnh trong thit b l 10, ch truy xut l _IO*/
#define GPIO_GET #define GPIO_SET #define GPIO_CLEAR #define GPIO_DIR_IN #define GPIO_DIR_OUT _IO(IOC_GPIODEV_MAGIC, 10) _IO(IOC_GPIODEV_MAGIC, 11) _IO(IOC_GPIODEV_MAGIC, 12) _IO(IOC_GPIODEV_MAGIC, 13) _IO(IOC_GPIODEV_MAGIC, 14)

Cu trc nh ngha s nh danh lnh c dng:


<ch truy xut lnh>(<s magic thit b>, <s m lnh thit b>)

<ch truy xut lnh>: ioctl c 4 trng thi lnh: (Quy nh bi 2 bits

trng thi)
_IO lnh ioctl khng c tham s; _IOW lnh ioctl cha tham s dng nhn d liu t user (tng dng chc nng

ca hm copy_from_user());
_ IOR lnh ioctl cha tham s dng gi d liu sang user (tng ng chc

nng ca hm copy_to_user());
_IOWR lnh ioctl cha tham s dng cho hai nhim v, c v ghi d liu ca user.

ngha. -

<s magic thit b>: L s c trng cho tng thit b do ngi dng nh

<s m lnh thit b>: L s c trng cho tng lnh trong mi thit b.

Cn c vo s nh danh lnh ny, ngi lp trnh driver s la chn lnh no s c thc thi khi user gi hm ioctl. Cng vic la chn lnh c thc hin bng cu trc
switch...case... nh sau:

y l on chng trnh mu cho hm ioctl() c khai bo s dng trong driver


gpio_dev mang tn gpio_ioctl; static int ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

93

N TT NGHIP
gpio_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { int retval = 0;

/*Thc hin la chn lnh thc thi bng lnh switch vi tham s la chn l s nh danh lnh cmd*/
switch (cmd) { case GPIO_GET:

/*Hm thao tc cho lnh GPIO_GET*/


break; case GPIO_SET:

/*Hm thao tc cho lnh GPIO_SET*/


break; case GPIO_CLEAR:

/*Hm thao tc cho lnh GPIO_CLEAR*/


break; case GPIO_DIR_IN:

/*Hm thao tc cho lnh GPIO_DIR_IN*/


break; case GPIO_DIR_OUT:

/*Hm thao tc cho lnh GPIO_DIR_OUT*/


break; default:

/*Tr v m li trong trng hp khng c lnh thc thi ph hp*/


retval = -EINVAL; break; } return retval; }

unsigned long arg, l tham s lnh tng ng vi s nh danh lnh, tham s ny c vai tr l b nh m cha thng tin t user hay thng tin n user ty theo ch ca lnh c nh ngha u chng trnh driver. Trong trng hp lnh khng c tham s, chng ta khng cn thit phi s dng tham s ny trong user, chng trnh
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

94

N TT NGHIP trong ioctl vn thc thi m khng c li. Trong trng hp hm cn nhiu tham s, chng ta khai bo s dng tham s ny nh l mt con tr d liu. IV.Tng kt: Nh vy vi nhng giao din chnh trong character device nh read(), write() v
ioctl(), open(), ... chng ta c th giao tip gia user v kernel rt thun li. iu ny

cng c ngha rng: Gia ngi s dng v thit b vt l c th giao tip trao i thng tin vi nhau d dng thng qua hot ng ca driver vi s h tr ca giao din. Bn cnh nhng giao din trn, linux cn h tr rt nhiu giao din khc, ng dng ca nhng giao din ny khng nm trong cc driver c nghin cu trong gio trnh cho nn chng s khng c cp n. i vi nhng driver ln, s c rt nhiu giao din khc nhau xut hin, nhim v ca chng ta l tm hiu nguyn l hot ng ca giao din da vo nhng kin thc hc. y cng chnh l mc ch cui cng m nhm bin tp mun thc hin trong cun gio trnh ny. Trc khi bc vo vit mt driver hon chnh, chng ta s tm hiu cc cu trc vit mt driver n gin trong bi sau.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

95

N TT NGHIP BI 5

TRNH T VIT CHARACTER DEVICE DRIVER


Lp trnh driver l mt trong nhng cng vic quan trng m mt ngi lp trnh h thng nhng cn phi nm vng. mt chng trnh ng dng hot ng ti u, ngi lp trnh phi bit phn cng nhim v gia driver v application sao cho hp l. Trong mt ng dng iu khin, nu driver m trch nhiu chc nng th chng trnh trong application s tr nn n gin, nhng b li ti nguyn phn cng s d b xung t, khng thun li cho cc driver khc dng chung ti nguyn. Ngc li nu driver ch thc hin nhng cng vic rt n gin, th chng trnh trong application tr nn phc tp, vic chuyn qua li gia cc tin trnh tr nn kh khn. Vic phn chia nhim v ny i hi phi c nhiu kinh nghim lp trnh thc t vi h thng nhng mi c th em li hiu qu ti u cho h thng. Vi nhng kin thc tng qut trnh by trong nhng phn trc v driver m ch yu l character device driver, chng ta c nhng khi nim ban u v vai tr ca driver trong h thng nhng, cch thc iu khin thit b vt l, cc giao din giao tip thng tin gia user space v kernel space, ... trong phn ny chng ta s i vo cc bc c th vit hon chnh mt character device driver. Cng vic pht trin mt ng dng iu khin mi thng tin hnh theo nhng bc sau: Tm hiu nhu cu iu khin ngoi thc t: T hot ng thc tin hay n t hng xc nh yu cu, thi gian thc hin, gi c chi ph, ... Phn tch yu cu iu khin: T nhng yu cu gii hn v thi gian, chi ph, cht lng, ngi lp trnh tm ra phng php ti u ha h thng, la chn cng ngh ph hp, ...; Lp danh sch cc yu cu cn thc hin trong h thng iu khin; Phn cng nhim v iu khin gia application v driver h thng hot ng ti u; Lp trnh driver theo nhng yu cu c lp; Lp trnh application s dng driver hon tt chng trnh iu khin;
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

96

N TT NGHIP Chy kim tra tin cy h thng; Giao cho khch hnh s dng, bo tr s cha khc phc li khi thc thi; Chng ta ang tp trung nghin cu bc lp trnh driver, khi c nhng yu cu c th. Trong bc ny, c rt nhiu cch thc hin, tuy nhin nhn chung iu c nhng thao tc cn bn sau: 1. Vit lu hoc my trng thi thc thi cho dirver; 2. Lp trnh m lnh; 3. Bin dch driver; 4. Ci t vo h thng linux; 5. Vit chng trnh ng dng kim tra hot ng driver; 6. Nu t yu cu gn c nh vo cu trc kernel linux, bin dch li nhn driver hot ng lu di trong h thng; Nu khng tin hnh chnh sa, kim tra cho n khi hon thin; Trong cc bc 1, 5, 6 chng ta c dp nghin cu trong phn I lp trnh nhng cn bn hoc trong cc ti liu chuyn ngnh khc. Phn ny chng ta s tm hiu chi tit cc bc 2, 3, v 4; I. Lp trnh m lnh trong character driver: C rt nhiu cch vit character driver nhng cng ging nh chng trnh ng dng application, cng c nhng cu trc chung, chun, t s ty bin theo tng yu cu c th. y, chng ta s tm hiu hai dng cu trc: Cu trc dng 1, v cu trc dng 2; Cu trc dng 1: Bao gm nhng thao tc c bn nht, nhng a s nhng thao tc kim tra li, ly s nh danh lnh, s nh danh thit b, ... ngi lp trnh driver phi t mnh thc hin. C mt u im l ngi lp trnh c th ty bin theo yu cu ca ng dng, c kh nng pht trin driver. Nhng b li, thi gian thc hin hon chnh driver c th chy trong linux lu hn. Cu trc dng 2: Nhng thao tc c bn trong vic thnh lp cc thng s cho driver nh: Ly s nh danh lnh, thit b, khai bo ci t driver vo h thng, ... c gi gn trong mt cu lnh duy nht. u im l thi gian thc hin hon chnh mt driver nhanh hn, n gin hn, cc dch v kim tra li c h tr sn, gip trnh xy ra li trong qu trnh s dng. Th nhng vic ty bin ca ngi dng nm trong mt gii hn cho php.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

97

N TT NGHIP Thng thng chng ta nn dng cu trc dng 2 cho nhng driver n gin, v nhng kh nng trong cu trc ny hu ht cng tng t nh trong cu trc dng 1, cng cho chng ta thc hin tt c nhng thao tc iu khin khc nhau. Sau y chng ta s tm hiu chi tit tng cu trc c ci nhn c th hn v nhng u v nhc im nu trn. Cc chng trnh driver cng c cu trc tng t nh cc chng trnh trong C, ch khc l chng c thm nhng hm chun nh ngha ring cho vic giao tip iu khin gia user space v kernel space v cn nhiu c im khc na, s c chng ta cp trong mi phn cu trc; a. Cu trc chng trnh character device driver dng 1: /*Bc 1: Khai bo th vin cho cc hm dng trong chng trnh, th vin dng trong kernel space khc vi th vin dng trong user space. Th vin trong driver l nhng hm, bin, hng s, ... c nh ngha sn v hu ht c lu trong th mc linux/ trong cu trc m ngun ca linux. Do khi khai bo, chng ta phi ch r ng dn n th mc ny */
#include <linux/module.h> #include <linux/fs.h> #include <linux/cdev.h> #include <asm/uaccess.h> ......

//Th vin th nht trong th mc linux/

/*Bc 2: nh ngha nhng hng s cn dng trong chng trnh driver*/


#define ... ...

/*Bc 3: Khai bo s nh danh thit b (Device number); Cu trc (file structure); Cu trc (file operations); */
int struct cdev device_devno; //Khai bo bin lu s nh danh thit b device_cdev; //Khai bo bin lu cu trc tp tin device_fops; //Khai bo bin lu cu trc lnh

struct file_operations

/*Bc 4: Khai bo nhng bin, cu trc cn dng trong chng trnh driver*/
unsigned int variable_0;

//Nhng bin ny c nh ngha tng t //m lnh C, v C++ // 98

trong
unsigned long variable_1; struct clk *device_clock_0;

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

N TT NGHIP
....

/*Bc 5: Khai bo, nh ngha nhng hm con, chng trnh con c s dng trong driver*/ /*Chng trnh con th nht, c hai tham s parameter_0 v parameter_1 cng kiu int*/
void sub_program_0 (int parameter_0, int parameter_1) {

/*Nhng lnh thao tc cho chng trnh con*/


lnh_0; lnh_1; lnh_2; }

/*Hm th nht, tr v kiu int, hai tham s con tr parameter_0 v parameter_1 kiu int*/
int func_0 (int *parameter_0, int *parameter_1) {

/*Cc thao tc lnh cho hm*/


lnh_0; lnh_1; lnh_2; }

/*Bc 6: nh ngha hm init cho driver, hm init l hm c thc thi u tin khi thc hin ci t driver vo h thng linux bng lnh shell insmod driver_name.ko*/ /*Hm init c mt vai tr quan trng trong lp trnh driver. Ban u hm s gi thc thi cc hm xc nh s nh danh thit b; Cp nht cc thng s ca cu trc tp tin, cu trc lnh; ng k cc cu trc vo h thng linux; Khi to cc thng s iu khin ban u cho cc thit b ngoi vi m driver iu khin*/ /*Hm init c kiu d liu tr v dng int, static trong trng hp ny ngha l hm init chi dng ring cho driver s hu*/
static int __init at91adc_init (void) {

/*Khai bo bin lu gi tr tr v ca hm*/


int ret;

/*Xc nh s nh danh ng cho thit b, trnh trng hp b trng khi ci t vi cc driver thit b khc c trong h thng*/
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

99

N TT NGHIP
ret = alloc_chrdev_region ( &device_devno,//Ch n a ch bin lu s

//nh danh u tin tm c;


0, 1,

//S Minor u tin yu cu; //S thit b yu cu; //Tn thit b mun ng

device_name );

k; /*Kim tra m li khi thc thi hm alloc_chrdev_region()*/


if (ret < 0) {

//In thng bo li khi thc hin xc nh s nh danh thit b;


printk (KERN_INFO fail); ret = -ENODEV; //Tr v m li cho bin ret; return ret; //Tr v m li cho hm init; } Device_name: Device number allocate

/*Khi to thit b vi s nh danh xc nh, yu cu h thng dnh mt vng nh lu driver thit b sp c to ra;*/
cdev_init ( &device_cdev, device_devno, 1 );

//Tr n cu trc tp tin c nh ngha; //S nh danh thit b c xc nh; //S thit b mun ng k vo h thng;

/*Chp nht nhng thng tin cn thit cho cu trc tp tin va c h thng dnh ra*/
device_cdev.owner = THIS_MODULE; /*Cp nht ngi s hu cu trc tp

tin*/
device_cdev.ops = &device_fops; /*Cp nht cu trc lnh c nh

ngha*/ /*ng k thit b vo h thng */


ret = cdev_add ( &device_cdev, //Tr n cu trc tp tin c khi to; device_devno, //S nh danh thit b c xc nh; 1 ); //S thit b mun ng k;

/*Kim tra li trong qu trnh ng k thit b vo h thng*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

100

N TT NGHIP
if (ret < 0) {

//In thng bo khi li xut hin


printk(KERN_INFO "Device: Device number allocation failed\n"); ret = -ENODEV; //Tr v m li cho bin; return ret;//Tr v m li cho hm; }

/*Thc hin cc cng vic khi to thit b vt l do driver iu khin*/ ... //Tr v m li 0 khi qu trnh thc thi hm init khng c li;
return 0; }

/*Bc 7: Khai bo v nh ngha hm exit, hm exit l hm c thc hin ngay trc khi driver c tho g khi h thng bng lnh shell rmmod device.ko; Nhng tc v bn trong hm exit c lp trnh nhm khi phc li trng thi h thng trc khi ci t driver. Chng hn nh gii phng vng nh, timer, v hiu ha cc ngun pht sinh ngt, ...*/
static void __exit device_exit (void) {

/*Cc lnh gii phng vng nh s dng trong driver*/


...

/*Cc lnh gii phng ngun ngt, timer, ...*/


...

/*Tho thit b ra khi h thng bng hm*/


unregister_chrdev_region( device_devno, /*S nh danh u tin nhm

thit b;*/
1); //S thit b cn tho g;

/*In thng bo driver thit b c tho ra khi h thng*/


printk(KERN_INFO "device: Unloaded module\n"); }

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

101

N TT NGHIP /*Bc 8: Khai bo hm open, y l hm c thc thi ngay sau khi lnh open trong user space thc thi. Nhng lnh cha trong hm ny thng thng dng cp nht d liu ban u cho chng trnh driver, khi to mi trng hot ng ban u h thng lm vic n nh*/
static int device_open (struct inode *inode, struct file *filp) {

/*Ni lp trnh cc lnh khi to h thng*/


return 0; }

/*Bc 9: Khai bo v nh ngha hm release, y l hm c thc thi ngay trc khi driver b ng bi hm close trong user space*/
static int device_release (struct inode *inode, struct file *filp) {

/*Ni thc thi nhng lnh trc khi driver b ng, khng cn s dng*/
return 0; }

/*Bc 10: Khai bo cc hm read(), write(), ioctl() trong h thng khi cn s dng*/ /*Hm read() c thng tin t driver qua chng trnh trong user*/
static ssize_t device_read (struct file *filp, char __iomem *buf, size_t bufsize, loff_t *f_pos) {

/*nh ngha cc tc v hot ng trong hm read, truy cp ly thng tin t thit b vt l*/
... }

/*Hm write() ghi thng tin t user qua driver*/


static ssize_t device_write (struct file *filp, char __iomem *buf, size_t bufsize, loff_t *f_pos) {

/*nh ngha cc tc v hot ng trong hm write(), truy cp ly thng tin t chng trnh ng dng trong user*/
... } ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

102

N TT NGHIP

/*Hm ioctl nh ngha cc trng thi lnh thc thi theo s nh danh lnh t chng trnh ng dng bn user*/ static int
gpio_ioctl (struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) {

/*Khai bo bin lu m li tr v cho hm giao din ioctl()*/


int retval = 0;

/*Chia trng hp thc thi lnh*/


switch (cmd) { case LENH_0:

/*Lnh 0 c thc thi*/


break; case LENH_1:

/*Lnh 1 c thc thi*/


break; default:

/*C th thng bo, khng c lnh no thc thi*/


retval = -EINVAL; break; } return retval; }

/*Bc 11: Gn cc con tr hm giao din chun vo cu trc lnh file structure*/
struct file_operations gpio_fops = { .read .write .ioctl .open .release }; = device_read, = device_write, = device_ioctl, = device_open, = device_release,

/*Bc 12: Gn cc hm exit v init vo h thng driver*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

103

N TT NGHIP
module_init (device_init);

/*Hm device_init() thc hin khi driver c /*Hm device_exit() thc hin khi driver c

ci t*/
module_exit (device_exit);

g b*/ /*Bc 13: Khai bo cc thng tin lin quan n driver*/


MODULE_AUTHOR("Tn ngi vit driver"); MODULE_DESCRIPTION("M t nhim v ca driver"); MODULE_LICENSE("GPL"); //Bn quyn ca driver l GPL

b. Cu trc chng trnh character device driver dng 2: Cu trc chng trnh character device driver dng 2 cng tng t nh dng 1, nhng im khc bit l k thut to v ng k thit b mi vo h thng. thun tin cho vic tham kho chng ti khng ngi nhc li nhng bc tng t v gii thch nhng iu mi khi tip xc vi cu lnh. /*Bc 1: Khai bo nhng th vin cn thit cho cc lnh dng trong chng trnh driver*/
#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <asm/uaccess.h> #include <asm/atomic.h> #include <linux/miscdevice.h>

/*Bc 2: nh ngha nhng hng s cn dng trong chng trnh driver*/


#define ... ...

/*Bc 3: Khai bo s nh danh thit b, cc bin phc v ng b ha d liu*/ /*Bin lu s major ca thit b*/
static int dev_major;

/*Khai bo bin atomic_t dng ng b ha ti nguyn driver thit b*/ /*Cch ng b ha ti nguyn ca thit b: Trc khi m thao tc vi driver thit b, k thut atomic s kim tra xem thit b c m hay cha, nu thit b c m (nhn bit bng s counter) th khng cho

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

104

N TT NGHIP php truy cp n thit b ny, thng bo li cho ngi s dng. Ngc li, cho php m thit b, thc thi nhng cu lnh tip theo trong h thng. C th l: Ban u cho bin kiu atomic_t bng 1, ngha l thit b cha c m; Khi thit b c m, chng ta gim bin kiu atomic_t mt n v, lc ny gi tr bin kiu atomic_t bng 0. Trong qu trnh m, hay ng iu phi c s so snh bin atomic_t. Ch ng driver thit b khi bin kiu atomic_t bng 1. Ch m khi bin kiu atomic_t bng 0. ng thit b, thc hin tng bin kiu atomic_t. M thit b, thc hin gim bin kiu atomic_t.*/
static atomic_t device_open_cnt = ATOMIC_INIT(1);

/*Bc 4: Khai bo cc bin dng trong chng trnh driver*/


...

/*Bc 5: Khai bo v nh ngha cc hm, chng trnh con cn s dng trong qu trnh lp trnh driver*/
...

/*Bc 6: Khai bo v nh ngha hm open, l hm c thc thi khi thc hin lnh open() trong user application*/
static int device_open (struct inode *inode, struct file *file) {

/*Khai bo bin lu m li tr v*/


int result = 0;

/*Khai bo bin lu s minor ca thit b, ng thi cp nht s minor ca thit b trong h thng*/
unsigned int device_minor = MINOR (inode->i_rdev);

/*Thc hin kim tra bin atomic_t trong qu trnh m thit b nhiu ln*/
if (!atomic_dec_and_test(&device_open_cnt)) {

/*Tng bin kiu atomic_t*/


tomic_inc(&device_open_cnt);

/*In ra thng bo thit b mun m ang bn*/


printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor);

/*Tr v m li bn*/
return -EBUSY; ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

105

N TT NGHIP
}

/*Thc hin nhng cng vic tip theo nu m tp tin thit b thnh cng*/
...

/*Tr v m li cui cng nu qu trnh thc thi khng b li*/


return result; }

/*Bc 7: Khai bo v nh ngha hm close(), c thc hin khi thc thi hm close trong user application*/
static int device_close (struct inode *inode, struct file *file) {

/*Thc hin ng b ha counter trc khi tng*/


smp_mb_before_atomic_inc();

/*Tng bin m atomic khi ng tp tin thit b*/


atomic_inc(&device_open_cnt);

/*Tr v m li 0 cho hm close()*/


return 0; }

/*Bc 8: Khai bo v cp nht cu trc lnh file_operations cho thit b*/


struct file_operations device_fops = {

/*Gn hm device_read ca thit b vo giao din chun, nu s dng*/


.read = device_read,

/*Gn hm device_write ca thit b vo giao din chun, nu s dng*/


.write = device_write,

/*Gn hm device_open ca thit b vo giao din chun open*/


.open = device_open,

/*Gn hm device_release ca thit b vo giao din chun release*/


.release = device_release, };

/*Bc 9: Khai bo v cp nht cu trc tp tin thit b theo kiu miscdevice*/


static struct misdevice device_dev = {

/*Thc hin k thut ly s minor dng cho thit b bng hng s nh ngha sn trong th vin linux/miscdevice.h*/
.minor = MISC_DYNAMIC_MINOR,

/*Cp nht tn cho thit b*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

106

N TT NGHIP
.name = device,

/*Cp nht cu trc lnh c nh ngha*/


.fops = device_fops, };

/*Bc 10: Khai bo nh ngha hm init thc hin khi ci t driver vo h thng*/ /*Tng t nh trong dng 1, tuy nhin vi k thut mi ny, trong hm init chng ta khng cn phi ly s nh danh thit b, khi to vng nh cho driver, ci t driver vo h thng. Tt c nhng cng vic ny c thc hin bi mt hm duy nht l misc_register()*/
static int __init device_mod_init(void) {

/*Nhng lnh cn thc hin khi ci t driver vo h thng*/


...

/*Thc hin ng k driver vo h thng, kt hp tr v m li*/


return } misc_register(&devive_dev);

/*Bc 11: Khai bo v nh ngha hm exit()*/


static void __exit device_mod_exit (void) {

/*Thc hin nhng cng vic khi phc h thng trc khi driver b tho g*/
...

/*Tho g thit b mang tn l device_dev*/


misc_deregister (&device_dev); }

/*Bc 12: Gn cc hm exit v init vo h thng driver*/


module_init (device_mod_init); module_exit (device_mod_exit);

/*Bc 13: Cp nht cc thng tin c nhn cho driver*/


MODULE_LICENSE("Bn quyn driver thng thng l GPL"); MODULE_AUTHOR("Tn ngi vit driver"); MODULE_DESCRIPTION("M t khi qut thng tin v driver");

II. Bin dch driver:

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

107

N TT NGHIP Sau khi lp trnh dirver, cng vic tip theo l bin dch driver bin tp tin m ngun C thnh tp tin ngn ng my driver trc khi ci t vo h iu hnh. Sau y l cc bc bin dch driver. Bin dch driver c 2 dng, u tin bin dch driver khi tp tin m ngun driver thuc mt b phn trong cu trc m ngun m ca kernel, khi driver c bin dch cng lc vi kernel, cch ny ch p dng khi driver hot ng n nh, hn na chng ta khng cn ci t li driver khi khi ng li h thng. Phng php th hai l bin dch driver khi n nm ngoi cu trc m ngun m ca kernel, driver c th c bin dch trong khi kernel ang chy, u im ca phng php ny l thi gian thc hin nhanh, thch hp cho vic th nghim driver mi, th nhng mi ln h thng khi ng li, driver s b mt do phi ci t li khi khi ng. Khi driver hot ng n nh chng ta mi bin dch driver theo cch 1. Bin dch driver hon ton khc vi bin dch chng trnh ng dng. Chng trnh ng dng c nhng th vin chun trong h thng linux, nn khi bin dch ta ch vic chp tp tin chng trnh vo trong mt th mc bt k trong cu trc root file system v gi lnh bin dch. Nhng i vi driver, nhng th vin s dng khng nm sn trong h thng, m nm trong cu trc m ngun m ca kernel. V th trc khi bin dch driver chng ta phi gii nn tp tin m ngun m ca kernel vo cu trc root file system. Sau to tp tin Makefile dng lnh make trong shell bin dch driver. Cu trc Makefile c hng dn k trong phn lp trnh h thng nhng cn bn. Trong phn ny chng ta ch to ra Makefile vi ni dung cn thit c th bin dch c driver. Bin dch driver c tin hnh theo cc bc sau: 1. Chp tp tin driver m ngun C vo th mc no trong cu trc root file system. 2. To tp tin c tn Makefile nm trong cng th mc vi tp tin driver m ngun C. Tp tin Makefile c ni dung nh sau: /*Thng bo cho trnh bin dch bit loi chip m driver s ci t*/
export ARCH=arm

/*Khai bo chng trnh bin cho l nhng tp tin c tn u tin l armnone-linux-gnueabi-...*/


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

108

N TT NGHIP
export CROSS_COMPILE=arm-none-linux-gnueabi-

/*Ti y tp tin m ngun driver s c bin dch thnh tp tin .ko, c th ci t vo linux*/
obj-m += <tn tp tin driver m ngun C>.o

/*Ty chn all, thc hin chuyn n cu trc m ngun m ca kernel, ti y driver s c bin dch thng qua lnh modules */
all: make C <ng dn n th mc cha cu trc m ngun m ca kernel> M=$(PWD) modules

/*Ty chn clean, thc hin chuyn n cu trc m ngun m ca kernel, thc hin xa nhng tp tin .o, .ko c to thnh trong ln bin dch trc*/
clean: make -C / ng dn n th mc cha cu trc m ngun m ca kernel> M=$(PWD) clean

3. Ti th mc cha m ngun driver, dng lnh shell: make clean all Lc ny h thng linux s xa nhng tp tin c ui .o, .ko, ... to thnh trong nhng ln bin dch trc.Tip theo, bin dch tp tin m ngun driver thnh tp tin .ko, tp tin ny c th c ci dt vo h thng linux thng qua nhng thao tc s c hng dn trong phn sau. III. Ci t driver vo h thng linux: Trong phn I, chng ta trnh by hai cu trc chung vit hon chnh mt character device driver, mi cu trc iu c nhng u v nhc im ring. Nhng u v nhc im ny cn c biu hin r trong vic ci t driver vo h thng. Sau khi bin dch thnh cng driver, xut hin tp tin .ko trong th mc cha tp tin m ngun, chng ta dng nhng cu lnh trong shell hon tt cng on cui cng a driver vo hot ng trong h thng, tin hnh kim tra chc nng. Ty theo k thut p dng lp trnh driver m s c nhng thao tc ci t khc nhau: 1. Ci t driver khi p dng cu trc dng 1: Tin hnh theo cc bc sau: Di chuyn n th mc cha tp tin .ko va bin dch xong; Ti dng lnh shell, thc thi: insmod <tn driver>.ko; 109

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

N TT NGHIP Vo tp tin /proc/devices tm tn thit b va ci t vo h thng, xc nh s Major v s Minor ng ca thit b; S dng cu lnh trong shell: mknod /dev/<tn thit b> c <S Major>
<S Minor>, to inode trong th mc /dev/, lm tp tin thit b s dng cho nhng

chng trnh ng dng; 2. Ci t driver khi p dng cu trc dang 2: Di chuyn n th mc cha tp tin .ko va bin dch xong; Ti dng lnh shell, thc thi lnh: insmod <tn driver>.ko; Khi , cu trc inode t ng c to ra trong th mc /dev/ lin kt vi s nh danh thit b lu trong tp tin /proc/devices m khng cn phi thng qua nhng cu lnh shell khc nh trong cch 1. Nh vy, vi cu trc dng 2 thi gian ci t driver vo h thng c rt gn ng k. IV.Tng kt: T nhng kin thc l thuyt nn tng trong nhng bi trc, chng ta rt ra c nhng bc tng qut lp trnh hon chnh mt character device driver. C nhiu cch vit ra mt character driver, trong bi ny chi cp 2 cch cn bn lm nn tng cho cc bn nghin cu thm nhng cch khc hiu qu hn ngoi thc t. Trong bi sau, chng ta s thc hnh vit mt character device driver mang tn l helloworld. Driver ny s p dng tt c nhng k thut c hc. Nu cn thit, cc bn c th xem li l thuyt c trc khi qua bi sau nm c nhng vn ct li trong lp trnh driver.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

110

N TT NGHIP BI 6

HELLO WORLD DRIVER


I. M u: n y, chng ta c c nhng kin thc gn nh y t mnh vit mt character device driver. Cc bn bit th no l character driver, s nh danh lnh, s nh danh thit b, cu trc inode, file structure,...cng nh nhng lnh khi to v cp nht chng. Vi nhng yu cu ca tng lnh, chng ta rt ra c hai cu trc chung khi mun vit mt driver hon chnh, c tm hiu trong bi trc. Ty vo tng cu trc m c cc bc ci t driver khc nhau. Th nhng, chng ta ch mi dng li cc thao tc trn giy, cha thc s lp trnh ra c mt driver no. Trong bi ny, chng ta s vit mt d n c tn helloworld nhm mc ch thc t ha nhng thao tc lnh c trnh by trong phn driver. Vi mc ch l em nhng thao tc lnh c hc vo thc t chng trnh, d n ny bao gm c hai thnh phn cn hon thnh l driver v. Driver trong d n s p dng 3 giao din chnh dng trao i thng tin d liu v iu khin qua li gia hai lp user v kernel, l cc giao din hm read(), write() v ioctl() cng vi cc hm ng m driver nh open() hay close(). Chng trnh ng dng (Application) s p dng nhng hm v truy cp tp tin, ... truy xut nhng thng tin trong driver, hin th cho ngi dng. Ngoi ra, driver v application iu c nhim v xut thng tin c lin quan ngi lp trnh bit mi trng no ang thc thi. Theo nhng yu cu trn, u tin chng ta s phn cng tc v cho driver v application trong mc II sau lp trnh theo nhng tc v phn cng trong mc III. Ngi lp trnh s bin dch, ci t chng trnh vo h thng linux, thc thi v quan st kt qu. T gii thch rt ra nhn xt. II. Phn cng tc v gia driver v application: helloworld l mt d n bao qut tt c nhng k thut lp trnh driver c nghin cu trong nhng ni dung trc. Nhim v chnh l dng hm printf() v printk() xut thng tin ra mn hnh hin th theo mt quy lut ph hp, t ngi lp trnh c th hiu nguyn l hot ng ca tng hm s dng p dng vo trng hp khc. Driver v Application iu c nhim v ring, ty vo tng giao din s dng m yu cu
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

111

N TT NGHIP ca tng v d s khc nhau, sao cho tot ln c ngha ct li ca giao din hm. Sau y l chi tit tng yu cu ca d n helloworld. II.1. Driver: a. Giao din read(): Giao din read() c s dng chp thng tin t kernel space sang user space. Thng tin c lu trong driver l s khi to ban u khi driver c m cha trong mt bin cc b. Ti thi im gi giao din read(), thng tin ny s c chp qua user space, cha trong bin khai bo trong user application thng qua hm
copy_to_user().

Sau khi chp thng tin cho user, driver thng bo cho ngi lp trnh bit qu trnh chp thnh cng hay khng. b. Giao din write(): Giao din write() dng chp thng tin t user space qua kernel space. Thng tin t user l d liu kiu s do ngi dng nhp vo chuyn qua kernel thng qua giao din
write() lu vo mt bin trong kernel, bin ny cng l ni lu thng tin c chuyn

sang user khi giao din read() c gi. Sau khi nhn d liu t user, driver thng bo cho ngi lp trnh qu trnh chp thnh cng. Ngc li s tr v m li. c. Giao din ioctl():
ioctl() l mt giao din hm a chc nng, ngha l ch cn mt dng cu lnh m

c th thc hin c tt c nhng chc nng khc. th hin c nhng chc nng ny ca hm, chng ta lp trnh mt v d sau: Xy dng giao din ioctl() thnh mt hm ton hc, thc hin cc php ton cng, tr, nhn, chia. Cc tham s c truyn t user, sau khi tnh ton xong, kt qu c gi ngc li user. Cc php ton c la chn thng qua cc s nh danh lnh. II.2. Application: Chng trnh trong user, s dng k thut ty chn trong hm main() kim tra tt c nhng chc nng do chng trnh trong driver h tr. Mi chc nng s c thc hin do ngi s dng la chn. Trc khi i vo vit chng trnh c th, chng ta s tm hiu h iu hnh linux thc hin ty chn trong hm main() nh th no:
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

112

N TT NGHIP Hm main() l hm c thc hin u tin khi chng trnh ng dng c gi thc thi. T hm ny, ngi lp trnh s tin hnh tt c nhng chc nng nh to lp tin trnh, tuyn, gi cc chng trnh con, ... Thng thng hm main() c khai bo nh sau:
void main(void) { /*Cc lnh do ngi lp trnh nh ngha*/ }

Vi cch khai bo ny th hm main() khng c tham s cng nh khng c d liu tr v. Ngoi ra linux cn h tr cho ngi lp trnh cch khai bo hm main() khc c dng nh sau:
int main (int argc, char **argv) { /*Cc lnh do ngi lp trnh nh ngha*/ }

Vi cch lp trnh ny hm main() c th c ngi s dng cung cp cc tham s trong khi gi thc thi. C php cung cp tham s trong cu lnh shell nh sau:
./<tn chng trnh> <tham s 1> <tham s 2> <...> <tham s n>

Hm main() c hai tham s: Tham s th nht int argc l s int lu s lng tham s khai bo trong cu lnh shell trn, bao gm c tham s u tin l tn chng trnh cha hm main(). Tham s th hai char **argv l mng con tr lu ni dung tng tham s nhp trong cu lnh gi chng trnh thc thi trong shell; Nh vy tn chng trnh cha hm main() s thuc v tham s u tin c ni dung lu trong argv[0]. Tng t <tham s 1> l tham s th hai cha trong argv[1], ...Tng t cho cc tham s khc. Tng qut nu c n tham s trong cu lnh shell th trong hm main c: argc = n+1; argv[0], argv[1], argv[2], ..., argv[n] lu ni dung ca tng tham s. Trong chng trnh ng dng user application ca d n helloworld, hm main() c khai bo c dng ty chn nh trn. Khi ngi dng nhp: add, sub,
mul, div, read, write, th cu lnh tng ng s thc hin gi cc giao

din hm cn thit thc hin chc nng cng, tr , nhn, chia, c v ghi c lp trnh
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

113

N TT NGHIP trong dirver. Thao tc c th s c chng ti ch thch trong tng dng lnh ca dirver v application. III. Chng trnh driver v application: A. Chng trnh driver:
/*Chng trnh driver mang tn helloworld_dev.c*/ /*Khai bo cc th vin cn thit*/ #include <linux/module.h> /*dng cho cc cu trc module*/ #include <linux/errno.h> /*dng truy xut m li*/ #include <linux/init.h> /*dng cho cc macro module_init(), ...*/ #include <asm/uaccess.h>/*dng cho cc hm copy_to(from)_user*/ #include <asm/atomic.h>/*dng cho kim tra atomic*/ #include <linux/genhd.h> /*dng cho cc giao din hm*/ #include <linux/miscdevice.h>/*dng cho k thut to device t ng*/ /*Khai bo tn cho device v driver*/ #define DRVNAME #define DEVNAME "helloworld_dev" "helloworld" 'B' /*S type l s 66 trong m ascii*/

/*Khai bo s type cho s nh danh lnh dng trong ioctl() */ #define HELLOWORLD_DEV_MAGIC /*S nh danh lnh cho hm add*/ #define HELLOWORLD_ADD _IOWR(HELLOWORLD_DEV_MAGIC, 10,unsigned long) /*S nh danh lnh cho hm sub*/ #define HELLOWORLD_SUB _IOWR(HELLOWORLD_DEV_MAGIC, 11,unsigned long) /*S nh danh lnh cho hm mul*/ #define HELLOWORLD_MUL _IOWR(HELLOWORLD_DEV_MAGIC, 12,unsigned long) /*S nh danh lnh cho hm div*/ #define HELLOWORLD_DIV _IOWR(HELLOWORLD_DEV_MAGIC, 13,unsigned long) /*Bin lu gi tr truyn sang user space khi gi hm read() t user; hay lu gi tr nhn c t user khi hm write c gi*/ static char helloworld_dev_number = 34; /*Khai bo bin m atomic v khi to*/ static atomic_t helloworld_open_cnt = ATOMIC_INIT(1); /*Cu trc ioctl() thc hin cc php ton add, sub, mul v div*/ static int helloworld_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg[]) ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

114

N TT NGHIP
{ /*Bin lu m li tr v ca ioctl()*/ int retval; /*Phn bit cc trng hp lnh khc nhau*/ switch (cmd) { case HELLOWORLD_ADD: /*Thng bo qu trnh tnh ton bt u*/ printk ("Driver: Start ...\n"); /*Thc hin tnh ton, chp qua user qua bin arg[2]*/ arg[2] = arg[0] + arg [1]; /*In thng bo tnh ton kt thc*/ printk ("Driver: Calculating is complete\n"); break; case HELLOWORLD_SUB: /*Thng bo qu trnh tnh ton bt u*/ printk ("Driver: Start ...\n"); /*Thc hin tnh ton, chp qua user qua bin arg[2]*/ arg[2] = arg[0] - arg [1]; /*In thng bo tnh ton kt thc*/ printk ("Driver: Calculating is complete\n"); break; case HELLOWORLD_MUL: /*Thng bo qu trnh tnh ton bt u*/ printk ("Driver: Start ...\n"); /*Thc hin tnh ton, chp qua user qua bin arg[2]*/ arg[2] = arg[0] * arg [1]; /*In thng bo tnh ton kt thc*/ printk ("Driver: Calculating is complete\n"); break; case HELLOWORLD_DIV: /*Thng bo qu trnh tnh ton bt u*/ printk ("Driver: Start ...\n"); /*Thc hin tnh ton, chp qua user qua bin arg[2]*/ arg[2] = arg[0] / arg [1]; ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

115

N TT NGHIP
/*In thng bo tnh ton kt thc*/ printk ("Driver: Calculating is complete\n"); break; default: /*Thng bo li cho ngi s dng, khng c lnh h tr*/ printk ("Driver: I don't have this operation!\n"); retval = -EINVAL; break; } /*Tr v m li cho hm ioctl() */ return retval; } /*Khai bo v nh ngha hm giao din read*/ static ssize_t helloworld_read (struct file *filp, char __iomem buf[], size_t bufsize, loff_t *f_pos) { /*Khai bo con tr m d liu cn truyn qua user */ int *read_buf; /*Bin lu kch tht truyn thnh cng*/ int read_size = 0; /*Cp nht con tr m pht*/ read_buf = &helloworld_dev_number; /*Gi hm truyn d liu t con tr m pht sang user, kim tra m li nu ng tr v kch tht pht thnh cng*/ if (copy_to_user (buf, read_buf, bufsize) != 0 ) return -EFAULT; else read_size = bufsize; /*Thng bo s bytes truyn thnh cng qua user*/ printk ("Driver: Has sent %d byte(s) to user.\n", read_size); /*Tr v s byte d liu truyn thnh cng qua user*/ return read_size; } /*nh ngha giao din hm write()*/ static { /*Khai bo bin m nhn d liu t user*/ char write_buf[1]; ________________________________________________________________________________CH ssize_t helloworld_write (struct file *filp, char __iomem buf[], size_t bufsize, loff_t *f_pos)

NG II: LP TRNH NHNG NNG CAO

116

N TT NGHIP
/*Khai bo bin lu kch thc nhn thnh cng*/ int write_size = 0; /*Gi hm ly d liu t user, c kim tra li, ng s tr v s byte d liu nhn thnh cng*/ if (copy_from_user (write_buf, buf, bufsize) != 0) return EFAULT; else write_size = bufsize; /*Cp nht thng tin cho ln c tip theo*/ helloworld_dev_number = write_buf[0]; /*In ra thng bo s byte d liu nhn thnh cng t user*/ printk ("Driver: Has received %d byte(s) from user.\n", write_size); /*Tr v s byte nhn thnh cng cho hm write()*/ return write_size; }

/*Khai bo giao din open()*/ static int helloworld_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&helloworld_open_cnt)) { atomic_inc(&helloworld_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; } /*Khai bo giao din hm close*/ static int helloworld_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&helloworld_open_cnt); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

117

N TT NGHIP
return 0; } /*Gn cc giao din hm vo cu trc file operation*/ struct file_operations helloworld_fops = { .ioctl .read .write .open .release }; /*Gn cu trc file operation vo inode, cp nht tn thit b, hin th trong inode*/ static struct miscdevice helloworld_dev = { .minor .name .fops }; /*Khai bo v nh ngha hm thc hin lc cai t driver*/ static int __init helloworld_mod_init(void) { return misc_register(&helloworld_dev); } /*Khai bo nh ngha hm thc thi lc tho g driver khi h thng*/ static void __exit helloworld_mod_exit(void) { misc_deregister(&helloworld_dev); } /*Gn hm nh ngha vo macro init v exit module*/ module_init (helloworld_mod_init); module_exit (helloworld_mod_exit); /*Cp nht thng tin ca driver, quyn s hu, tn ngi vit chng trnh*/ MODULE_LICENSE("GPL"); MODULE_AUTHOR("coolwarmboy"); MODULE_DESCRIPTION("Character device for helloworld"); ________________________________________________________________________________CH = MISC_DYNAMIC_MINOR, = "helloworld", = &helloworld_fops, = helloworld_ioctl, = helloworld_read, = helloworld_write, = helloworld_open, = helloworld_close,

NG II: LP TRNH NHNG NNG CAO

118

N TT NGHIP B. Chng trnh application:


/*Chng trnh application mang tn helloworld_app.c*/ /*Khai bo cc th vin cn thit cho cc hm s dng trong chng trnh*/ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h> /*nh ngha cc s nh danh lnh cho giao din ioctl, cc s nh ngha ny ging nh trong driver*/ #define HELLOWORLD_DEV_MAGIC 'B' /*S nh danh lnh dng cho lnh add*/ #define HELLOWORLD_ADD _IOWR(HELLOWORLD_DEV_MAGIC, 10, unsigned long) /*S nh danh lnh dng cho lnh sub*/ #define HELLOWORLD_SUB _IOWR(HELLOWORLD_DEV_MAGIC, 11, unsigned long) /*S nh danh lnh dng cho lnh mul*/ #define HELLOWORLD_MUL _IOWR(HELLOWORLD_DEV_MAGIC, 12, unsigned long) /*S nh danh lnh dng cho lnh div*/ #define HELLOWORLD_DIV _IOWR(HELLOWORLD_DEV_MAGIC, 13, unsigned long) /*Chng trnh con in ra hng dn cho ngi dng*/ void print_usage() { printf("helloworld_app (arg_2)\n"); exit(0); } /*Hm main thc thi khi khi chng trnh c gi t shell, main khai bo theo dng ty chn tham s*/ int main(int argc, char **argv) { /*Bin lu s file descripition ca driver khi c m*/ int fd; /*Bin lu m li tr v cho hm main*/ int ret = 0; ________________________________________________________________________________CH add|sub|mul|div|read|write arg_1

NG II: LP TRNH NHNG NNG CAO

119

N TT NGHIP
/*B m d liu nhn c t driver*/ char read_buf[1]; /*B m d liu cn truyn sang driver*/ char write_buf[1]; /*B m d liu 2 chiu dng trong hm giao din ioctl()*/ unsigned long arg[3]; /*u tin m driver cn tng tc, quy nh ch truy xut driver l c v ghi*/ if ((fd = open("/dev/helloworld", O_RDWR)) < 0) { /*Nu c li trong qu trnh m thit b, in ra thng bo cho ngi dng*/ printf("Error whilst opening /dev/helloworld\n"); /*Tr v m li cho hm main*/ return fd; } /*Lit k cc trng hp c th xy ra khi giao tip vi ngi dng*/ if (argc == 4) { /*Trong trng hp l cc hm ton hc, dng ioctl, kim tra cc php ton v thc hin tnh ton*/ /*Trong trng hp l php ton cng*/ if (!strcmp(argv[1],"add")) { arg[0] = atoi(argv[2]); arg[1] = atoi(argv[3]); ioctl (fd, HELLOWORLD_ADD, arg); printf ("User: %ld + %ld = %ld\n", arg[0], arg[1], arg[2]); } /*Trong trng hp l php tr*/ else if (!strcmp(argv[1],"sub")) { arg[0] = atoi(argv[2]); arg[1] = atoi(argv[3]); ioctl (fd, HELLOWORLD_SUB, arg); printf ("User: %ld - %ld = %ld\n", arg[0], arg[1], arg[2]); } ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

120

N TT NGHIP
/*Trong trng hp l php nhn*/ else if (!strcmp(argv[1],"mul")) { arg[0] = atoi(argv[2]); arg[1] = atoi(argv[3]); ioctl (fd, HELLOWORLD_MUL, arg); printf ("User: %ld x %ld = %ld\n", arg[0], arg[1], arg[2]); } /*Trong trng hp l php chia*/ else if (!strcmp(argv[1],"div")) { arg[0] = atoi(argv[2]); arg[1] = atoi(argv[3]); ioctl (fd, HELLOWORLD_DIV, arg); printf ("User: %ld / %ld = %ld\n", arg[0], arg[1], arg[2]); } /*Trong trng hp khng c lnh h tr, in ra hng dn cho ngi dng*/ else { print_usage(); } } /*Trong trng hp l lnh chp thng tin sang driver*/ else if (argc == 3) { if (!strcmp(argv[1],"write")) { write_buf[0] = atoi(argv[2]); printf ("User: has just sent number: %d\n", write_buf[0]); write(fd, write_buf, 1); } else { print_usage(); } } /*Trong trng hp lnh c thng tin t driver*/ else if (argc == 2) { if (!strcmp(argv[1],"read")) { read(fd, read_buf, 1); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

121

N TT NGHIP
printf } else { print_usage(); } } /*In ra hng dn cho ngi dng trong trng hp khng c lnh no h tr*/ else { print_usage(); } } ("User: has just received number: %d\n",

read_buf[0]);

Bin dch chng trnh driver: Khi to bin mi trng thm vo ng dn n th mc cha cng c h tr bin dch; To tp tin c tn Makefile trong th mc cha chng trnh driver nh sau:

export ARCH=arm export CROSS_COMPILE=arm-none-linux-gnueabiobj-m += helloworld_dev.o all: #Ty thuc vo ni cha cu trc m ngun kernel m chn ng #dn ph hp cho lnh make all make -C /home/arm/project/kernel/linux-2.6.30 M=$(PWD) modules clean: #Ty thuc vo v tr cha cu trc m ngun kernel m chn ng #dn cho ph hp vi lnh make clean make -C /home/arm/project/kernel/linux-2.6.30 M=$(PWD) clean -

Tr n th mc cha driver thc thi lnh shell: make clean all lc ny tp tin
helloworld_dev.c s c bin dch thnh helloworld_dev.ko;

Chp tp tin helloworld.ko vo kit nhng cn ci t; Ci t driver vo h thng linux bng lnh shell: insmod helloworld_dev.ko;

Bin dch chng trnh application: Thc hin theo cc bc sau:


________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

122

N TT NGHIP Ci t bin mi trng tr vo ni cha cng c h tr bin dch, (Nu lm trong khi bin dch driver th khng cn lm bc ny); Trong th mc cha m ngun chng trnh helloworld_app.c thc thi lnh shell:
arm-none-linux-gnueabi-gcc helloworld_app.c o helloworld_app

Lc ny tp tin helloworld_app s c to thnh nu chng trnh


helloworld_app.c khng c li.

Chp tp tin helloworld_app bin dch vo kit; Thc thi chng trnh kim tra hot ng ca driver lp trnh; Sau y l kt qu thc thi chng trnh trong tng trng hp: Trng hp 1: Kim tra hot ng ca php ton add trong driver;
./helloworld_app add 100 50 Driver: Start ... Driver: Calculating is complete User: 100 + 50 = 150

Chng ta thy driver hot ng ng chc nng ca mnh. Khi chng trnh c gi thc thi, n gi hm ioctl thc hin truyn hai tham s, kt qu c tnh ton trong driver khi tnh ton xong, n gi d liu qua user. Cui cng, user xut d liu tnh ton nhn c t driver ra ngoi mn hnh. Tng t cho cc php ton khc nh sau: Trng hp 2: Kim tra hot ng ca php ton sub trong driver;
./helloworld_app sub 100 50 Driver: Start ... Driver: Calculating is complete User: 100 - 50 = 50

Trng hp 3: Kim tra hot ng ca php ton mul trong driver;


./helloworld_app mul 100 50 Driver: Start ... Driver: Calculating is complete User: 100 x 50 = 5000

Trng hp 3: Kim tra hot ng ca php ton div trong driver;


./helloworld_app div 100 50 Driver: Start ... Driver: Calculating is complete ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

123

N TT NGHIP
User: 100 / 50 = 2

Trng hp 5: Kim tra c d liu t driver;


./helloworld_app read Driver: Has sent 1 byte(s) to user. User: has just receive number: 34

Khi chng trnh application c gi thc thi, vi trng hp lnh read, hm read c gi thc thi yu cu d liu t driver, driver truyn mt s lu trong vng nh ca mnh cho user application. User application nhn c thng tin, thng bo cho ngi dng. Trng hp 6: Kim tra ghi d liu vo driver thng qua hm write:
./helloworld_app write 100 User:Driver: Has received 1 byte(s) from user has just sent number: 100

C mt vn ny sinh l, mc d thng tin c chuyn qua driver thnh cng nhng kt qu in ra xy ra mt li nh v th t in ca nhng dng thng tin. Nguyn nhn l trong khi user in thng bo, driver nhn c d liu v xut ra thng bo ca mnh. V th sau khi driver in xong thng bo, user mi tip tc thc hin nhim v ca mnh. Nh th chng ta cn phi ch n vn ng b d liu gia driver v application trnh trng hp ny xy ra. IV.Tng kt: Nh vy chng ta hon thnh cng vic vit hon chnh mt driver n gin da vo cc bc mu trong bi hc trc. Cc bn cng hiu nguyn l hot ng ca hm main c tham s, cch la chn tham s hot ng trong tng trng hp c th theo yu cu. Vi nhng thao tc trn, cc bn c th t mnh vit nhng dirver n gin trong x l tnh ton, xut nhp thng bo, ... Th nhng, trong thc t, driver khng phi ch dng trong vic truy xut nhng k t thng bo. Nhim v chnh ca n l iu khin cc thit b phn cng thng qua cc hm giao tip vi cc cng vo ra, truy xut thanh ghi lnh, d liu, ...ca thit b, thu thp thng tin lu vo vng nh m trong driver ch chng trnh trong user truy xut. c th giao tip vi cc thit b phn cng thng
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

124

N TT NGHIP qua cc cng vo ra, trong bi sau chng ta s nghin cu cc hm giao tip gpio do linux h tr sn.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

125

N TT NGHIP BI 7

CC HM H TR GPIO
I. Tng quan v GPIO: GPIO, vit tt ca cm t General Purpose Input/Output, l mt th vin phn mm iu khin cc cng vo ra tch hp trn vi iu khin hay cc ngoi vi IO lin kt vi vi iu khin . Hu ht cc vi iu khin iu h tr th vin ny, gip cho vic lp trnh cc cng vo ra tr nn thun tin hn. Cc tp lnh vo ra v iu khin, cch quy nh s chn, ... hu ht tng t nhau so vi cc loi vi khin khc nhau. iu ny lm tng tnh linh hot, gim thi gian xy dng h thng. Theo nh quy nh chun, mi mt chn IO trn vi iu khin s tng ng vi mt s GPIO ca th vin ny. S GPIO c quy nh nh sau: i vi vi iu khin ARM9260, s cng vo ra l 3x32 cng, tng ng vi 3 ports, l cc Port A, Port B, v Port C. Mi chn quy nh trong GPIO theo quy lut sau: BASEx32+PIN; Trong BASE l s c s ca Port. Port A c c s l 1, Port B l 2, Port C l 3. PIN l s th t ca tng chn trong Port. Chn 0 c gi tr PIN l 32, 1 l 33, ... V d, chn th 2 ca Port A c s GPIO l 33; Chn th 2 ca Port B c s GPIO l 65, ... tng t cho cc chn cn li trn vi iu khin. i vi cc vi iu khin khc c s Port ln hn ta ch vic tun theo quy lut trn tm s GPIO ph hp. GPIO cho cc loi vi iu khin khc nhau iu c chung nhng tnh cht: Mi chn trong GPIO iu c th c hai ch input v output, ty vo loi vi iu khin m GPIO ang s dng. Trong ch input, cc chn GPIO c th lp trnh tr thnh ngun ngt h thng. V nhiu chc nng khc na, trong quyn sch ny chng ta ch tm hiu nhng chc nng ph bin nht phc v giao tip vi cc chn IO trong cc chng trnh ng dng. Mt trong nhng thao tc u tin a GPIO hot ng trong h thng l xc nh GPIO cn dng bng hm:
gpio_request(); //Yu cu truy xut chn GPIO ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

126

N TT NGHIP Tip n, chng ta cu hnh chn GPIO l ng vo hay ng ra bng hai hm:
int gpio_direction_input(unsigned gpio); int gpio_direction_output(unsigned gpio, int value);

Cng vic cui cng l a d liu n chn GPIO, nu l ng ra; hoc c d liu t chn GPIO, nu l ng vo; ta s dng hai hm sau:
int gpio_get_value(unsigned gpio); //c d liu; void gpio_set_value(unsigned gpio, int value); //Xut d liu;

Ngoi ra cn c nhiu hm chc nng khc s c trnh by trong mc sau. **C nhiu cch thao tc vi gpio. Hoc thao tc vi giao din thit b trong cu trc root file system (y l nhng dirver c lp trnh sn), vic iu khin s l thao tc vi tp tin v th mc (lp trnh trong user application). Hoc dng trc tip nhng lnh trong m ngun kernel, ngha l ngi s dng to ring cho mnh mt driver s dng trc tip cc hm giao tip vi gpio sau mi vit chng trnh ng dng iu khin IO theo nhng giao din trong driver h tr. Nhm mc ch thun tin cho vic iu khin IO, phn lp trnh nhng nng cao ch trnh bay cch th hai, iu khin trc tip IO thng qua th vin gpio.h trong kernel. II. Cc hm chnh trong GPIO: 1. Hm gpio_is_valid(): C php hm nh sau:
#include <linux/gpio.h> int gpio_is_valid (int number);

Do th vin gpio dng chung cho nhiu loi vi iu khin khc nhau, nn s lng chn IO ca tng loi cng khc nhau. Cn thit phi cung cp mt hm kim tra s tn ti ca chn trong h thng. Hm gpio_is_valid() lm nhim v ny. Hm c tham s l int number l s chn gpio mun kim tra. Hm tr v gi tr 0 nu s chn gpio cung cp l hp l, ngha l chn gpio ny tn ti trong h thng m gpio ang h tr. Ngc li, nu chn gpio khng hp l, hm tr v m li m EINVAL. V d, nu mun kim tra chn gpio 32 hp l hay khng, ta dng on m lnh sau: /*Khai bo bin lu m li tr v*/
int ret;

/*Gi hm kim tra gpio*/


ret = gpio_is_valid(32); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

127

N TT NGHIP /*Kim tra m li tr v h thng*/


if (ret < 0) {

/*Nu xy ra li, in thng bo cho ngi dng*/


printk (This gpio pin is not valid\n);

/*Tr v m li cho hm gi*/


return ret; }

Cng vic kim tra c thc hin u tin khi mun thao tc vi mt chn no trong gpio. Nu hp l cc lnh tip theo s c thc hin. Ngc li, in ra thng bo cho ngi dng v thot ra khi driver. 2. Hm gpio_request(): C php ca hm ny nh sau:
#include <linux/gpio.h> int gpio_request ( unsigned gpio, const char *lable);

Sau khi kim tra tnh hp l ca chn gpio, cng vic tip theo l khai bo s dng chn gpio . Linux kernel cung cp cho chng ta hm gpio_request() thc hin cng vic ny. Hm gpio_request c hai tham s. Tham s th nht unsigned gpio l chn gpio mun khai bo s dng; Tham s th hai const char *lable l tn mun t cho gpio, phc v cho qu trnh thao tc vi chn gpio d dng hn. Tham s ny c th trng bng cch dng hng s rng NULL. Sau y l on chng trnh mu minh ha cch s dng hm gpio_request(): /*Nhng on lnh trc*/
...

/*Khai bo bin lu v m li cho hm gi*/


int ret;

/*Gi hm gpio_request (), yu cu s dng chn gpio 32 vi tn l EXPL*/


ret = gpio_request (32, EXPL);

/*Kim tra m li tr v*/


if (ret) {

/*Nu xy ra li th in ra thng bo cho ngi s dng*/


printk (KERN_WARNING EXPL: unable to request gpio 32); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

128

N TT NGHIP /*Tr v m li cho hm gi*/


return ret; }

/*Nu khng c li, thc thi nhng on lnh khc*/


...

3. Hm gpio_free(): C php ca hm ny nh sau:


#include <linux/gpio.h> void gpio_free (unsigned gpio);

Hm gpio_free() c chc nng ngc li vi hm gpio_request(). Hm


gpio_free() dng gii phng chn gpio no khng cn s dng cho h thng. Hm

ny ch c mt tham s tr v unsigned gpio l s gpio ca chn mun gii phng. Hm khng c d liu tr v. Sau dy l on chng trnh v d cch s dng hm gpio_free: /*on chng trnh gii phng chn gpio 32 ra khi driver*/
gpio_free(32);

4. Hm gpio_direction_input(): C php ca hm ny nh sau:


#include <linux/gpio.h> int gpio_direction_input (unsigned gpio);

Hm gpio_direction_input dng ci t ch giao tip cho chn gpio l input. Ngha l chn gpio ny s nhn d liu t bn ngoi lu vo vng nh m bn trong. Hm gpio_direction_input c tham s unsigned gpio l chn gpio mun ci t ch input. Hm tr v gi tr 0 nu qu trnh ci t thnh cng. Ngc li, s tr v m li m. Sau y l mt v d cho hm gpio_direction_input(): /*Hm ci t chn gpio 32 ch ng vo*/ /*Khai bo bin lu gi tr m li tr v cho hm gi*/
int ret;

/*Ci t chn 32 ch ng vo*/


ret = gpio_direction_input (32); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

129

N TT NGHIP /*Kim tra li thc thi */


if (ret) {

/*Nu c li in ra thng bo cho ngi dng*/


printk (KERN_WARNING Unable to set input mode);

/*Tr v m li cho hm gi*/


return ret; } ...

5. Hm gpio_direction_output(): C php ca hm ny nh sau:


#include <linux/gpio.h> int gpio_direction_output (unsigned gpio, int value);

Hm gpio_direction_output dng ci t ch giao tip cho chn gpio l output. Chn gpio s lm nhim v xut d liu bn trong chng trnh ra ngoi. Hm
gpio_direction_output() c hai tham s. Tham s th nht, unsigned gpio, l chn

gpio mun ci t. Tham s th hai, int value, l gi tr ban u ca gpio khi n l ng ra. Hm tr v gi tr 0 nu qu trnh ci t thnh cng. Ngc li, s tr v m li m. Sau y l mt v d cho hm gpio_direction_output(): /*Hm ci t chn gpio 32 ch ng ra, gi tr ban u l 1*/ /*Khai bo bin lu gi tr m li tr v cho hm gi*/
int ret;

/*Ci t chn 32 ch ng vo*/


ret = gpio_direction_output (32, 1);

/*Kim tra li thc thi */


if (ret) {

/*Nu c li in ra thng bo cho ngi dng*/


printk (KERN_WARNING Unable to set gpio 32 into output mode);

/*Tr v m li cho hm gi*/


return ret; } ...

6. Hm gpio_get_value():
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

130

N TT NGHIP C php ca hm ny nh sau:


#include <linux/gpio.h> int gpio_get_value (unsigned gpio);

Khi chn unsigned gpio l ng vo, hm gpio_get_value() s ly gi tr tn hiu ca chn ny. Hm c gi tr tr v dng int, bng 0 nu ng vo mc thp, khc 0 nu ng vo mc cao. Sau y l mt v d c vo gi tr chn gpio 32, kim tra v in thng tin ra mn hnh: ...
if (gpio_get_value(32)) { printk (The input is high value\n); } else { printk (The input is low value\n); }

... 7. Hm gpio_set_value(): C php ca hm ny nh sau:


#include <linux/gpio.h> void gpio_set_value (unsigned gpio, int value);

Ngc li vi hm gpio_get_value(), hm gpio_set_value() c chc nng xut d liu cho mt chn unsigned gpio ng ra. Vi d liu cha trong tham s int
value. Bng 0 nu mun xut ra mc thp, bng 1 nu mun xut ra mc cao. Hm gpio_set_value() khng c d liu tr v.

Sau y l mt v d xut mc cao ra chn gpio 32: /*Cc lnh khi to gpio 32 l ng ra*/
...

/*Xut mc cao ra chn gpio 32 */


gpio_set_value (32, 1);

/*Cc lnh x l tip theo*/


...

8. Hm gpio_to_irq(): C php ca hm ny nh sau:


#include <linux/gpio.h> ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

131

N TT NGHIP
int gpio_to_irq (unsigned gpio);

i khi chng ta mun ci t ch d ngt cho mt chn no trong gpio dng thu nhn thng tin ng b t phn cng. Hm gpio_to_irq() thc hin chc nng ny. Hm c tham s unsigned gpio l chn gpio mun ci t ch ngt. Hm c gi tr tr v l s IRQ nu qu trnh ci t ch ngt thnh cng. Ngc li s tr v m li m. S IRQ c s dng cho hm request_irq() khi to ngt cho h thng, hm s gn s IRQ vi hm x l ngt. Hm ny s thc hin nhng thao tc do ngi lp trnh quy nh khi xut hin ngt t tn hiu ngt c s nh danh ngt l IRQ. Bn cnh hm request_irq() cn quy nh ch ngt cho chn gpio l ngt theo cnh hay ngt theo mc, ... Sau y l on chng trnh v d khi to ngt t chn gpio. /*on chng trnh khi to ngt cho chn gpio 70, PC6*/ /*Khai bo bin lu m li tr v hm gi*/
int ret;

/*Yu cu chn gpio, vi nh danh l IRQ*/


ret = gpio_request (70, "IRQ");

/*Kim tra m li tr v*/


if (ret) {

/*Thng bo cho ngi lp trnh c li xy ra*/


printk (KERN_ALERT "Unable to request PC6\n"); }

/*Ci t ch ko ln cho chn gpio*/


at91_set_GPIO_periph (70, 1);

/*Ci t chn gpio l input*/


at91_set_gpio_input (70, 1);

/*Ci t chn gpio c ch chng li*/


at91_set_deglitch (70, 1);

/*Ci t gpio thnh ngun ngt, lu v s nh danh ngt irq*/


irq = gpio_to_irq (70);

/* Get IRQ number */

/*Thng bo chn gpio khi to ngt */


printk (KERN_ALERT "IRQ = %d\n", irq); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

132

N TT NGHIP /*Khai bo ngt chn gpio cho h thng*/


ret = request_irq (irq, gpio_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "MyIRQ", NULL);

/*Kim tra m li tr v khi khai bo ngt*/


if (ret) {

/*Thng bo cho ngi s dng s nh danh ngt khng cn trng*/


printk (KERN_ALERT "IRQ %d is not free\n", irq);

/*Tr v m li cho hm gi */
return ret; }

Nh vy trnh li trong qu trnh khi to ngt cho chn gpio, trc tin chng ta phi ci t nhng thng s cn thit cho gpio , chng hn nh chn gpio phi hp l v ch ng vo. III. Kt lun: Trn y, chng ta s dng c nhng hm iu khin cc chn gpio ngoi vi thc hin chc nng c th ca yu cu ng dng. Kt hp vi nhng kin thc trong nhng bi trc: Giao din iu khin lin kt user space vi kernel space, cc hm tr hon thi gian trong user space, cc k thut lp trnh C, ... chng ta c th vit c hu ht tt c nhng ng dng c lin quan n cc cng vo ra: chng hn nh iu khin LED, iu khin LCD, ... gpio khng ch iu khin cc cng vo ra trn vi iu khin, theo yu cu trong thc t, a s cc kit nhng, s cng vo ra rt hn ch, i hi phi c cc chn io m rng t nhng linh kin ph tr khc, v th gpio cn h tr thm cc hm iu khin cc chn io m rng. Vn ny s c cp trong nhng ti liu khc khng thuc phm vi ca gio trnh ny. Trc khi di vo ng dng cc hm thao tc vi gpio trong iu khin LED n, LCD, ... bi tip theo s tm hiu thm v cch tr hon thi gian trong kernel, vi cch tr hon thi gian ny, chng ta khng cn dng n cc hm tr hon khc trong user space v l do yu cu ng b ha phn cng h thng, hay mt s trng hp chng ta mun s dng delay trong driver gn lin vi nhng thao tc iu khin.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

133

N TT NGHIP BI 7

CC HM H TR GPIO
I. S lc v thi gian trong kernel: Thi gian trong h iu hnh linux ni ring v cc h iu hnh khc ni chung iu rt quan trng. Trong h iu hnh, nhng hot ng iu da theo s tc ng mang tnh cht chu k. Chng hn nh hot ng chia khe thi gian thc thi, chuyn qua li gia cc tin trnh vi nhau, ng b ha hot ng gia cc thit b phn cng c thi gian truy xut khng ging nhau, v nhiu hot ng quan trng khc na. Khi lm vic vi h thng linux, chng ta cn phn bit hai khi nim thi gian: Thi gian tuyt i v thi gian tng i. Thi gian tuyt i c hiu nh thi gian thc ca h thng, l cc thng tin nh ngy-thng-nm-gi-pht-giy v cc n v thi gian khc nh hn, phc v cho ngi s dng. Thi gian tng i c hiu nh nhng khong thi gian c cp nht khng c nh, mang tnh cht chu k, mc thi gian khng c nh v thng thng khng bit trc. V d thi gian tuyt i l thi im trong mt ngy, c mc thi gian tnh t ngy 1 thng 1 nm 1970 quy nh trong cc thit b thi gian thc. Thi gian tng i l khong thi gian tnh t thi im xy ra mt s kin no , chng hn nh thi tc ng mt khong thi gian sau khi h thng c li hoc cp nht thng s hin ti ca h thng sau mi mt thi khong c nh. c th kim tra, qun l v thao tc vi thi gian mt cch chnh xc, h iu hnh phi da vo thit b thi gian c tch hp trn hu ht cc vi x l l timer. Timer c s dng bi h iu hnh c gi l timer h thng, h iu hnh ci t cc thng s thch hp cho timer, quy nh khong thi gian sinh ra ngt, khong thi gian gia hai ln xy ra ngt lin tip c gi bi thut ng tick, gi tr ca tick do ngi s dng driver quy nh. Khi xy ra ngt, h iu hnh linux s cp nht gi tr ca bin jiffies, chuyn tin trnh, cp nht thi gian trong ngy, ... Trong phn lp trnh user application, chng ta tm hiu nhng hm thao tc vi thi gian user space. y l nhng hm c h tr sn bi h iu hnh, ngha l chng c lp trnh hot ng n nh khng gy nh hng n cc tin trnh khc chy ng thi. Trong kernel, nhng hm thao tc vi thi gian hot ng bn ngoi tm kim sot ca h iu hnh, s dng trc tip ti nguyn phn cng ca h thng, c th l thi
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

134

N TT NGHIP gian hot ng ca vi x l trung tm trong vi iu khin. V th nu s dng khng ph hp th h iu hnh s hot ng khng n nh, xy ra nhng li v thi gian thc trong khi thc hin tc v. Nhng thi gian thc hin ca cc hm ny s nhanh hn, v khng qua trung gian l h iu hnh, ph hp vi yu cu iu khin ca driver l nhanh chng v chnh xc. Trong bi ny, u tin chng ta s tm hiu nguyn tc qun l thi gian trong kernel, sau l cc hm tng tc, x l thi gian thc, cch s dng nh thi trong timer, v cui cng l mt s k thut tr hon thi gian trong kernel. II. n v thi gian trong kernel: qun l chnh xc thi gian, h iu hnh s dng b nh thi timer tch hp sn trn vi iu khin m n hot ng. B nh thi (timer) c t cho mt gi tr c nh sao cho c th sinh ra ngt theo chu k cho trc. Khong thi gian ca mt chu k ngt c gi l tick. Trong mt giy c khong N ticks c hon thnh. Hay ni cch khc, tc tick l N Hz. Gi tr N c nh ngha bi ngi s dng trc khi bin dch kernel. Thng thng mt s h iu hnh c gi tr mc nh l N = 100 v y cng l gi tr mc nh ca h iu hnh chy trn kit KM9260. Gi tr ca HZ c nh ngha nh sau:
# define USER_HZ 100 /* User interfaces are in "ticks" */

v
# define HZ 100 /*Internal kernel timer frequency*/

trong tp tin \arch\arm\include\asm\param.h. Chng ta thy, gi tr mc nh ca HZ l 100. C ngha l timer h thng c ci t sao cho trong mt giy c khong 100 ln ngt xy ra. Hay ni cch khc, chu k ngt l 10 ms. Chng ta cng ch , trong tp tin c hai tham s cn sa cha mt lc l USER_HZ v HZ. thun tin cho vic chuyn i qua li thi gian gia kernel v user th gi tr ca chng phi ging nhau. Gi tr HZ thay i phi ph hp vi ng dng m h iu hnh ang phc v. Lm th no lm c iu ny. Chng hn, gi tr ca HZ nh hng rt nhiu n phn gii ca nhng hm nh thi ngt. Vi gi tr HZ = 100, thi gian lp trnh nh thi ngt ti thiu l 10ms. Vi gi tr HZ=1000, thi gian lp trnh nh thi ngt ti thiu l 1ms. iu nyc ngha l gi tr ca HZ cng ln cng tt. Liu thc s c phi nh th?
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

135

N TT NGHIP Khi tng gi tr ca HZ, iu c nhng u v nhc im. V u im, tng gi tr HZ lm phn gii ca thi gian kernel tng ln, nh th mt s ng dng c lin quan n thi gian cng chnh xc hn ,...V nhc im, khi tng gi tr ca HZ, th vi iu khin thc hin ngt nhiu hn, tiu tn thi gian cho vic lu lu ngn xp, khi to ngt, ... nhiu hn, ... do vy ty tng ng dng c th m chng ta thay i gi tr HZ cho ph hp h thng hot ng ti u. III. jiffies: jiffies l mt bin ton cc c nh ngha trong th vin linux/jiffies.h lu s lng ticks t c k t khi h thng bt u khi ng. Khi xy ra ngt timer h thng, kernel tin hnh tng gi tr ca jiffies ln 1 n v. Nh vy nu nh c HZ ticks trong mt giy th jiffies s tng trong mt giy l HZ n v. Nu nh chng ta c c gi tr jiffies hin ti l N, th thi gian k t khi h thng khi ng l N ticks hay N/HZ giy. i khi chng ta mun i gi tr jiffies sang giy v ngc li ta ch vic chia hay nhn gi tr jiffies cho(vi) HZ. Trong kernel, jiffies c lu tr di dng s nh phn 32 bits. L 32 bits c trong s thp trong tng s 64 bits ca bin jiffies_64. Vi chu k tick l 10ms th sau mt khong thi gian 5.85 t nm i vi bin jiffies_64 v 1.36 nm i vi bin jiffes mi c th b trn. Xc sut bin jiffies_64 b trn l cc k nh v jiffies l rt nh. Th nhng vn c th xy ra i vi nhng ng dng i hi tin cy rt cao. Nu cn c th kim tra nu yu cu chnh xc cao. Khi thao tac vi jiffies, kernel h tr cho chng ta cc hm so snh thi gian sau, tt c cc hm ny iu c nh ngha trong th vin linux/jiffies.h: u tin l hm get_jiffies_64(), vi gi tr jiffies th chng ta c th c trc tip theo tn ca n, th nhng jiffies_64 khng th c trc tip m phi thng qua hm ring v gi tr ca jiffies_64 c cha trong s 64 bits. Hm khng c tham s, gi tr tr v ca hm l s c 64 bits. Cui cng l cc hm so snh thi gian theo gi tr ca jiffies. Cc hm ny c nh ngha trong th vin linux/jiffies.h nh sau:
#define time_after(unknown,known)(long)(known)-(long)(unknown)<0) #define time_before(unknown,known)((long)(unknown)-(long)(known)<0) #define time_after_eq(unknown,known)((long)(unknown)-(long)(known)>= 0) #define time_before_eq(unknown,known)((long)(known)-(long)(unknown)>= 0)

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

136

N TT NGHIP cc hm ny tr v gi tr kiu boolean, ty theo tn hm v tham s ca hm. Hm


time_after(unknown, known) tr v gi tr ng nu unknown > known, tng t cho

cc hm khc. ng dng ca cc hm ny khi chng ta mun so snh hai khong thi gian vi nhau thc thi mt tc v no , chng hn ng dng trong tr hon thi gian nh trong on chng trnh sau: /*on chng trnh tr hon thi gian 1s dng jiffies*/ /*Khai bo bin lu thi im cui cng mun so snh*/
unsigned long timeout = jiffies + HZ; //Tr hon 1s

/*Kim tra xem gi tr timeout c b trn hay khng*/


if (time_after(jiffies, timeout)) { printk(This timeout is overflow\n); return -1; }

/*Thc hin tr hon thi gian nu khng b trn*/


if (time_before(jiffies, timeout)) { /*Do nothing loop to delay*/ }

IV. Thi gian thc trong kernel: Trong phn lp trnh ng dng user, chng ta tm hiu k v cc lnh x l thi gian thc trong th vin <time.h>. Trong kernel cng c nhng hm c xy dng sn thao tc vi thi gian thc nm trong th vin <linux/time.h>. S khc bit gia hai th vin ny l vai tr ca chng trong h thng. <time.h> cha trong lp user, giao tip vi kernel, tng t nh cc hm giao din trung gian giao tip gia ngi dng vi thi gian thc trong kernel, v th th vin cha nhng hm ch yu phc v cho ngi dng; i vi th vin <linux/time.h> hot ng trong lp kernel, cha nhng hm c lp trnh sn phc v ch yu cho h thng kernel, gip ngi lp trnh driver qun l thi gian thc tin li hn, v d nh cc hm x l thi gian ngt, nh thi, so snh thi gian, ... im c bit l thi gian thc trong kernel ch yu qun l di dng s giy tuyt i, khng theo dng ngy thng nm nh trong user. Cc kiu cu trc thi gian, ngha cc tham s trong nhng hm thi gian a phn tng t nh trong th vin <time.h> trong user application nn chng s c trnh by s lc trong khi gii thch.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

137

N TT NGHIP 1. Cc kiu, cu trc thi gian: a. Cu trc timespec: cu trc ny c nh ngha nh sau:
struct timespec { __kernel_time_t tv_sec; long }; tv_nsec; /* seconds */ /* nanoseconds */

Trong , tv_sec dng lu thng tin ca giy; tv_nsec dng lu thng tin nano giy ca giy hin ti. b. Cu trc timeval: Cu trc ny c nh ngha nh sau:
struct timeval { __kernel_time_t __kernel_suseconds_t }; tv_sec; tv_usec; /* seconds */ /* microseconds */

Trong , tv_sec dng lu thng tin v s giy; tv_usec dng lu thng tin v micro giy ca giy hin ti. c. Cu trc timezone: Cu trc ny c nh ngha nh sau:
struct timezone { int int }; tz_minuteswest; /* minutes west of Greenwich */ tz_dsttime; /* type of dst correction */

Trong , tz_minuteswst l s pht chnh lch mi gi v pha Ty ca Greenwich;


tz_dsttime l tham s iu chnh chnh lch thi gian theo ma;

2. Cc hm so snh thi gian: a. timespec_equal: Hm c nh ngha nh sau:


static inline int timespec_equal(const struct timespec *a, const struct timespec *b) { return (a->tv_sec == b->tv_sec) && (a->tv_nsec == b->tv_nsec); }

Nhim v ca hm l so snh 2 con tr cu trc thi gian kiu timespec, const


struct timespec *a v const struct timespec *b. So snh tng thnh phn trong

cu trc, tv_sec v tv_nsec, nu hai thnh phn ny bng nhau th hai cu trc thi gian ny bng nhau. Khi hm tr v gi tr true, ngc li tr v gi tr false;
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

138

N TT NGHIP b. timespec_compare: Hm c nh ngha nh sau:


static inline int timespec_compare(const struct timespec *lhs, const struct timespec *rhs) { if (lhs->tv_sec < rhs->tv_sec) return -1; if (lhs->tv_sec > rhs->tv_sec) return 1; return lhs->tv_nsec - rhs->tv_nsec; }

Nhim v ca hm l so snh hai cu trc thi gian kiu timespec, const struc
timespec *lhs v const struct timespec *rhs. Kt qu l mt trong 3 trng hp

sau: Nu lhs < rhs th tr v gi tr nh hn 0; Nu lhs = rhs th tr v gi tr bng 0; Nu lhs > rhs th tr v gi tr ln hn 0; c. timeval_compare: Hm c nh ngha nh sau:
static inline int timeval_compare(const struct timeval *lhs, const struct timeval *rhs) { if (lhs->tv_sec < rhs->tv_sec) return -1; if (lhs->tv_sec > rhs->tv_sec) return 1; return lhs->tv_usec - rhs->tv_usec; }

Nhim v ca hm l so snh hai cu trc thi gian kiu timeval, const struct
timeval *lhs v const struc timeval *rhs. Kt qu tr v l mt trong 3 trng

hp: Nu lhs < rhs th tr v gi tr nh hn 0; Nu lhs = rhs th tr v gi tr bng 0; Nu lhs > rhs th tr v gi tr ln hn 0;

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

139

N TT NGHIP 3. Cc php ton thao tc trn thi gian: a. mktime: Hm c nh ngha nh sau:
extern unsigned long mktime( const unsigned int year, const unsigned int mon, const unsigned int day, const unsigned int hour, const unsigned int min, const unsigned int sec);

Nhim v ca hm l chuyn cc thng tin thi gian dng ngy thng nm ngy gi pht giy thnh thng tin thi gian dng giy tnh t thi im epoch. b. set_normalized_timespec: Hm c nh ngha nh sau:
extern void set_normalized_timespec(struct timespec *ts, time_t sec, long nsec);

Sau khi chuyn cc thng tin ngy thng nm ... thnh s giy tnh t thi im epoch bng cch s dng hm mktime, thng tin tr v cha phi l mt cu trc thi gian chun c th x l c trong kernel. bin thnh cu trc thi gian chun ta s dng hm set_normalize_timespec chuyn s giy dang unsigned long thnh cu trc thi gian timespec. Hm c 3 tham s. Tham s th nht, struct timespec *ts, l con tr tr n cu trc timespec c nh ngha trc lu gi tr thng tin thi gian tr v sau khi chuyn i xong; Tham s th hai, time_t sec, l s giy mun chuyn i sang cu trc timespec (c lu vo trng tv_sec); Tham s th ba, long nsec, l s nano giy ca giy ca thi im mun chuyn i. c. timespec_add_safe:Hm c nh ngha nh sau:
extern struct timespec timespec_add_safe( const struct timespec lhs, const struct timespec rhs);

Nhim v ca hm l cng hai cu trc thi gian kiu timespec, const struct
timespec lhs v const struct timespec rhs. Kt qu tr v dng timespec l tng

ca hai gi tr thi gian nu khng b trn, nu b trn th hm s tr v gi tr ln nht c th c ca kiu timespec. d. timespec_sub:Hm c nh ngha nh sau:
static inline struct timespec timespec_sub(struct timespec lhs,struct timespec rhs) ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

140

N TT NGHIP
{ struct timespec ts_delta; set_normalized_timespec(&ts_delta, lhs.tv_sec - rhs.tv_sec, lhs.tv_nsec - rhs.tv_nsec); return ts_delta; }

Nhim v ca hm ny l tr hai cu trc thi gian kiu timespec, struct


timespec lhs v struct timespec rhs. Hiu ca hai cu trc ny c tr v di

dng timespec. Thng thng hm dng tnh ton khong thi gian gia hai thi im. e. timespec_add_ns: Hm c nh ngha nh sau:
static __always_inline void timespec_add_ns(struct timespec *a, u64 ns) { a->tv_sec+=__iter_div_u64_rem(a->tv_nsec+ns, NSEC_PER_SEC, &ns); a->tv_nsec = ns; }

Nhim v ca hm ny l cng thm mt khong thi gian tnh bng nano giy vo cu trc timespec c a vo hm. Hm c hai tham s. Tham s th nht, struct
timespec *a, l cu trc timespec mun cng thm. Tham s th hai, u64 ns, l s

nano giy mun cng thm vo. 4. Cc hm truy xut thi gian: a. do_gettimeofday:Hm c nh ngha nh sau:
extern void do_gettimeofday(struct timeval *tv);

Nhim v ca hm l ly v thng tin thi gian hin ti ca h thng. Thng tin thi gian hin ti c tr v cu trc dng struct timeval *tv trong tham s ca hm. b. do_settimeofday: Hm c nh ngha nh sau:
extern int do_settimeofday(struct timespec *tv);

Nhim v ca hm l ci t thng tin thi gian hin ti cho h thng da vo cu trc thi gian dng timespec cha trong tham s struct timespec *tv ca hm. c. do_sys_settimeofday: Hm c nh ngha nh sau:
extern int do_sys_settimeofday(struct timespec *tv, struct timezone *tz); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

141

N TT NGHIP Nhim v ca hm l ci t thng tin thi gian hin ti ca h thng c tnh n s chnh lch thi gian v mi gi da vo hai tham s trong hm. Tham s th nht,
struct timespec *tv, l thng tin thi gian mun cp nht. Tham s th hai, sruct timezone *tz, l cu trc lu thng tin chnh lch mi gi mun cp nht.

d. getboottime: Hm c nh ngha nh sau:


extern void getboottime (struct timespec *ts);

Nhim v ca hm l ly v tng thi gian t khi h thng khi ng n thi im hin ti. Thng tin thi gian c lu v cu trc kiu timespec, srtuc timespec. 5. Cc hm chuyn i thi gian: a. timespec_to_ns: Hm c nh ngha nh sau:
static inline s64 timespec_to_ns(const struct timespec *ts) { return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec; }

Nhim v ca hm l chuyn cu trc thi gian dng timespec, const struct


timespec *ts, thnh s nano giy lu vo bin 64 bits lm gi tr tr v cho hm.

b. timeval_to_ns: Hm c nh ngha nh sau:


static inline s64 timeval_to_ns(const struct timeval *tv) { return ((s64) tv->tv_sec * NSEC_PER_SEC) + tv->tv_usec * NSEC_PER_USEC; }

Nhim v ca hm l chuyn i cu trc thi gian dng timeval, const struct


timeval *tv, thnh s nano giy lu vo bin 64 bits lm gi tr tr v cho hm.

c. ns_to_timespec: Hm c dnh ngha nh sau


extern struct timespec ns_to_timespec(const s64 nsec);

Nhim v ca hm l chuyn thng tin thi gian di dng nano giy, const s64
nsec, thnh thng tin thi gian dng timespec lm gi tr tr v cho hm.

d. ns_to_timeval: Hm c nh ngha nh sau:


extern struct timeval ns_to_timeval(const s64 nsec);

Nhim v ca hm l chuyn thng tin thi gian dng nano giy, const s64 nsec, thnh thng tin thi gian dng timeval lm gi tr tr v cho hm.
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

142

N TT NGHIP

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

143

N TT NGHIP V. Timer v s dng ngt trong timer: 1. Khi qut v timer trong kernel: Timer l mt nh ngha quen thuc trong hu ht tt c cc h thng khc nhau. Trong linux kernel, timer c hiu l tr hon thi gian ng gi thc thi mt hm no c lp trnh trc. Ngha l thi im bt u tr hon khng c nh, thng thng c tnh t lc ci t khi ng timer trong h thng, khong thi gian tr hon do ngi lp trnh quy nh, khi ht thi gian tr hon, timer sinh ra mt ngt. Kernel tm hon hot ng hin ti ca mnh thc thi hm ngt c lp trnh trc . a mt timer vo hot ng, chng ta cn phi thc hin nhiu thao tc. u tin phi khi to timer vo h thng linux. Tip theo, ci t khong thi gian mong mun tr hon. Ci t hm thc thi ngt khi thi gian tr hon kt thc. Khi xy ra hot ng ngt, timer s b v hiu ha. V th, nu mun timer hot ng theo chu k c nh chng ta phi khi to li timer ngay trong chng trnh thc thi ngt. S lng timer khi to trong kernel l khng gii hn, v y l mt timer mm khng phi l timer vt l, c gii hn l dung lng vng nh cho php. Chng ta s trnh by c th nhng bc trn trong phn sau. 2. Cc bc s dng timer: **Lu : Khi s dng cc hm trong timer chng ta phi thm th vin
<linux/timer.h> u chng trnh.

a. Bc 1: Khai bo bin cu trc timer_list lu timer khi khi to Cu trc timer_list c linux kernel nh ngha trong th vin <linux/timer.h> nh sau:
struct timer_list { struct list_head entry; unsigned long expires; void (*function) (unsigned long); unsigned long data; struct tvec_t_base_s *base; }

Ta khai bo timer bng dng lnh sau: /*Khai bo mt timer c tn l my_timer*/


struct timer_list my_timer; ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

144

N TT NGHIP

b. Bc 2: Khai bo v nh ngha hm thc thi ngt Hm thc thi ngt c dng nh sau:
void my_timer_function (unsigned long data) { /*Cc thao tc do ngi lp trnh driver quy nh*/ ... /*Nu cn thit c th khi to li timer trong phn cui chng trnh*/ }

c. Bc 3: Khi to cc tham s cho cu trc timer Cng vic tip theo l yu cu kernel cung cp mt vng nh cho timer hoat ng, chng ta s dng cu lnh: /*Khi to timer va khai bo my_timer*/
init_timer (&my_timer);

Sau khi kernel dnh cho timer mt vng nh, timer vn cn trng cha c gn nhng thng s cn thit, cng vic ny ca ngi lp trnh driver: /*Khi to gi tr khong thi gian mun tr hon, n v tnh bng tick*/
my_timer.expires = jiffies + delay;

/*Gn tham s cho hm thc thi ngt, nu khng c tham s ta c th gn mt gi tr bt k*/


my_timer.data = 0;

/*Gn con tr hm x l ngt vo timer*/


my_timer.function = my_function;

Trong cc tham s trn, chng ta cn ch nhng tham s sau y: my_timer.expires y l gi tr thi gian tng lai c n v l tick, ti mi thi im, timer so snh vi s jiffies. Nu s jiffies bng vi s my_timer.expires th ngt xy ra. my_timer.data l tham s chng ta mun a vo hm thc thi ngt, i khi chng ta mun khi to cc thng s ban u cho hm thc thi ngt, k tha nhng thng tin x l t trc hay t ngi dng.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

145

N TT NGHIP my_timer.function l trng cha con tr ca hm phc v ngt c khi to v nh ngha trc . d. Bc 4: Kch hot timer hot ng trong kernel: Chng ta thc thi lnh sau:
add_timer (&my_timer);

Tham s ca hm add_timer l con tr ca timer c khi to v gn cc tham s cn thit. Khi timer c kch hot, hm thc thi ngt hot ng, n s b v hiu ha trong ch k tip theo. Mun timer tip tc hot ng, chng ta phi kch hot li bng cu lnh sau: /*Kch hot timer hot ng li cho chu k ngt tip theo*/
mod_timer (&my_timer, jiffies + new_delay);

Nu mun xa timer khi h thng chng ta sng lnh sau: /*Xa timer khi h thng*/
del_timer (&my_timer);

Tuy nhin lnh ny ch thc hin thnh cng khi timer khng cn hot ng, ngha l khi timer cn ang ch chu k ngt tip theo dng lnh del_timer() s khng hiu qu. Mun khc phc li ny, chng ta phi dng lnh del_timer_sync(), lnh ny s ch cho n khi timer hon thnh chu k ngt gn nht mi xa timer . 3. V d: on chng trnh sau s nh thi xut thng tin ra mn hnh hin th vi chu k l 1s. Mi ln xut s thay i thng tin, thng bo nhng ln xut thng tin l khc nhau; /*Khai bo bin cc b lu gi tr mun xut ra mn hnh, gi tr ban u bng 0*/
int counter = 0;

/*Khai bo bin timer phc v ngt*/


struct time_list my_timer;

/*Khai bo nh ngha hm phc v ngt*/


void timer_isr (unsigned long data) {

/*In thng bo cho ngi dng*/


printk (Driver: Hello, the counters value is %d\n, counter++); ________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

146

N TT NGHIP /*Ci t li gi tr timer cho ln hot ng tip theo, ci t chu k 1 giy*/


mod_timer (&my_timer, jiffies + HZ); }

/*Thc hin khi to timer trong khi ci t driver vo h thng, trong hm init()*/
static int __init my_driver_init (void) {

/*Cc lnh khi to khc*/ ... /*Khi to timer hot ng ngt*/ /*Khi to timer c khai bo*/
init_timer (&my_timer);

/*Ci t cc thng s cho timer*/


my_timer.expires = jiffies + HZ; //Khi to tr hon ban u l 1s; my_timer.data = 0; //D liu truyn cho hm ngt l 0; my_timer.function = my_function; //Gn hm thc thi ngt cho timer.

/*Kch hot timer hot ng trong h thng*/


add_timer (&my_timer); ... }

VI.Tr hon thi gian trong kernel: Tr hon thi gian l mt trong nhng vn quan trng trong lp trnh driver cng nh trong lp trnh application. Trong phn trc chng ta tm hiu nhng lnh tr hon thi gian t khong thi gian nh tnh theo nano giy n khong thi gian ln hn tnh bng giy. Ty thuc vo yu cu chnh xc cao hay thp m chng ta p dng k thut tr hon thi gian cho ph hp. Kernel cng h tr cc k thut tr hon khc nhau ty theo yu cu m p dng k thut no ph hp nht sao cho khng nh hng n hot ng ca h thng. 1. Vng lp v tn: K thut tr hon thi gian u tin l vng lp busy loop. y l cch tr hon thi gian c in v n gin nht, p dng cho tt c cc h thng. K thut tr hon ny c dng nh sau:
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

147

N TT NGHIP /*Khai bo thi im tng lai mun thc hin tr hon*/


unsigned long timeout = jiffies + HZ/10; //Tr hon 10ms;

/*Thc hin vng lp v tn while () tr hon thi gian*/


while (time_before(jiffies, timeout)) ;

Vi cch tr hon thi gian trn, chng ta dng bin jiffies so snh vi thi im tng lai lm iu kin cho lnh while () thc hin vng lp. Nh vy chng ta ch c th tr hon mt khong thi gian ng bng mt s nguyn ln ca tick. Hn na, khc vi lp user, vng lp trong kernel khng c chia tin trnh thc hin. V th vng lp v tn trong kernel s chim ht thi gian lm vic ca CPU v nh th cc hot ng khc s khng c thc thi, h thng s b ngng li tm thi. iu ny rt nguy him cho cc ng dng i hi tin cy cao v thi gian thc. Cch tr hon thi gian ny rt him khi c s dng trong nhng h thng ln. gii quyt vn ny, ngi ta dng k thut chia tin trnh trong lc thc hin tr hon nh sau:
while (time_before(jiffies, timeout)) schedule(); //Hm ny cha trong th vin <linux/sched.h>

Trong khi jiffies vn tha mn iu kin nh hn thi im t trc, kernel s chia thi gian thc hin cng vic khc trong h thng. Cho n khi vng lp c thot, nhng lnh tip theo s tip tc thc thi. Chng ta cng c th p dng nhng lnh so snh thi gian thc trong phn trc thc hin tr hon thi gian vi chnh xc cao hn. 2. Tr hon thi gian bng nhng hm h tr sn: Linux kernel cng cung cp cho chng ta nhng hm thc hin tr hon thi gian vi chnh xc cao, thch hp cho nhng khong thi gian nh. l nhng hm: void udelay(unsigned long usec); Hm dng tr hon thi gian c phn gii micr giy; void ndelay(unsigned long nsec); Hm tr hon thi gian c phn gii nan giy; void mdelay(unsigned long msec); Hm tr hon thi gian c phn gii mili giy;
________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

148

N TT NGHIP **Cc hm tr hon thi gian ny ch thch hp cho nhng khong thi gian nh hn 1 tick trong kernel. Nu ln hn s lm nh hng n hot ng ca c h thng v bn cht y vn l nhng vng lp v tn, chim thi gian hot ng ca CPU. 3. Tr hon thi gian bng hm schedule_timeout (): K thut ny khc vi hai k thut trn, dng hm schedule_timeout() s lm cho chng trnh driver dng li ti thi im khai bo, ri vo trng thi ng trong sut thi gian tr hon. Thi gian tr hon do ngi lp trnh ci t. s dng hm ny, ta tin hnh cc bc sau: /*Ci t chng trnh driver vo trng thi ng*/
set_current_state (TASK_INTERRUPTIBLE);

/*Ci t thi gian cho tn hiu nh thc chng trnh*/


schedule_timeout (unsigned long time_interval);

**Trong time_interval l khong thi gian tnh bng tick mun ci t tn hiu nh thc chng trnh ang trong trng thi ng. VII. Kt lun: Trong bi ny chng ta tm hiu r v cch qun l thi gian trong kernel, th no l jiffies, HZ, ... vai tr ngha ca chng trong duy tr qun thi gian thc cng nh trong tr hon thi gian. Chng ta cng tm hiu cc hm thao tc vi thi gian thc trong kernel, vi nhng hm ny chng ta c th xy dng cc ng dng c lin quan n thi gian thc trong h thng. C nhiu cc khc nhau thc hin tr hon trong kernel tng t nh trong user. Nhng chng ta phi bit cch chn phng php ph hp khng lm nh hng n hot ng ca ton h thng. n y chng ta c th bc vo cc bi thc hnh, vit driver v ng dng cho mt s phn cng c bn trong nhng bi sau. Hon thnh nhng bi ny s gip cho chng ta c c ci nhn th t hn v lp trnh h thng nhng.

________________________________________________________________________________CH

NG II: LP TRNH NHNG NNG CAO

149

CHNG IV

LP TRNH GIAO TIP NGOI VI

Li u chng

Sau khi nghin cu nhng ni dung trong chng III-Lp trnh nhng nng cao, ngi hc c nhng kin thc cn thit v lp trnh user application v kernel driver bt tay vo vit ng dng iu khin cc thit b ngoi vi. qu trnh nghin cu t hiu qu cao nht, trc khi di vo tng bi thc hnh trong chng ny ngi hc phi c nhng kin thc v k nng sau: S dng thnh tho nhng phn mm h tr lp trnh nhng nh: SSH, Linux o, console putty, ... Tt c u c trnh by trong chng II-Lp trnh nhng cn bn. Bit cch bin dch chng trnh ng dng trong user bng trnh bin dch gcc trong linux o v trc tip trong h thng linux ca kit; Bin dch chng trnh driver bng tp tin Makefile; Cch ci t driver v thc thi ng dng trong kit. Trnh by c cc vn c lin quan n character device driver. Gii thch c cc cu lnh c s dng trong qu trnh lp trnh application cng nh lp trnh driver nh: cc giao din hm, gpio, tr hon thi gian, ... Chng ny c trnh by bao gm nhng bi tp thc hnh ring bit nhau, c sp xp theo th t t d n kh. Mi bi hc s nghin cu iu khin mt thit b ngoi vi hoc c th phi hp vi cc thit b ngoi vi khc ty theo yu cu iu khin ca bi ton. Nhm mc ch cho ngi hc ng dng ngay nhng kin thc trong trong cc chng trc, t s khc su v p dng mt cch thnh tho vo cc trng hp trong thc t. Cc ngoi vi c trnh by trong chng l nhng module c tch hp trong CHIP vi iu khin hoc c lp t trong cc b th nghim khc. Cc ngoi vi l: LED n, LED 7 on, LCD, ADC on chip, UART, I2C, ... l nhng module n gin ph hp vi trnh , gip cho ngi hc c th hiu v vn dng vo nhng ng dng ln khc nhanh chng hn. Mi bi l mt d n thc hnh c cu trc thnh 3 phn: Phc tho d n, thc hin d n v kt lun-bi tp. Trong : Phn phc tho d n: Trnh by s lc v yu cu thc hin trong d n. Sau khi khi qut c yu cu, s tin hnh phn cng nhim v thc thi gia hai thnh phn user application v kernel driver sau cho d n c hot ng ti u trong h thng. Phn thc thi d n: Bao gm s nguyn l kt ni cc chn gpio vi phn cng; m chng trnh tham kho ca driver v application, mi dng lnh u c

nhng ch thch gip ngi hc hiu c qu trnh lm vic ca chng trnh, (m lnh chng trnh hon chnh c lu trong th mc tham kho ca CD km theo ti, ngi hc c th chp vo chng trnh son tho v bin dch thc thi). Phn kt lun-bi tp: Phn ny s tng hp li nhng kin thc kinh nghim lp trnh m d n trnh by, nu ln nhng ni dung chnh trong bi hc ti. ng thi chng ti cng a ra nhng bi tp tham kho gip cho ngi hc nm vng kin thc to nn tng cho d n mi. **Mi bi tp thc hnh c trnh by mang tnh cht k tha, do ngi hc cn tin hnh theo dng trnh t c bin son t hiu qu cao nht.

BI 1

GIAO TIP IU KHIN LED N


1-1IU KHIN SNG TT 1 LED: I. Phc tho d n: y l d n u tin cn bn nht trong qu trnh lp trnh iu khin cc thit b phn cng. Ngi hc c th lm quen vi vic iu khin cc chn gpio cho cc mc ch khc nhau: truy xut d liu, ci t thng s i vi mt chn vo ra trong vi iu khin thng qua driver v chng trnh ng dng. hon thnh c bi ny, ngi hc phi c nhng kin thc v k nng sau: Kin thc v mi quan h gia driver v application trong h thng nhng, cng nh vic trao i thng tin qua li da vo cc giao din chun; Kin thc v giao din chun ioctl trong giao tip gia driver (trong kernel) v application (trong user); Kin thc v gpio trong linux kernel; Lp trnh chng trnh ng dng c s dng k thut hm main c nhiu tham s giao tip vi ngi dng; Bin dch v ci t c driver, application np vo h thng v thc thi; **Tt c nhng kin thc yu cu nu trn iu c chng ti trnh by k trong nhng phn trc. Nu cn ngi hc c th quay li tm hiu bc vo ni dung ny hiu qu hn. a. Yu cu d n: D n ny c yu cu l iu khin thnh cng 1 led n thng qua driver v application. Ngi dng c th iu khin led sng tt v c v trng thi ca mt chn gpio theo yu cu nhp t dng lnh shell. u tin, ngi dng xc nh ch vo ra cho chn gpio mun iu khin. Tip theo, nu l ch d ng vo th s xut thng tin ra mn hnh hin th cho bit trng thi ca chn gpio l mc thp hay mc cao. Nu l ch ng ra th ngi dng s nhp thng tin high hoc low iu khin led sng tt theo yu cu.

**Lu , nu ng vo th ngi dng nn kt ni chn gpio vi mt cng tc iu khin ON-OFF, nu ng ra th ngi dng nn kt ni chn gpio vi mt LED n theo kiu tch cc mc cao. b. Phn cng nhim v: Driver: c tn single_led_dev.c S dng k thut giao din ioctl nhn lnh v tham s t user application thc thi diu khin chn gpio theo yu cu. ioctl c 5 tham s lnh tng ng vi 5 kh nng m driver c th phc v cho application: GPIO_DIR_IN: Ci t chn gpio l ng vo; GPIO_DIR_OUT: Ci t chn gpio l ng ra; GPIO_GET: Ly d liu mc logic t chn gpio ng vo tr v mt bin ca user application; GPIO_SET: Xut d liu cho chn gpio ng ra theo thng tin ly t mt bin trong user application tng ng s l mc thp hay mc cao; Application: c tn single_led_app.c S dng k thut lp trnh hm main c nhiu tham s la chn cho ngi dng kh nng iu khin trn mn hnh shell trong qu trnh thc thi chng trnh ng dng. Theo , chng trnh ng dng single_led_app c nhng thao tc lnh sau: u tin ngi dng nhp tn chng trnh cng vi cc tham s mong mun tng ng vi tng lnh mun thc thi. Nu l lnh dirin, ngi dng phi cung cp cho driver tham s tip theo l s chn gpio mun ci t ch ng vo; Nu l lnh dirout, ngi dng phi cung cp cho driver tham s tip theo l s chn gpio mun ci t ch ng ra; Nu l lnh set, thng tin tip theo phi cung cp l 1 hoc 0 v chn gpio mun xut d liu; Nu l lnh get, thng tin tip theo ngi dng phi cung cp l s chn gpio mun ly d liu. Sau khi ly d liu, xut ra mn hnh hin th thng bo cho ngi dng bit. II. Thc hin: a. Kt ni phn cng: Thc hin kt ni phn cng theo s sau:

VCC

U1 PC0 9 8 7 6 5 4 3 2 1 19 A8 A7 A6 A5 A4 A3 A2 A1 DIR G 74HC245 B8 B7 B6 B5 B4 B3 B2 B1 11 12 13 14 15 16 17 18

D1 R1 D2 R1 330 R1 330 R1 330 R1 330 R1 330 R1 330 R1 330 330 D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED LED LED PA23 PB10 R2 4k7 R2 4k7

VCC

SW1

b. Chng trnh driver: /*Khai bo th vin cho cc hm s dng trong chng trnh*/
#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <linux/genhd.h> #include <linux/miscdevice.h>

/*nh ngha tn driver thit b*/


#define DRVNAME #define DEVNAME "single_led_dev" "single_led"

/*nh ngha s nh danh lnh cho giao din ioctl*/


#define IOC_SINGLE_LED_MAGIC #define GPIO_GET #define GPIO_SET #define GPIO_DIR_IN #define GPIO_DIR_OUT 'B' _IO(IOC_SINGLE_LED_MAGIC, 10) _IO(IOC_SINGLE_LED_MAGIC, 11) _IO(IOC_SINGLE_LED_MAGIC, 12) _IO(IOC_SINGLE_LED_MAGIC, 13)

/* Counter is 1, if the device is not opened and zero (or less) if opened. */
static atomic_t gpio_open_cnt = ATOMIC_INIT(1);

/*Khai bo v nh ngha giao din ioctl*/ static int


gpio_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg[]) {

int retval = 0;

/*Kim tra s nh danh lnh thc hin theo yu cu*/


switch (cmd) {

/*Trong trng hp l lnh GPIO_GET*/


case GPIO_GET:

/*Ly thng tin t chn gpio*/


retval = gpio_get_value(arg[0]); break;

/*Trong trng hp l GPIO_SET*/


case GPIO_SET:

/*Xut d liu arg[1] t user application cho chn gpio arg[0]*/


gpio_set_value(arg[0], arg[1]); break;

/*Trong trng hp l lnh GPIO_DIR_IN*/


case GPIO_DIR_IN:

/*Yu cu truy xut chn gpio arg[0]*/


gpio_request (arg[0], NULL);

/*Chn gpio arg[0] trong ch ko ln*/


at91_set_GPIO_periph (arg[0], 1);

/*Ci t chn gpio arg[0] ch d ng vo*/


gpio_direction_input(arg[0]); break;

/*Trong trng hp l lnh GPIO_DIR_OUT*/


case GPIO_DIR_OUT:

/*Yu cu truy xut chn gpio arg[0]*/


gpio_request (arg[0], NULL);

/*Ci t ko ln cho chn gpio arg[0]*/


at91_set_GPIO_periph (arg[0], 1);

/*Ci t ch ng ra cho chn gpio arg[0], gi tr khi u l 0*/


gpio_direction_output(arg[0], 0); break;

/*Trng hp khng c lnh thc th, tr v m li*/ default:


retval = -EINVAL; break; }

/*Tr v m li cho ioctl*/


return retval; }

/*Khai bo v nh ngha giao din open*/


static int gpio_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&gpio_open_cnt)) { atomic_inc(&gpio_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; }

out: return result; }

/*Khai bo v nh ngha giao din close*/


static int gpio_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&gpio_open_cnt);

return 0; }

/*Gn cc giao din vo file_operations*/


struct file_operations gpio_fops = { .ioctl .open .release }; = gpio_ioctl, = gpio_open, = gpio_close,

/*Ci t cc thng s trn vo file_node*/


static struct miscdevice gpio_dev = { .minor .name = MISC_DYNAMIC_MINOR, = "single_led",

.fops };

= &gpio_fops,

/*Hm khi to ban u*/


static int __init gpio_mod_init(void) { return misc_register(&gpio_dev); }

/*Hm kt thc khi tho g driver ra khi h thng*/


static void __exit gpio_mod_exit(void) { misc_deregister(&gpio_dev); }

/*Gn cc hm khi to init v kt thc exit vo cc macro cn thit*/


module_init (gpio_mod_init); module_exit (gpio_mod_exit);

/*Cp nht cc thng tin v chng trnh*/


MODULE_LICENSE("GPL"); MODULE_AUTHOR("coolwarmboy"); MODULE_DESCRIPTION("Character device for for generic gpio api");

c. Chng trnh application: /*Khai bo cc th vin s dng trong chng trnh*/


#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h>

/*nh ngha s nh danh lnh s dng trong giao din ioctl*/


#define IOC_SINGLE_LED_MAGIC #define GPIO_GET #define GPIO_SET #define GPIO_DIR_IN #define GPIO_DIR_OUT 'B' _IO(IOC_SINGLE_LED_MAGIC, 10) _IO(IOC_SINGLE_LED_MAGIC, 11) _IO(IOC_SINGLE_LED_MAGIC, 12) _IO(IOC_SINGLE_LED_MAGIC, 13)

/*Chng trnh con in ra hng dn cho ngi dng, khi c li xy ra*/


void print_usage() {

printf("single_led_app dirin|dirout|get|set gpio <value>\n"); exit(0); }

/*Chng trnh chnh main() khai bo theo dng c tham s*/


int main(int argc, char **argv) {

/*S int lu tr s chn gpio*/


int gpio_pin;

/*S m t tp tin, c tr v khi m tp tin thit b*/


int fd;

/*B nh m trao i d liu qua li gia kernel v user trong giao din ioctl*/
unsigned long ioctl_buff[2];

/*Bin tr v m li trong qu trnh thc thi chng trnh*/


int result = 0;

/*M tp tin thit b trc khi thao tc*/


if ((fd = open("/dev/single_led", O_RDWR)) < 0) {

/*In ra thng bo li nu qu trnh m thit b khng thnh cng*/


printf("Error whilst opening /dev/single_led_dev\n"); return -1; }

/*Chuyn tham s nhp t ngi dng thnh s gpio lu vo bin gpio_pin*/


gpio_pin = atoi(argv[2]);

/*Thng bo cho ngi dng ang s dng chn gpio*/


printf("Using gpio pin %d\n", gpio_pin);

/*So snh tham s nhp t ngi dng bit phi thc hin lnh no*/ /*Trong trng hp l lnh dirin ci t chn gpio l ng vo*/
if (!strcmp(argv[1], "dirin")) {

/*Cp nht b nh m trc khi chuyn qua kernel*/


ioctl_buff[0] = gpio_pin;

/*S dng giao din ioctl vi lnh GPIO_DIR_IN*/


ioctl(fd, GPIO_DIR_IN, ioctl_buff);

/*Trong trng hp l lnh dirout ci t chn gpio l ng ra*/


} else if (!strcmp(argv[1], "dirout")) {

/*Cp nht cng nh m trc khi truyn sang kernel*/


ioctl_buff[0] = gpio_pin;

/*Dng giao din ioctl vi lnh GPIO_DIR_OUT */


ioctl(fd, GPIO_DIR_OUT, ioctl_buff);

/*Trong trng hp l lnh get ly d liu t chn gpio*/


} else if (!strcmp(argv[1], "get")) {

/*Cp nht vng nh m trc khi truyn sang kernel*/


ioctl_buff[0] = gpio_pin;

/*S dng ioctl cp nht thng tin tr v cho user*/


result = ioctl(fd, GPIO_GET, ioctl_buff);

/*In thng bo cho ngi s dng bit mc cao hay thp ca chn gpio*/
printf("Pin %d is %s\n", gpio_pin, (result ? "HIGH" : "LOW"));

/*Trong trng hp l lnh set xut thng tin ra chn gpio*/


} else if (!strcmp(argv[1], "set")) {

/*Kim tra li c php*/


if (argc != 4) print_usage();

/*Cp nht thng tin b nh m trc khi truyn cho kernel*/ /*Cp nht thng tin v s chn gpio*/
ioctl_buff[0] = gpio_pin;

/*Cp nht thng tin mc mun xut ra chn gpio*/


ioctl_buff[1] = atoi(argv[3]);

/*Dung giao din oictl truyn thng ip cho dirver*/


ioctl(fd, GPIO_SET, ioctl_buff); } else print_usage(); return result; }

d. Bin dch v thc thi d n: Bin dch driver: Trong th mc cha tp tin m ngun drive, to tp tin Makefile c ni dung sau:
export ARCH=arm export CROSS_COMPILE=arm-none-linux-gnueabiobj-m += single_led_dev.o all:

/*Lu phi ng dng dn n cu trc m ngun kernel*/


make -C /home/arm/project/kernel/linux-2.6.30 M=$(PWD) modules

clean:

/*Lu phi ng ng dn n cu trc m ngun kernel*/


make -C /home/arm/project/kernel/linux-2.6.30 M=$(PWD) clean

Bin dch driver bng lnh shell nh sau:


make clean all

**lc ny tp tin chng trnh driver c to thnh vi tn single_led_dev.ko Bin dich application: Bng lnh shell sau:
./arm-none-linux-gnueabi-gcc single_led_app.c o single_led_app

**Chng trnh c bin dch c tn l single_led_app Thc thi chng trnh: Chp driver v application vo kit; Ci t driver bng lnh: insmod single_led_dev.ko Thay i quyn thc thi cho chng trnh application bng lnh:
chmod 777 single_led_app

Chy chng trnh v quan st kt qu: Khai bo chn PC0 l ng ra:


./single_led_app dirout 96 Using gpio pin 96

(Lc ny led kt ni vi PC0 tt) Xut d liu mc cao cho PC0:


./single_led_app set 96 1 Using gpio pin 96

(Lc ny ta thy led ni vi chn PC0 sng ln) Xut d liu mc thp cho PC0:
./single_led_app set 96 0 Using gpio pin 96

(Lc ny ta thy led ni vi chn PC0 tt xung) Khai bo chn PA23 l ng vo:
./single_led_app dirin 55 Using gpio pin 55

**Khi cng tc ni vi PA23 v tr ON, chn PA23 ni xung mass; Ly d liu vo t chn PA23
./single_led_app get 55 Using gpio pin 55 Pin 55 is LOW

** Khi cng tc ni vi PA23 v tr OFF, chn PA23 ni ln VCC;

Ly d liu vo t chn PA23


./single_led_app get 55 Using gpio pin 55 Pin 55 is HIGH

**Tng t cho cc chn gpio khc; III. Kt lun v bi tp: a. Kt lun: Phn ny cc bn nghin cu thnh cng cc thao tc truy xut chn gpio n l. Kin thc ny s lm nn cho cc bi ln hn, truy xut theo port 8 bits, hay iu khin thit b ngoi vi bng nt nhn... Chng ta s tm hiu cc k thut lp trnh giao tip gpio khc vi nhiu chn gpio cng mt lc trong phn sau. b. Bi tp: 1. Da vo cc lnh trong driver single_led_dev.ko h tr, hy vit chng trnh application cho 1 led sng tt vi chu k 1s trong 10 ln ri ngng. 2. Xy dng chng trinh application da vo driver single_led_dev.ko c sn iu khin 8 LEDS sng tt cng mt lc vi chu k 1 s lin tc. 3. Xy dng driver mi da vo driver single_led_dev.ko vi yu cu: Thm chc nng set 1 port 8 bit, v tt 1 port 8 bit. Vit chng trnh application s dng driver mi thc hin li yu cu ca bi 2.

1-2-

IU KHIN SNG TT 8 LED:

I. Phc tho d n: D n ny ch yu truy xut chn gpio theo ch ng ra, nhng im khc bit so vi d n trc l khng iu khin ring l tng bit m cng vic diu khin ny s do driver thc hin. Phn ny s cho chng ta lm quen vi cch iu khin thng tin theo tng port 8 bits. vic tip thu t hiu qu cao nht, trc khi nghin cu ngi hc phi c nhng kin thc v k nng sau: Kin thc tng qut v mi quan h gia driver v application trong h thng nhng, cng nh vic trao i thng tin qua li da vo cc giao din chun; Kin thc v giao din chun write trong giao tip gia driver (trong kernel) v application (trong user); Kin thc v gpio trong linux kernel; Lp trnh chng trnh ng dng c s dng k thut hm main c nhiu tham s giao tip vi ngi dng; Bin dch v ci t c driver, application np vo h thng v thc thi; **Tt c nhng kin thc yu cu nu trn iu c chng ti trnh by k trong nhng phn trc. Nu cn ngi hc c th quay li tm hiu bc vo ni dung ny hiu qu hn. a. Yu cu d n: Yu cu ca d n l iu khin thnh cng 1 port 8 leds hot ng chp tt cng lc theo ch k v s ln c nhp t ngi dng trong lc gi chng trnh thc thi. Khi ht nhim v chng trnh s c thot v ch ln gi thc thi tip theo. u tin ngi dng gi chng trnh driver, cung cp thng tin v thi gian ca chu k v s ln nhp nhy mong mun; Chng trnh application nhn d liu t ngi dng, tin hnh iu khin driver tc ng vo ng ra gpio lm led sng tt theo yu cu; Lu iu khin nh sau:

b. Phn cng nhim v: Driver: C tn l port_led_dev.c Driver s dng giao din write() nhn d liu t user application xut ra led tng ng vi d liu nhn c. D liu nhn t user application l mt s char c 8 bits. Mi bit tng ng vi 1 led cn iu khin. Nhim v ca driver l so snh tng ng tng bit trong s char ny quyt nh xut mc cao hay mc thp cho led ngoi vi. Cng vic ca driver c thc hin tun t nh sau: Yu cu ci t cc chn ngoi vi l ng ra, ko ln. Cng vic ny c thc hin khi thc hin lnh ci t driver vo h thng linux; Trong giao din hm write() (nhn d liu t user) thc hin xut ra mc cao hoc mc thp cho gpio iu khin led. Gii phng cc chn gpio c khai bo khi khng cn s dng, cng vic ny c thc hin ngay trc khi tho b driver ra khi h thng. Application: C tn l port_led_app.c Thc hin khai bo hm main theo cu trc tham s p ng cc yu cu khc nhau t ngi dng. Chng trnh application c hai tham s: Tham s th nht l thi gian tnh bng giy ca chu k chp tt, tham s th hai l s chu k mun chp tt. Bn cnh , phn ny cn lp trnh thm mt s chng trnh to hiu ng iu khin led khc nh: 8 led sng dn tt dn (Tri qua phi, phi qua tri, ...). Cc chc nng ny c tng hp trong mt chng trnh application duy nht, ngi s dng s la chn hiu ng thng qua cc tham s ngi dng ca hm main.

II. Thc hin: a. Kt ni phn cng: Cc bn thc hin kt ni phn cng theo s sau:
U1 PB8 PB10 PA23 PB16 PA24 PB11 PB9 PB7 VCC 9 8 7 6 5 4 3 2 1 19 A8 A7 A6 A5 A4 A3 A2 A1 DIR G 74HC245 B8 B7 B6 B5 B4 B3 B2 B1 11 12 13 14 15 16 17 18 D1 R1 D2 R2 330 R3 330 R4 330 R5 330 R6 330 R7 330 R8 330 330 D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED LED LED

**Lu phi ng s chn quy c. b. Chng trnh driver: port_led_dev.c /*Khai bo th vin cn thit cho cc hm s dng trong chng trnh*/
#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <asm/atomic.h> #include <linux/genhd.h> #include <linux/miscdevice.h>

/*t tn cho driver thit b*/


#define DRVNAME #define DEVNAME "port_led_dev" "port_led"

/*nh ngha cc chn s dng tng ng vi chn trong kit h tr */


/*-------------Port Control-----------*/ #define P00 #define P01 #define P02 #define P03 #define P04 #define P05 #define P06 #define P07 AT91_PIN_PB8 AT91_PIN_PB10 AT91_PIN_PA23 AT91_PIN_PB16 AT91_PIN_PA24 AT91_PIN_PB11 AT91_PIN_PB9 AT91_PIN_PB7

/*nh ngha port t cc bit khai bo*/


#define P0 (P00|P01|P02|P03|P04|P05|P06|P07)

/*Khai bo cc lnh set v clear cn bn cho qu trnh iu khin port*/


/*Basic commands*/ #define SET_P00() #define SET_P01() #define SET_P02() #define SET_P03() #define SET_P04() #define SET_P05() #define SET_P06() #define SET_P07() #define CLEAR_P00() #define CLEAR_P01() #define CLEAR_P02() #define CLEAR_P03() #define CLEAR_P04() #define CLEAR_P05() #define CLEAR_P06() #define CLEAR_P07() gpio_set_value(P00,1) gpio_set_value(P01,1) gpio_set_value(P02,1) gpio_set_value(P03,1) gpio_set_value(P04,1) gpio_set_value(P05,1) gpio_set_value(P06,1) gpio_set_value(P07,1) gpio_set_value(P00,0) gpio_set_value(P01,0) gpio_set_value(P02,0) gpio_set_value(P03,0) gpio_set_value(P04,0) gpio_set_value(P05,0) gpio_set_value(P06,0) gpio_set_value(P07,0)

/* Counter is 1, if the device is not opened and zero (or less) if opened. */
static atomic_t port_led_open_cnt = ATOMIC_INIT(1);

/*Set v clear cc bits trong port tng ng vi d liu 8 bit nhn c*/
void port_led_write_data_port(char data) { (data&(1<<0))? SET_P00():CLEAR_P00(); (data&(1<<1))? SET_P01():CLEAR_P01(); (data&(1<<2))? SET_P02():CLEAR_P02(); (data&(1<<3))? SET_P03():CLEAR_P03(); (data&(1<<4))? SET_P04():CLEAR_P04(); (data&(1<<5))? SET_P05():CLEAR_P05(); (data&(1<<6))? SET_P06():CLEAR_P06(); (data&(1<<7))? SET_P07():CLEAR_P07(); }

/*Giao din hm write, nhn d liu t user xut thng tin ra port led*/
static { ssize_t port_led_write (struct file *filp, char __iomem buf[], size_t bufsize, loff_t *f_pos)

/*S dng hm xut d liu ra port led nh ngha*/


port_led_write_data_port(buf[0]);

return bufsize; } static int port_led_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&port_led_open_cnt)) { atomic_inc(&port_led_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; } static int port_led_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&port_led_open_cnt); return 0; } struct file_operations port_led_fops = { .write .open .release }; static struct miscdevice port_led_dev = { .minor .name .fops }; static int __init port_led_mod_init(void) = MISC_DYNAMIC_MINOR, = "port_led", = &port_led_fops, = port_led_write, = port_led_open, = port_led_close,

/*Yu cu cc chn gpio mun s dng*/


gpio_request (P00, NULL); gpio_request (P01, NULL); gpio_request (P02, NULL); gpio_request (P03, NULL); gpio_request (P04, NULL); gpio_request (P05, NULL); gpio_request (P06, NULL); gpio_request (P07, NULL);

/*Khi to cc chn gpio c in tr ko ln*/


at91_set_GPIO_periph (P00, 1); at91_set_GPIO_periph (P01, 1); at91_set_GPIO_periph (P02, 1); at91_set_GPIO_periph (P03, 1); at91_set_GPIO_periph (P04, 1); at91_set_GPIO_periph (P05, 1); at91_set_GPIO_periph (P06, 1); at91_set_GPIO_periph (P07, 1);

/*Khi to cc chn gpio c ch ng ra, gi tr ban u l 0*/


gpio_direction_output(P00, 0); gpio_direction_output(P01, 0); gpio_direction_output(P02, 0); gpio_direction_output(P03, 0); gpio_direction_output(P04, 0); gpio_direction_output(P05, 0); gpio_direction_output(P06, 0); gpio_direction_output(P07, 0); return misc_register(&port_led_dev); } static void __exit port_led_mod_exit(void) { misc_deregister(&port_led_dev); } module_init (port_led_mod_init); module_exit (port_led_mod_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("coolwarmboy");

MODULE_DESCRIPTION("Character device for for generic gpio api");

c. Chng trnh application: c tn l port_led_app.c /*Khai bo cc th vin cn dng cho cc hm trong chng trnh*/
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h>

/*Hm in ra hng dn thc thi lnh trong trng hp ngi dng nhp sai c php*/
void print_usage() { printf("port_led_app <TimePeriod> <NumberPeriod>\n"); exit(0); }

/*Khai bo hm main c tham s cho ngi dng*/


int main(int argc, char **argv) {

/*Khai bo s m t tp tin cho driver khi c m*/


int port_led_fd;

/*Khai bo vng nh b m ghi cho giao din hm write()*/


char write_buf[1];

/*Bin iu khin v lu tr thng tin ngi dng*/


int i, time_period, number_period;

/*M driver v kim tra li*/


if ((port_led_fd = open("/dev/port_led", O_RDWR)) < 0) {

/*Nu c li th in ra thng bo v kt thc chng trnh*/


printf("Error whilst opening /dev/port_led device\n"); return -1; }

/*Kim tra li c php t ngi dng*/


if (argc != 3) { print_usage(); }

/*Ly chu k thi gian nhp t ngi dng*/


time_period = atoi(argv[1]);

/*Ly s chu k mong mun nhp t ngi dng*/


number_period = atoi(argv[2]);

/*Np thng tin cho vng nh m*/


write_buf[0] = 0x00;

/*Thc hin chp tt theo ng s chu k t*/


for (i=0; i < number_period; i++) {

/*Cp nht thng tin ca vng nh m ghi driver*/


write_buf[0] = ~(write_buf[0]);

/*Ghi thng tin ca b m sang driver ra port led*/


write (port_led_fd, write_buf, 1);

/*Tr hon thi gian theo ng chu k ngi dng nhp vo*/
usleep(time_period*500000); }

/*Tr v gi tr 0 khi khng c li xy ra*/


return 0; }

d. Bin dch v thc thi d n: Bin dch driver: To tp tin Makefile trong cng th mc vi driver. C ni dung sau:
export ARCH=arm export CROSS_COMPILE=arm-none-linux-gnueabiobj-m += port_led_dev.o all:

/*Lu phi ng dng dn n cu trc m ngun kernel*/


make -C /home/arm/project/kernel/linux-2.6.30 M=$(PWD) modules clean:

/*Lu phi ng dng dn n cu trc m ngun kernel*/


make -C /home/arm/project/kernel/linux-2.6.30 M=$(PWD) clean

Bin dch application: Tr vo th mc cha tp tin chng trnh, bin dch chng trnh ng dng vi lnh sau:
arm-none-linux-gnueabi-gcc port_led_app.c o port_led_app

**Chng trnh bin dch thnh cng c tn l: port_led_app Thc thi chng trnh:

Chp driver v chng trnh vo kit, thc thi v kim tra kt qu; Ci t driver vo kit theo lnh sau:
insmod port_led_dev.ko

Thay i quyn thc thi cho chng trnh ng dng:


chmod 777 port_led_app

Thc thi v kim tra kt qu:


./port_led_app 1 10

**Chng ta thy 8 led nhp nhy 10 ln vi chu k 1s. Cc bn thay i chu k v s ln nhp nhy quan st kt qu. III. Kt lun v bi tp: a. Kt lun: Trong bi ny chng ta vit xong driver iu khin 8 led n trong cng mt lc tng ng vi d liu nhn c t user application. Chng ta cng vit mt chng trnh iu khin led chp tt theo yu cu ca ngi dng. Trong nhng bi sau, driver ny s c p dng lp trnh cc hiu ng iu khin led khc. **Do nhng thao tc bin dch driver v application c chng ti trnh by rt k trong phn lp trnh h thng nhng cn bn, hn na cng c nhc li mt cch c th trong nhng bi u tin ca lp trnh thc hnh iu khin phn cng, nn trong nhng bi tip theo s khng nhc li. Sau khi c m ngun ca driver v application th cng vic cn li l lm sau cho chng c th chay c trn kit, ... thuc v ngi hc. b. Bi tp: 1. M rng driver iu khin 8 LED trn thnh driver iu khin 16 LED theo s kt ni sau:
U1 PB8 PB10 PA23 PB16 PA24 PB11 PB9 PB7 VCC 9 8 7 6 5 4 3 2 1 19 A8 A7 A6 A5 A4 A3 A2 A1 DIR G 74HC245 B8 B7 B6 B5 B4 B3 B2 B1 11 12 13 14 15 16 17 18 D1 R1 D2 R2 330 R3 330 R4 330 R5 330 R6 330 R7 330 R8 330 330 D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED LED LED PB0 PB2 PC5 PC6 PC7 PC4 PB3 PB1 VCC 9 8 7 6 5 4 3 2 1 19 U1 A8 A7 A6 A5 A4 A3 A2 A1 DIR G 74HC245 B8 B7 B6 B5 B4 B3 B2 B1 11 12 13 14 15 16 17 18 D1 R1 D2 R2 330 R3 330 R4 330 R5 330 R6 330 R7 330 R8 330 330 D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED LED LED

Nhim v ca driver l nhn d liu c chiu di 16 bits t user application. Sau xut ra tng LED tng ng vi 16 bits d liu.

2. Vit chng trnh iu khin 16 LEDs ny chp tt theo yu cu ca ngi s dng. (V thi gian v s lng chu k mun iu khin).

1-3-

SNG DN TT DN 8 LED:

I. Phc tho d n: D n ny da vo driver c t bi trc vit chng trnh ng dng to nhiu hiu ng chp tt 1 port 8 LEDs khc nhau nh: iu khin sng, tt dn; Sng dn; im sng dch chuyn mt dn; ... Cc bi tp ny s gip cho ngi hc lm quen vi vic s dng driver xy dng sn vo nhng chng trnh ng dng khc nhau hon thnh mt yu cu no trong thc t. a. Yu cu d n: D n bao gm 2 phn, driver ging nh ca bi lp trnh sng tt 8 LEDs v applicaiton c lp trnh s dng driver ny to ra cc hiu ng hin th LEDs khc nhau. Chng trnh user application cng s dng k thut lp trnh hm main c tham s. Ngi s dng phi nhp theo dng c php la chn cho mnh hiu ng LEDs. C php l: <tn chng trnh> <kiu hiu ng> <chu k> <s chu k> Trong :
<Tn chng trnh> l tn chng trnh c bin dch t m ngun; <kiu hiu ng> l hiu ng hin th LED, y c 4 kiu: type1, type2, type3 v

type4;
<chu k> l khong thi gian (tnh bng ms) gia 2 ln thay i trng thi; <s chu k> l s chu k lp li trng thi.

b. Phn cng nhim v: Driver: C tn l port_led_dev.c c xy dng trong bi trc. Application: C tn l 1_3_OtherLedControl.c. Bao gm nhng chc nng sau: 1. 8 LEDs sng dn tt ht (Dch tri); Cch 1: To mt mng bao gm c 9 trng thi khc nhau ca 8 bits sao cho c hiu ng sng dn, sau cho 8 led tt ht. C tip tc theo ng s chu k ngi s dng mun. Cc trng thi tng ng nh sau:

1: 00000000 2: 00000001 3: 00000011 gian quan st c kt qu).

4: 00000111 5: 00001111 6: 00011111

7: 00111111 8: 01111111 9: 11111111

(Quay li t u sau khi hin th ht d liu, mi trng thi u c tr hon thi Cch 2: p dng lnh dch (<< v >>) trong C vit bi ton ny. Chng trnh c vit theo lu thut ton sau:
type1

j=0

j<number_period

False

End

True j=j+1 i=0 B m ghi bng 0x00

j=j+1

False

i <9

True Ghi d liu ra port; Tr hon thi gian; Dch tri 1 vo b m ghi; i = i + 1;

2. 8 LEDs sng dn tt dn (Dch tri); Cch 1: To mt mng bao gm c 15 trng thi khc nhau ca 8 bits sao cho c hiu ng sng dn, sau cho 8 led tt dn. C tip tc theo ng s chu k ngi s dng mun. Cc trng thi tng ng nh sau: 1. 00000001 2. 00000011 3. 00000111

4. 5. 6. 7. 8.

00001111 00011111 00111111 01111111 11111111

9. 10. 11. 12. 13.

11111110 11111100 11111000 11110000 11100000

14. 15. 16.

11000000 10000000 Trng thi 1.

(Tnh l 1 chu k);

(Quay li t u sau khi hin th ht d liu, mi trng thi u c tr hon thi gian quan st c kt qu). Cch 2: p dng lnh dch (<< v >>) trong C vit bi ton ny. Chng trnh c vit theo lu thut ton sau:
type2

j=0

j<number_period

False

End

True False j=j+1 i=0 B m ghi bng 0x00

i < 16
True

i=i+1 Ghi d liu ra port Tr hon thi gian

False

i <8 True

Dch tri 0 vo b m ghi (Tt dn)

Dch tri 1 vo b m ghi; (Sng dn)

3. 8 LEDs sng dn: Cch 1: To mt mng bao gm c 36 trng thi khc nhau ca 8 bits sao cho c hiu ng sng dn. C tip tc theo ng s chu k ngi s dng mun. Cc trng thi tng ng nh mng s hex 8 bits sau:
char Data_Display_Type_3[36] = { 0x00, 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, 0x81,0x82,0x84,0x90,0xA0,0xC0, 0xC1,0xC2,0xC4,0xC8,0xD0,0xE0, 0xE1,0xE2,0xE4,0xE8,0xF0,

N TT NGHIP
0xF1,0xF2,0xF4,0xF8, 0xF9,0xFA,0xFC, 0xFD,0xFE, 0xFF }

**Mi mt trng thi l mt gi tr trong mng, chng ta ch vic xut cc gi tr theo ng th t 0..35 t c hiu ng mong mun. (Quay li t u sau khi hin th ht d liu, mi trng thi u c tr hon thi gian quan st c kt qu). Cch 2: p dng lnh dch (<< v >>) trong C vit bi ton ny. Chng trnh c vit theo lu thut ton sau:
type3

j=0

j<number_period

False

End

True j = j + 1; i = 10 x = 0x00; y = 0x00

False

i >0 True i = i 1; k = 0; Dch phi 1 vo y; x = 0x00;

k < (i-2) True k =k+ 1;

False

Dch tri x, 1 im sng di chuyn; write_buf = x or y; Ghi ra port led; Tr hon thi gian;

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

N TT NGHIP 4. 8 LEDs dch chuyn mt dn; Cch 1: To mt mng bao gm c 36 trng thi khc nhau ca 8 bits sao cho c hiu ng dch chuyn mt dn. C tip tc theo ng s chu k ngi s dng mun. Cc trng thi tng ng nh mng s hex 8 bits sau:
char Data_Display_Type_3[36] = { 0xFF, 0xFE,0xFD, 0xFC,0xFA,0xF9, 0xF8,0xF4,0xF2,0xF1, 0xF0,0xE8,0xE4,0xE2,0xE1, 0xE0,0xD0,0xC8,0xC4,0xC2,0xC1, 0xC0,0xA0,0x90,0x84,0x82,0x81, 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }

**Mi mt trng thi l mt gi tr trong mng, chng ta ch vic xut cc gi tr theo ng th t 0..35 t c hiu ng mong mun. (Quay li t u sau khi hin th ht d liu, mi trng thi u c tr hon thi gian quan st c kt qu). Cch 2: p dng lnh dch (<< v >>) trong C vit bi ton ny. Chng trnh c vit theo lu thut ton sau:

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

N TT NGHIP

Cc hm dch bit: Mt im sng di chuyn, mt dim sng di chuyn ti v tr pos, dch tri bit c vo data c thc hin theo nhng lu sau:

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

True

N TT NGHIP
Dch tri c vo data 8 bits Dch tri data 8 bits 1 im sng di chuyn

data = data << 1;

data == 0x00 True

False

data = data or c;

data = data OR 1;

data = data << 1;

End Dch tri data 8 bits 1 im sng di chuyn ti v tr pos

End

data == 0x00 True data = data OR (1>>pos);

False

data = data << 1;

End

II. Thc hin: a. Kt ni phn cng: Cc bn thc hin kt ni phn cng theo s sau:
U1 PB8 PB10 PA23 PB16 PA24 PB11 PB9 PB7 VCC 9 8 7 6 5 4 3 2 1 19 A8 A7 A6 A5 A4 A3 A2 A1 DIR G 74HC245 B8 B7 B6 B5 B4 B3 B2 B1 11 12 13 14 15 16 17 18 D1 R1 D2 R2 330 R3 330 R4 330 R5 330 R6 330 R7 330 R8 330 330 D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED LED LED

**Lu phi ng s chn quy c.


b. Chng trnh driver: Tng t nh bi trc;

c. Chng trnh application: Cch 1: iu khin 8 LEDs bng cch xut trnh t cc d liu trng thi ra port; /*Chng trnh mang tn 1_3_OtherPortControl_Method_1.c*/ /*Khai bo th vin cn thit cho cc lnh trong chng trnh*/
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

N TT NGHIP
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h>

/*D liu trng thi LEDs cho hiu ng 1, 8 LEDs sng dn v tt ht*/
char Data_Display_Type_1[9] ={ 0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF };

/*D liu trng thi LEDs cho hiu ng 2, 8 LEDs sng dn v tt dn*/
char Data_Display_Type_2[15] = { 0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x7F,0xFF, 0xFE,0xFC,0xF8,0xE0,0xC0,0x80 };

/*D liu trng thi LEDs cho hiu ng 3, 8 LEDs sng dn*/
char Data_Display_Type_3[36] = { 0x00, 0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80, 0x81,0x82,0x84,0x90,0xA0,0xC0, 0xC1,0xC2,0xC4,0xC8,0xD0,0xE0, 0xE1,0xE2,0xE4,0xE8,0xF0, 0xF1,0xF2,0xF4,0xF8, 0xF9,0xFA,0xFC, 0xFD,0xFE, 0xFF };

/*D liu trng thi LEDs cho hiu ng 4, 8 LEDs dch chuyn mt dn*/
char Data_Display_Type_4[36] = { 0xFF, 0xFE,0xFD, 0xFC,0xFA,0xF9, 0xF8,0xF4,0xF2,0xF1, 0xF0,0xE8,0xE4,0xE2,0xE1, 0xE0,0xD0,0xC8,0xC4,0xC2,0xC1, 0xC0,0xA0,0x90,0x84,0x82,0x81, 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

10

N TT NGHIP
};

/*Bin lu s m t tp tin cho driver khi c m*/


int port_led_fd;

/*B nh m d liu cn ghi vo driver*/


char write_buf[1];

/*Chng trnh cho in thng bo hng dn s dng khi c li c php t ngi dng*/
void print_usage() { printf exit(0); } ( "OtherPortControl <type1|type2|type3|type4> <TimePeriod> <NumberPeriod>\n");

/*Hm main c khai bo dng tham s la chn, ly thng tin ngi dng*/
int main(int argc, char **argv) {

/*Bin time_period lu thi gian thay i trng thi;


bin number_period lu s chu k cn thc hin*/ long int time_period, number_period;

/*Cc bin m phc v cho truy xut d liu trng thi*/


int j; char i;

/*M tp tin thit b trc khi thao tc*/


if ((port_led_fd = open("/dev/port_led", O_RDWR)) < 0) { printf("Error device\n"); return -1; } whilst opening /dev/port_led

/*Kim tra c php nhp t ngi dng*/


if (argc != 4) { print_usage(); printf("%d\n",argc); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

11

N TT NGHIP
}

/*Ly thi gian tr hon t ngi dng*/


time_period = atoi(argv[2])*500;

/*Ly s chu k cn lp li t ngi dng*/


number_period = atoi(argv[3]);

/*So snh thc hin tng kiu hiu ng khc nhau da vo tham s
nhp t ngi dng*/

/*Trng hp 1: Hiu ng 8 LEDs sng dn tt ht*/


if (!strcmp(argv[1],"type1")) { for (j=0; j < number_period; j ++) { for (i=0; i < 9; i++) {

/*Cp nht thanh ghi m bng d liu trng


thi*/ write_buf[0] = Data_Display_Type_1[i];

/*Xut thanh ghi m sang driver*/


write(port_led_fd, write_buf, 1);

/*Tr hon thi gian bng time_period (ms)*/


usleep(time_period); }; };

/*Trng hp 2: Hiu ng 8 LEDs sng dn tt dn*/ /*Phng php iu khin cng tng t nh trng hp du tin*/
} else if (!strcmp(argv[1], "type2")) { for (j=0; j < number_period; j ++) { for (i=0; i < 15; i++) { write_buf[0] = Data_Display_Type_2[i]; write(port_led_fd, write_buf, 1); usleep(time_period); }; };

/*Trng hp 3: Hiu ng 8 LEDs sng dn*/


} else if (!strcmp(argv[1], "type3")) { for (j=0; j < number_period; j ++) { for (i=0; i < 36; i++) { write_buf[0] = Data_Display_Type_3[i]; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

12

N TT NGHIP
write(port_led_fd, write_buf, 1); usleep(time_period); }; };

/*Trng hp 4: HIu ng 8 LEDs dch chuyn mt dn*/


} else if (!strcmp(argv[1], "type4")) { for (j=0; j < number_period; j ++) { for (i=0; i < 36; i++) { write_buf[0] = Data_Display_Type_4[i]; write(port_led_fd, write_buf, 1); usleep(time_period); }; };

/*In ra thng bo li trong trng hp khng c lnh no h tr*/


} else { print_usage(); } return 0; }

Cch 2: iu khin 8 led bng lnh dch ( >> v <<); /*Chng trnh mang tn 1_3_OtherPortControl_Method_2.c*/ /*Khai bo th vin cn thit cho cc lnh dng trong chng trnh*/
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h>

/*Chng trnh cho in thng bo hng dn s dng khi c li c php t ngi dng*/
void print_usage() { printf( "OtherPortControl <type1|type2|type3|type4> <TimePeriod> <NumberPeriod>\n"); exit(0); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

13

N TT NGHIP
}

/*Hm dch tri c c vo data 8 bits*/


char shift_left_1_8bits_c(char data, char c) { return ((data<<1) | c); }

/*Hm dch phi c c vo data 8 bits*/


char shift_right_1_8bits_c(char data, char c) { return ((data>>1) | (c<<7)); }

/*Hm dch tri 1 im sng di chuyn trong data 8 bits*/


char shift_left_1_lighting_led_8bits(char data) { if (data == 0) { return (data | 1); } else { return (data<<1); } }

/*Hm dch phi mt im sng di chuyn trong data 8 bits*/


char shift_right_1_lighting_led_8bits(char data) { if (data == 0) { return (data | 0x80); } else { return (data>>1); } }

/*Hm dch tri mt dim sng di chuyn trong data 8 bits ti v tr pos (bit 0: pos=1, bit 1: pos=2, ...*/
char shift_left_1_lighting_at_position_led_8bits(char data, char pos) { if (data == 0) { return (data | (1>>pos)); } else { return (data<<1); } } ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

14

N TT NGHIP /*Hm dch phi mt dim sng di chuyn trong data 8 bits ti v tr pos (bit 0: pos=1, bit 1: pos=2, ...*/
char shift_right_1_lighting_at_position_led_8bits(char data, char pos) { if (data == 0) { return (data | (1<<pos)); } else { return (data>>1); } }

/*Chng trnh chnh main() khai bo di dng tham s nhp t ngi dng*/
int main(int argc, char **argv) {

/*Bin lu s m t tp tin thit b khi n c m*/


int port_led_fd;

/*Thanh ghi m ghi vo driver v cc bin ph thao tc bit*/


char write_buf[1], x, y;

/*Bin lu tr thi gian v s chu k ngi dng mong mun*/


long int time_period, number_period;

/*Cc bin m h tr thao tc d liu*/


int j; char i,k,l;

/*M tp tin thit b trc khi thao tc*/


if ((port_led_fd = open("/dev/port_led", O_RDWR)) < 0) { printf("Error device\n"); return -1; } whilst opening /dev/port_led

/*Kim tra li c php t ngi dng*/


if (argc != 4) { print_usage(); printf("%d\n",argc); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

15

N TT NGHIP
}

/*Ly thi gian chu k t ngi dng*/


time_period = atoi(argv[2])*500;

/*Ly s chu mong mun t ngi dng*/


number_period = atoi(argv[3]);

/*So snh cc trng hp lnh nhp t ngi dng*/ /*Trng hp 1: Hiu ng LEDs sng dn tt ht*/
if (!strcmp(argv[1],"type1")) { for (j=0; j < number_period; j ++) { write_buf[0] = 0x00; for (i=0; i<8; i++) { write(port_led_fd, write_buf, 1); usleep(time_period); write_buf[0]=shift_left_1_8bits_c(write_buf[0],1); } };

/*Trng hp 2: Hiu ng LEDs di chuyn sng dn sau tt dn*/


} else if (!strcmp(argv[1], "type2")) { for (j=0; j < number_period; j ++) { write_buf[0] = 0x00; for (i=0; i<16; i++) { write(port_led_fd, write_buf, 1); usleep(time_period); if (i<8) { write_buf[0]=shift_left_1_8bits_c(write_buf[0],1); } else { write_buf[0]=shift_left_1_8bits_c(write_buf[0],0); } } };

/*Trng hp 3: Hiu ng LEDs di chuyn sng dn*/


} else if (!strcmp(argv[1], "type3")) { for (j=0; j < number_period; j ++) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

16

N TT NGHIP
x = 0x00; y = 0x00; for (i=10;i>0;i--) { for (k=0;k<(i-2);k++) { x=shift_left_1_lighting_led_8bits (x); write_buf[0] = x | y; write(port_led_fd, write_buf, 1); usleep(time_period); } y = shift_right_1_8bits_c (y,1); x = 0x00; } }

/*Trng hp 4: Hiu ng LEDs di chuyn mt dn*/


} else if (!strcmp(argv[1], "type4")) { for (j=0; j < number_period; j ++) { x = 0x00; y = 0xFF; for (i=0;i<8;i++) { y = shift_left_1_8bits_c (y,0); x = 0x00; do { x= shift_right_1_lighting_at_position_led_8bits(x,i); write_buf[0] = x | y; write(port_led_fd, write_buf, 1); usleep(time_period); } while (x != 0x01); } } } else { print_usage(); } return 0; }

d. Bin dch v thc thi d n:


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

17

N TT NGHIP Bin dch driver: Mang tn port_led_dev.ko Chp driver bin dch thnh cng trong bi trc vo kt chun b ci t vo h thng. Bin dch application: Mang tn 1_3_Othercontrol_Method_1.c v
1_3_Othercontrol_Method_2.c

Tr vo th mc cha tp tin chng trnh, bin dch chng trnh ng dng vi lnh sau:
arm-none-linux-gnueabi-gcc Othercontrol_Method_1 arm-none-linux-gnueabi-gcc Othercontrol_Method_2 1_3_Othercontrol_Method_2.c o 1_3_Othercontrol_Method_1.c o

**Chng trnh bin dch thnh cng c tn l: Othercontrol_Method_1 v


Othercontrol_Method_2. ***Lu : cu lnh trong shell phi vit trn cng mt

dng. Thc thi chng trnh: Chp driver v chng trnh vo kit, thc thi v kim tra kt qu; Ci t driver vo kit theo lnh sau:
insmod port_led_dev.ko

Thay i quyn thc thi cho chng trnh ng dng:


chmod 777 Othercontrol_Method_1 chmod 777 Othercontrol_Method_2

Thc thi v kim tra kt qu: Thc thi chng trnh ng dng theo c php c quy nh, quan st v kim tra kt qu. **Chng ta thy 8 led nhp nhy 10 ln vi chu k 1s. Cc bn thay i chu k v s ln nhp nhy quan st kt qu. Nh vy, to ra nhiu hiu ng iu khin LEDs khc nhau, vic n gin nht l ch vic to ra cc trng thi iu khin mong mun, lu vo mt vng nh no , cng vic cui cng l nh thi xut cc trng thi ra LEDs hin th. Nhng cch ny ch hiu qu khi s lng LEDs iu khin l nh v trng thi LEDs xut ra khng mang tnh quy lut r rng. i vi nhng trng hp: s lng LEDs iu khin ln, hiu ng mang tnh quy lut th cch th 2 l ph hp

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

18

N TT NGHIP nht. Chng ta phi p dng cch no l ty trng hp, sao cho tn t dung lng b nh v thi gian thc hin l nh nht. III. Kt lun v bi tp: a. Kt lun: Trong bi ny, chng ta vit thnh cng cc chng trnh ng dng to ra nhiu hiu ng LEDs khc nhau da vo mt driver iu khin LEDs c. y cng l mc ch ca quyn sch ny: Vi vic thc hnh vit driver v chng trnh ng dng ngi hc c th t mnh nghin cu mt driver c sn vit chng trnh ng dng phc v nhu cu trong thc t. n y chng ta s tm ngng cng vic iu khin LEDs n bc sang mt i tng khc. l LEDs 7 on, c ng dng rt nhiu trong hin th thng tin s thp phn. b. Bi tp: 1. Da vo driver iu khin 16 LED c hon thnh trong bi luyn tp trc vit ng dng to ra cc hiu ng iu khin LEDs tng t nh trong v d trn (nhng l iu khin 16 LEDs n). Driver iu khin theo s kt ni sau:
U1 PB8 PB10 PA23 PB16 PA24 PB11 PB9 PB7 VCC 9 8 7 6 5 4 3 2 1 19 A8 A7 A6 A5 A4 A3 A2 A1 DIR G 74HC245 B8 B7 B6 B5 B4 B3 B2 B1 11 12 13 14 15 16 17 18 D1 R1 D2 R2 330 R3 330 R4 330 R5 330 R6 330 R7 330 R8 330 330 D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED LED LED PB0 PB2 PC5 PC6 PC7 PC4 PB3 PB1 VCC 9 8 7 6 5 4 3 2 1 19 U1 A8 A7 A6 A5 A4 A3 A2 A1 DIR G 74HC245 B8 B7 B6 B5 B4 B3 B2 B1 11 12 13 14 15 16 17 18 D1 R1 D2 R2 330 R3 330 R4 330 R5 330 R6 330 R7 330 R8 330 330 D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED LED LED

2. Vit chng trnh iu khin 8 LEDs vi cng yu cu nh v d trn nhng c chiu thay i, chuyn t dch tri sang dch phi, v ngc li. 3. Kt hp cc hiu ng trn thnh mt chui hiu ng lin tc, k tip nhau khng cn phi qua tham s chn la hiu ng. 4. Hy vit chng trnh iu khin 8, 16 LEDs sng dn t ngoi vo trong v t trong ra ngoi.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

19

N TT NGHIP 5. Hy vit chng trnh iu khin 8, 16 LEDs dch chuyn mt dn t ngoi vo trong v t trong ra ngoi.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

20

N TT NGHIP 1-4CI T THI GIAN DNG TIMER:

I. Phc tho d n: Trong nhng bi trc, thc hin tr hon thi gian chng ta thng dng k thut dng cc hm tr hon thi gian h tr sn trong user application. Thao tc vi thi gian cn c mt ng dng khc rt quan trng l nh thi gian thc hin tc v. Cng vic nh thi c th mang tnh chu k hoc khng mang tnh chu k. Trong bi ny chng ta s p dng k thut nh thi gian mang tnh cht chu k cp nht iu khin trng thi LEDs, thay v dng k thut tr hon thi gian thng thng. nh thi gian trong h thng Linux c hai cch thc hin, nh thi trong kernel driver (khng c s qun l ca h iu hnh) v nh thi trong user application (c s qun l ca h iu hnh). C hai cch iu c s dng trong bi ny. a. Yu cu d n: Ni dung iu khin LEDs trong bi ny khng c g mi, n gin vn l iu khin LEDs chp tt theo chu k thi gian c quy nh bi ngi s dng khi gi chng trnh ng dng thc thi. Ngi s dng gi chng trnh thc thi theo c php sau:
<tn chng trnh> <chu k>

Trong :
<tn chng trnh> l tn chng trnh sau khi c bin dch; <chu k> l thi gian tnh bng giy do ngi s dng nhp vo;

b. Phn cng nhim v: 1. Timer trong user application: Driver: Lm nhim v nhn d liu 8 bits t user application xut ra LEDs hin th, tng t nh driver port_led_dev.ko trong bi trc. Application: Nhn thng tin khong thi gian cp nht thay i trng thi LEDs. Thng tin ny s c chuyn thnh thi gian nh thi. User application s dng hm alarm() v hm signal() khi to nh thi. Hm alarm() lm
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

21

N TT NGHIP nhim v ci t thi gian xut hin tn hiu ngt SIGALRM. Khi xy ra tn hiu ngt SIGALRM, hm signal() s n bt v thc thi hm phc v ngt c ngi lp trnh quy nh. 2. Timer trong kernel driver: Driver: Nhn thng tin khong thi gian (tnh bng s) t ngi dng thng qua user application, ci t dnh thi thng qua ngt thi gian dng timer mm. u tin driver s tin hnh khi to timer da vo cc hm thao tc vi timer c tm hiu trong nhng bi trc. Sau mi ln n thi gian nh thi, driver cp nht trng thi LEDs. Driver c thay i thi gian cp nht khi giao din hm write() c gi bi user application. Application: Lc ny nhim v ca user application rt n gin, ch dng cp nht thi gian nh thi cho driver thay i trng thi LEDs hin th bng cch gi giao din hm write() mi khi chng trnh thc thi. II. Thc hin: Kt ni phn cng theo s sau:
U1 PB8 PB10 PA23 PB16 PA24 PB11 PB9 PB7 VCC 9 8 7 6 5 4 3 2 1 19 A8 A7 A6 A5 A4 A3 A2 A1 DIR G 74HC245 B8 B7 B6 B5 B4 B3 B2 B1 11 12 13 14 15 16 17 18 D1 R1 D2 R2 330 R3 330 R4 330 R5 330 R6 330 R7 330 R8 330 330 D3 LED D4 LED D5 LED D6 LED D7 LED D8 LED LED LED

1. Timer trong user application: a. Chng trnh driver: L driver port_led_dev.ko trong bi trc; b. Chng trnh user application: c tn 1_4_1_TimerLedControl.c /*Khai bo th vin cn dng cho cc hm trong chng trnh*/
#include <stdio.h> #include <stdlib.h> ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

22

N TT NGHIP
#include <unistd.h> #include <signal.h> //Th vin cho ham signal() #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h>

/*Bin lu s m t tp tin thit b c m khi thao tc*/


int port_led_fd;

/*B m ghi d liu sang driver xut ra LEDs*/


char write_buf[1];

/*Bin lu khong thi gian nh thi*/


long int time_period;

/*Bin lu trng thi o LEDs*/


int i=0;

/*Hm in ra hng dn cho ngi dng trong trng hp nhp sai c php*/
void print_usage() { printf("timer_led_control_app <TimePeriod>\n"); exit(0); }

/*Hm x l tn hiu ngt SIGALRM c ci t vo hm signal()*/


void catch_alarm(int sig_num) { if (i == 0) { i = 1;

/*In thng bo LEDs tt*/


printf ("LEDs are off\n");

/*Cp nht trng thi b ghi m*/


write_buf[0] = 0x00; } else { i = 0;

/*In thng bo LEDs sng*/


printf ("LEDs are on\n");

/*Cp nht trng thi b nh m */


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

23

N TT NGHIP
write_buf[0] = 0xFF; }

/*Ghi b nh m sang driver, xut hin th LEDs*/


write(port_led_fd, write_buf, 1);

/*Ci t li nh thi cho tn hiu SIGALRM*/


alarm (time_period); }

/*Chng trnh chnh, khai bo di dng tham s cho ngi dng la chn nhp tham s thi gian*/
int main(int argc, char **argv) {

/*Trc khi thao tc cn m tp tin thit b driver*/


if ((port_led_fd = open("/dev/port_led", O_RDWR)) < 0) { printf("Error device\n"); return -1; } whilst opening /dev/port_led

/*Kim tra li c php nhp t ngi dng*/


if (argc != 2) { print_usage(); }

/*Ly v thng tin thi gian nhp t ngi dng*/


time_period = atoi(argv[1]);

/*Ci t b nh thi tn hiu SIGALRM gn vi hm thc thi ngt catch_alarm()*/


signal (SIGALRM, catch_alarm);

/*Quy nh khong thi gian cho b nh thi*/


alarm (time_period); printf ("Go to death loop ...");

/*Vng lp busy, hoc c th lm cng vic khc trong khi b nh thi ang hot ng*/
while (1); } ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

24

N TT NGHIP c. Bin dch v thc thi chng trnh: Driver: Chp driver port_led_control.ko vo kit chun b ci t; Application: Bin dch tp tin chng trnh bng lnh sau:
arm-none-linux-gnueabie-gcc TimerLedControl_1 1_3_TimerLedControl_1.c o

Ci t driver vo h thng bng lnh sau: insmod port_led_control.ko Thc thi chng trnh: ./TimerLedControl_1.c 1 Chng ta thy LEDs sng tt theo chu k 1s, ng thi in ra cu thng bo trong mn hnh hin th nh sau:
./TimerLedControl_1 1 Go to death loop ... LEDs are off LEDs are on LEDs are off LEDs are on LEDs are off ...

(Chng trnh c tip tc in ra theo chu k 1s) Chng ta thy mc d chng trnh chnh i vo vng lp v tn (Go to death loop ...) nhng b nh thi vn cn hot ng v in ra cu thng bo ng thi iu khin LEDs sng tt theo chu k 1s cho n khi ngi dng kt thc chng trnh bng tn hiu ngt (bng cch dng lnh ctrl+C). 2. Timer trong driver: a. Chng trnh driver: /*Khai bo th vin cho cc lnh trong chng trnh*/
#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <asm/atomic.h> ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

25

N TT NGHIP
#include <linux/genhd.h> #include <linux/miscdevice.h> #include <linux/time.h> //Th vin dng cho timer #include <linux/jiffies.h> //Th vin cha ticks jiffies

/*Tn tp tin thit b*/


#define DRVNAME #define DEVNAME "timer_led_dev" "timer_led"

/*-------------Port Control-----------*/ /*nh ngha cc chn thao tc tng ng vi chn gpio*/


#define P00 #define P01 #define P02 #define P03 #define P04 #define P05 #define P06 #define P07 #define P0 AT91_PIN_PB8 AT91_PIN_PB10 AT91_PIN_PA23 AT91_PIN_PB16 AT91_PIN_PA24 AT91_PIN_PB11 AT91_PIN_PB9 AT91_PIN_PB7 (P00|P01|P02|P03|P04|P05|P06|P07)

/*Basic commands*/ /*nh ngha cc lnh set v clear PIN cn bn*/


#define SET_P00() #define SET_P01() #define SET_P02() #define SET_P03() #define SET_P04() #define SET_P05() #define SET_P06() #define SET_P07() #define CLEAR_P00() #define CLEAR_P01() #define CLEAR_P02() #define CLEAR_P03() gpio_set_value(P00,1) gpio_set_value(P01,1) gpio_set_value(P02,1) gpio_set_value(P03,1) gpio_set_value(P04,1) gpio_set_value(P05,1) gpio_set_value(P06,1) gpio_set_value(P07,1) gpio_set_value(P00,0) gpio_set_value(P01,0) gpio_set_value(P02,0) gpio_set_value(P03,0)

#define CLEAR_P04() gpio_set_value(P04,0) ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

26

N TT NGHIP
#define CLEAR_P05() #define CLEAR_P06() #define CLEAR_P07() gpio_set_value(P05,0) gpio_set_value(P06,0) gpio_set_value(P07,0)

/*Bin sa li trong qu trnh m thit b*/ /* Counter is 1, if the device is not opened and zero (or less) if opened. */
static atomic_t timer_led_open_cnt = ATOMIC_INIT(1);

/*Khai bo bin cu trc lu timer khi to tn my_timer*/


struct timer_list my_timer;

/*Thi gian khi to ngt cho mi chu k l 1s*/


int time_period=1;

/*Bin cp nht trng thi LEDs*/


int i=0;

/*Hm chuyn d liu 8 bit thnh trng thi tng ng ca LEDs*/


void timer_led_write_data_port(char data) { (data&(1<<0))? SET_P00():CLEAR_P00(); (data&(1<<1))? SET_P01():CLEAR_P01(); (data&(1<<2))? SET_P02():CLEAR_P02(); (data&(1<<3))? SET_P03():CLEAR_P03(); (data&(1<<4))? SET_P04():CLEAR_P04(); (data&(1<<5))? SET_P05():CLEAR_P05(); (data&(1<<6))? SET_P06():CLEAR_P06(); (data&(1<<7))? SET_P07():CLEAR_P07(); }

/*Khai bo v nh ngha hm phc v ngt cho timer (my_timer)*/


void my_timer_function (unsigned long data) {

/*Nu i = 0 th cho i = 1 cp nht LEDs tt v ngc li to hiu ng sng tt theo chu k thi gian nhp*/
if (i == 0) { i = 1; timer_led_write_data_port(0x00); } else { i = 0; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

27

N TT NGHIP
timer_led_write_data_port(0xFF); }

/*Chu k chp tt phi >= 1 */


if (time_period==0) { time_period = 1; }

/*Ci t li chu k ngt sau mi ln thc thi hm phc v ngt, to hiu ng sng tt lin tc, vi chu k l time_period giy*/
mod_timer (&my_timer, jiffies + time_period*HZ); }

/*Giao din hm write() lm nhim v cp nht thi gian ca mt chu k ngt do ngi s dng nhp vo thng qua user application*/
static ssize_t timer_led_write (struct file *filp, char __iomem buf[], size_t bufsize, loff_t *f_pos) { time_period = buf[0]; printk ("Timer period has just been set to %ds\n", time_period); return bufsize; }

/*Hm thc thi khi thit b c m*/


static int timer_led_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&timer_led_open_cnt)) { atomic_inc(&timer_led_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; } ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

28

N TT NGHIP /*Hm thc thi khi thit b c ng*/


static int timer_led_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&timer_led_open_cnt); return 0; }

/*Khai bo v cp nht tp tin lnh cho thit b*/


struct file_operations timer_led_fops = { .write .open .release }; = timer_led_write, = timer_led_open, = timer_led_close,

/*Gn tp tin lnh v tn thit b vo tp tin thit b s c to*/


static struct miscdevice timer_led_dev = { .minor .name .fops }; = MISC_DYNAMIC_MINOR, = "timer_led", = &timer_led_fops,

/*Hm c thc thi khi ci t driver vo h thng*/


static int __init timer_led_mod_init(void) {

/*Ci t cc thng s cho cc PIN mun thao tc l ng ra*/


gpio_request (P00, NULL); gpio_request (P01, NULL); gpio_request (P02, NULL); gpio_request (P03, NULL); gpio_request (P04, NULL); gpio_request (P05, NULL); gpio_request (P06, NULL); gpio_request (P07, NULL); at91_set_GPIO_periph (P00, 1); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

29

N TT NGHIP
at91_set_GPIO_periph (P01, 1); at91_set_GPIO_periph (P02, 1); at91_set_GPIO_periph (P03, 1); at91_set_GPIO_periph (P04, 1); at91_set_GPIO_periph (P05, 1); at91_set_GPIO_periph (P06, 1); at91_set_GPIO_periph (P07, 1); gpio_direction_output(P00, 0); gpio_direction_output(P01, 0); gpio_direction_output(P02, 0); gpio_direction_output(P03, 0); gpio_direction_output(P04, 0); gpio_direction_output(P05, 0); gpio_direction_output(P06, 0); gpio_direction_output(P07, 0);

/*Cc thao tc khi to timer*/ /*Yu cu kernel dnh mt vng nh lu timer sp c to*/
init_timer (&my_timer);

/*Cp nht thi gian s sinh ra ngt*/


my_timer.expires = jiffies + time_period*HZ;

/*Cp nht d liu cho hm phc v ngt*/


my_timer.data = 0;

/*Gn hm phc v ngt cho timer*/


my_timer.function = my_timer_function;

/*Cui cng kch hot timer hot ng trong h thng*/


add_timer (&my_timer);

/*ng k tp tin thit b c khai bo trong nhng bc u tin*/


return misc_register(&timer_led_dev); }

/*Hm c thc thi khi tho g thit b ra khi h thng*/


static void __exit timer_led_mod_exit(void) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

30

N TT NGHIP /*Trc khi tho g driver ra khi h thng, chng ta phi tho b timer ra, nu khng timer vn chy mc d driver khng cn tn ti trong h thng na. Dn n pht sinh li trong nhng ln ci t tip theo*/
del_timer_sync(&my_timer);

/*Thc hin lnh tho b driver ra khi h thng*/


misc_deregister(&timer_led_dev); } module_init (timer_led_mod_init); module_exit (timer_led_mod_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("coolwarmboy"); MODULE_DESCRIPTION("Character device for for generic gpio api");

b. Chng trnh application: /*Khai bo cc th vin cn dng trong chng trnh*/


#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>

/*Bin lu s m t tp tin khi thit b c m*/


int port_led_fd;

/*B m ghi c kch tht 1 byte*/


char write_buf[1];

/*Bin lu thi gian nhp vo t ngi dng*/


long int time_period;

/*Hm in thng bo hng dn*/


void print_usage() { printf("timer_led_control_app <TimePeriod>\n"); exit(0); } ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

31

N TT NGHIP /*Hm main() c s dng c tham s*/


int main(int argc, char **argv) {

/*M v kim tra li trong qu trnh m*/


if ((port_led_fd = open("/dev/timer_led", O_RDWR)) < 0) { printf("Error whilst opening /dev/port_led device\n"); return -1; }

/*Kim tra li c php nhp t ngi dng*/


if (argc != 2) { print_usage(); }

/*Lu thng tin thi gian nhp vo t ngi dng*/


time_period = atoi(argv[1]);

/*Cp nht b m ghi*/


write_buf[0] = time_period;

/*Ghi d liu trong b m sang driver*/


write (port_led_fd, write_buf, 1);

/*Tr v 0 trong trng hp khng xy ra li trong qu trnh thc thi lnh*/


return 0; }

c. Bin dch v thc thi chng trnh: Bin dch chng trnh driver v application tng t nh trong cc bi trc, y chng ta khng nhc li. Chp driver v applicaiton vo kit ci t v xem kt qu. Sau khi ci t driver vo h thng, 8 LEDs s sng tt vi chu k 1s (nh lp trnh). Chng ta thay i tn s chp tt bng cch chay chng trnh ng dng trn, theo c php c quy nh trong chng trnh:
<tn chng trnh> <thi gian tr hon> <tn chng trnh> l tn chng trnh ng dng sau khi bin dch; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

32

N TT NGHIP
<thi gian tr hon> l thi gian tr hon gia hai ln thay i trng thi;

III. Kt lun v bi tp: a. Kt lun: Trong bi ny chng ta thc hnh thnh cng cch s dng ngt thi gian trong c driver v application. Mi cch khc nhau iu c nhng u v nhc im ring trong qu trnh s dng. Tuy nhin hai cch ny c mt im yu chng l thi gian pht sinh ngt ti thiu l 1s i vi k thut alarm trong user application, 10ms i vi timer trong driver. Nhng ng dng i hi thi gian ngt ngn hn th khng cn ph hp vi k thut ny na. Chng ta s tm hiu k thut khc hiu qu hn trong nhng module iu khin khc. b. Bi tp: 1. Vit chng trnh s dng k thut alarm lp trnh hiu ng led sng dn, tt dn; sng dn; mt im sng dch chuyn mt dn; Vi driver c lp trnh trong bi iu khin 8 LEDs sng tt. Chu k ngt do ngi s dng quy nh trong lc thc thi. 2. Lp trnh tng t vi k thut ngt dng timer trong driver. **Cc bi tp ny iu da vo s kt ni phn cng trong hai v d trn.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

33

N TT NGHIP BI 2

GIAO TIP IU KHIN LED 7 ON RI


I. Phc tho d n: LEDs 7 on l mt trong nhng linh kin in t hin th thng tin ph bin. Cc thng tin hin th thng thng l cc s thp phn, mt s trng hp l s nh phn, thp lc phn, ... C nhiu cch hin th LEDs 7 on khc nhau, iu khin trc tip thng qua cc cng vo ra, v iu khin bng phng php qut. n gin, trong bi ny chng ta s nghin cu cch iu khin trc tip thng qua cc cng xut m 7 don ra LEDs thng thng. Lm nn tng cho phng php hin th bng phng php qut LEDs trong bi sau. Nhng kin thc v LED 7 on c nghin cu rt k trong nhng mn hc k thut s cn bn. Nn s khng c nhc li trong quyn sch ny m ch p dng vo hng dn thc hnh thao tc vi h thng nhng. a. Yu cu d n: D n ny s hng dn cch iu khin 2 LEDs 7 don ri hin th s nguyn t 00 n 99. Ngi dng s nhp 3 tham s: gii hn 1, gii hn 2 v chu k m (tnh bng ms). H thng s tin hnh m bt u t gii hn 1 n gii hn 2 vi tc m c quy dnh. Nu gii hn 1 ln hn gii hn 2 th chng trnh s thc hin m xung. Nu gii hn 1 nh hn gii hn 2 th chng trnh s thc hin m ln. Nu gii hn 1 bng gii hn 2 th hin th s gii hn 1 ra LEDs. C hai gii hn u nm trong khong t 00 n 99. C php lnh khi thc thi nh sau:
<tn chng trnh> <gii hn 1> <gii hn 2> <thi gian tr hon>

Trong :
<tn chng trnh> l tn chng trnh sau khi bin dch thnh cng; <gii hn 1> l gii hn u tin do ngi dng nhp vo t 00 n 99; <gii hn 2> l gii hn sau do ngi dng nhp vo c gi tr t 00 n 99;

b. Phn cng nhim v: Driver:


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

34

N TT NGHIP p dng giao din hm write() nhn d liu l s nguyn t 00 n 99 t user application, gii m sang s BCD trc khi chuyn thnh m 7 on hin th ra LEDs. Application: Nhn cc tham s t ngi dng nhp khi gi chng trnh thc thi. Thc hin m ln hay m xung ty thuc vo gi tr nhn c t tham s ngi dng. Dng giao din hm write() truyn s t 00 n 99 cho driver hin th ra LEDs. Chng trnh application thc hin theo lu sau:
Begin

Cp nht Lmt1, Lmt2 v TimePeriod

Counter = Lmt1

Truyn sang driver

Delay trong khong TimePeriod

Counter < Lmt2 True Counter=Counter+1

False

Counter > Lmt2 True Counter=Counter-1

False

Counter=Ltd2

Truyn sang driver

End

Delay trong khong TimePeriod

II. Thc hin: 1. Kt ni phn cng theo s sau:

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

35

N TT NGHIP
VCC_ARROW R1 280 PB8 R3 280 PB10 R5 280 PA23 R7 280 PB16 R9 280 PA24 R11 280 PB11 R13 280 PB9 g\ f\ D13 LED PB3 e\ D11 LED PC4 R14 280 g\ d\ D9 LED PC7 R12 280 f\ D14 LED c\ D7 LED PC6 R10 280 e\ D12 LED b\ D5 LED PC5 R8 280 d\ D10 LED a\ D3 LED PB2 R6 280 c\ D8 LED D1 LED PB0 R4 280 b\ D6 LED R2 280 a\ D4 LED D2 LED VCC_ARROW

LED 1
2. Vit chng trnh: Driver: Tn 2_Dis_Seg_led_dev.c

LED 2

/*Khai bo th vin cn dng cho cc hm trong chng trnh*/


#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <linux/genhd.h> #include <linux/miscdevice.h>

/*Tn driver thit b*/


#define DRVNAME #define DEVNAME "dis_seg_led_dev" "dis_seg_led"

/*Khai bo cc chn LEDs s dng tng ng vi chn trong chip*/ /*Khai bo cc chn ca LEDs th nht (LEDs chc)*/
#define A1 #define B1 #define C1 #define D1 #define E1 #define F1 #define G1 AT91_PIN_PB8 AT91_PIN_PB10 AT91_PIN_PA23 AT91_PIN_PB16 AT91_PIN_PA24 AT91_PIN_PB11 AT91_PIN_PB9

/*Khai bo cc chn ca LEDs th hai (LEDs n v)*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

36

N TT NGHIP
#define A2 #define B2 #define C2 #define D2 #define E2 #define F2 #define G2 AT91_PIN_PB0 AT91_PIN_PB2 AT91_PIN_PC5 AT91_PIN_PC6 AT91_PIN_PC7 AT91_PIN_PC4 AT91_PIN_PB3

/*Cc lnh set v clear bit cho cc chn ca LEDs 7 on*/ /*Basic commands*/ /*Cc lnh cho LEDs 1 */
#define SET_A1() #define SET_B1() #define SET_C1() #define SET_D1() #define SET_E1() #define SET_F1() #define SET_G1() #define CLEAR_A1() #define CLEAR_B1() #define CLEAR_C1() #define CLEAR_D1() #define CLEAR_E1() #define CLEAR_F1() #define CLEAR_G1() gpio_set_value(A1,1) gpio_set_value(B1,1) gpio_set_value(C1,1) gpio_set_value(D1,1) gpio_set_value(E1,1) gpio_set_value(F1,1) gpio_set_value(G1,1) gpio_set_value(A1,0) gpio_set_value(B1,0) gpio_set_value(C1,0) gpio_set_value(D1,0) gpio_set_value(E1,0) gpio_set_value(F1,0) gpio_set_value(G1,0)

/*Cc lnh cho LEDs 2*/


#define SET_A2() #define SET_B2() #define SET_C2() #define SET_D2() #define SET_E2() #define SET_F2() #define SET_G2() #define CLEAR_A2() gpio_set_value(A2,1) gpio_set_value(B2,1) gpio_set_value(C2,1) gpio_set_value(D2,1) gpio_set_value(E2,1) gpio_set_value(F2,1) gpio_set_value(G2,1) gpio_set_value(A2,0)

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

37

N TT NGHIP
#define CLEAR_B2() #define CLEAR_C2() #define CLEAR_D2() #define CLEAR_E2() #define CLEAR_F2() #define CLEAR_G2() gpio_set_value(B2,0) gpio_set_value(C2,0) gpio_set_value(D2,0) gpio_set_value(E2,0) gpio_set_value(F2,0) gpio_set_value(G2,0)

/* Counter is 1, if the device is not opened and zero (or less) if opened. */ static atomic_t dis_seg_led_open_cnt = ATOMIC_INIT(1);

/*nh ngha m LEDs 7 on tch cc mc thp*/


static int SSC[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};

/*Hm chuyn i d liu 8 bit thnh cc trng thi LEDs tng ng trong LEDs 7 on*/ /*Dnh cho LEDs 1*/
void dis_seg_led_write_data_led_1(char data) { (data&(1<<0))? SET_A1():CLEAR_A1(); (data&(1<<1))? SET_B1():CLEAR_B1(); (data&(1<<2))? SET_C1():CLEAR_C1(); (data&(1<<3))? SET_D1():CLEAR_D1(); (data&(1<<4))? SET_E1():CLEAR_E1(); (data&(1<<5))? SET_F1():CLEAR_F1(); (data&(1<<6))? SET_G1():CLEAR_G1(); }

/*Hm chuyn i dnh cho LEDs 2*/


void dis_seg_led_write_data_led_2(char data) { (data&(1<<0))? SET_A2():CLEAR_A2(); (data&(1<<1))? SET_B2():CLEAR_B2(); (data&(1<<2))? SET_C2():CLEAR_C2(); (data&(1<<3))? SET_D2():CLEAR_D2(); (data&(1<<4))? SET_E2():CLEAR_E2(); (data&(1<<5))? SET_F2():CLEAR_F2(); (data&(1<<6))? SET_G2():CLEAR_G2(); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

38

N TT NGHIP
}

/*Hm gii m s nguyn t 00 n 99 sang s BCD v vit trng thi ra lEDs vt l*/
void dis_seg_led_decode_and_write_to_led(char data) { dis_seg_led_write_data_led_1(SSC[data/10]); dis_seg_led_write_data_led_2(SSC[data%10]); }

/*Giao din hm write() nhn s nguyn t user application hin th ra LEDs 7 on*/
static ssize_t dis_seg_led_write (struct file *filp, char __iomem buf[], size_t bufsize, loff_t *f_pos) {

/*Gi hm chuyn i d liu ghi ra LEDs*/


dis_seg_led_decode_and_write_to_led(buf[0]); return bufsize; } static int dis_seg_led_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&dis_seg_led_open_cnt)) { atomic_inc(&dis_seg_led_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; } static int dis_seg_led_close(struct inode * inode, struct file * file) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

39

N TT NGHIP
smp_mb__before_atomic_inc(); atomic_inc(&dis_seg_led_open_cnt); return 0; } struct file_operations dis_seg_led_fops = { .write .open .release }; static struct miscdevice dis_seg_led_dev = { .minor .name .fops }; static int __init dis_seg_led_mod_init(void) { = MISC_DYNAMIC_MINOR, = "dis_seg_led", = &dis_seg_led_fops, = dis_seg_led_write, = dis_seg_led_open, = dis_seg_led_close,

/*Ci t cc chn gpio s dng thnh thnh ng ra*/


gpio_request (A1, NULL); gpio_request (B1, NULL); gpio_request (C1, NULL); gpio_request (D1, NULL); gpio_request (E1, NULL); gpio_request (F1, NULL); gpio_request (G1, NULL); at91_set_GPIO_periph (A1, 1); at91_set_GPIO_periph (B1, 1); at91_set_GPIO_periph (C1, 1); at91_set_GPIO_periph (D1, 1); at91_set_GPIO_periph (E1, 1); at91_set_GPIO_periph (F1, 1); at91_set_GPIO_periph (G1, 1); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

40

N TT NGHIP
gpio_direction_output(A1, 0); gpio_direction_output(B1, 0); gpio_direction_output(C1, 0); gpio_direction_output(D1, 0); gpio_direction_output(E1, 0); gpio_direction_output(F1, 0); gpio_direction_output(G1, 0); gpio_request (A2, NULL); gpio_request (B2, NULL); gpio_request (C2, NULL); gpio_request (D2, NULL); gpio_request (E2, NULL); gpio_request (F2, NULL); gpio_request (G2, NULL); at91_set_GPIO_periph (A2, 1); at91_set_GPIO_periph (B2, 1); at91_set_GPIO_periph (C2, 1); at91_set_GPIO_periph (D2, 1); at91_set_GPIO_periph (E2, 1); at91_set_GPIO_periph (F2, 1); at91_set_GPIO_periph (G2, 1); gpio_direction_output(A2, 0); gpio_direction_output(B2, 0); gpio_direction_output(C2, 0); gpio_direction_output(D2, 0); gpio_direction_output(E2, 0); gpio_direction_output(F2, 0); gpio_direction_output(G2, 0); return misc_register(&dis_seg_led_dev); } static void __exit dis_seg_led_mod_exit(void) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

41

N TT NGHIP
misc_deregister(&dis_seg_led_dev); } module_init (dis_seg_led_mod_init); module_exit (dis_seg_led_mod_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("coolwarmboy"); MODULE_DESCRIPTION("Character device for for generic gpio api");

Application: /*Khai bo th vin cn thit cho cc lnh cn dng trong chng trnh*/
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h>

/*Hm in ra hng dn khi ngi dng nhp sai c php*/


void print_usage() { printf("dis_seg_led_app <lmt1> <lmt2> <time_period>\n"); exit(0); } /*Chng trnh chnh, khai bo dng tham s cho ngi dng*/ int main(int argc, char **argv) {

/*Bin lu s m t tp tin, khi tp tin thit b c m*/


int dis_seg_led_fd;

/*B m ghi*/
char write_buf[1];

/*Thi gian thay i trng thi do ngni dng nhp vo*/


long int time_period; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

42

N TT NGHIP /*Cc bin phc v cho qu trnh m*/


char counter, lmt1, lmt2;

/*M tp tin thit b trc khi thao tc*/


if ((dis_seg_led_fd = open("/dev/dis_seg_led", O_RDWR)) < 0) { printf("Error whilst opening /dev/dis_seg_led device\n"); return -1; }

/*Kim tra li c php t ngi dng*/


if (argc != 4) { print_usage(); }

/*Cp nht cc tham s cn thit t ngi dng*/


lmt1 = atoi(argv[1]); lmt2 = atoi(argv[2]); time_period = atoi(argv[3])*1000;

/*Cho counter bng gii hn 1 */


counter = lmt1;

/*Cp nht trng thi LEDs ln u tin*/


write_buf[0] = counter; write(dis_seg_led_fd,write_buf,1); usleep(time_period);

/*Thc hin m theo yu cu ca thut ton trnh by*/


do { if (counter < lmt2) { counter++; } else { counter--; } write_buf[0] = counter; write(dis_seg_led_fd,write_buf,1); usleep(time_period);

/*Lin tc m cho n khi counter bng gii hn 2 */


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

43

N TT NGHIP
} while (counter != lmt2);

/*Tr v 0 khi khng c li trong qu trnh thc thi chng trnh */


return 0; }

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

44

N TT NGHIP

3. Bin dch v thc thi chng trnh: Bin dch thc thi v chy chng trnh trn kit, quan st kt qu. III. Kt lun v bi tp: a. Kt lun: Trong phn ny chng ta iu khin thnh cng module 2 LEDs 7 on ri hin th s cc s nguyn trong khong t 00 n 99 bng cc chn gpio thng qua giao din hm write giao tip gia application v driver. Trong trng hp c nhiu LEDs s lng IO khng , th chng ta s chuyn sang dng phng php khc ti u hn. Cng dng s lng chn l 16, chng ta c th iu khin 8 LEDs 7 on. Chng ta s nghin cu cch iu khin LEDs bng phng php qut trong bi sau. b. Bi tp: 1. Vit chng trnh driver iu khin 2 LEDs 7 on hin th thng tin l s hex trong khong t 00-FF. Sau vit chng trnh application vi cng tng nh trong bi v d trn: Ngi dng nhp vo hai tham s: Gii hn 1 v gii hn 2, l hai s hex trong khong t 00-FF; Chng trnh thc hin m ln hay m xung t gii hn 1 n gii hn 2; Khong thi gian gia hai ln thay i gi tr c quy nh bi ngi dng. 2. M rng driver v application trong v d trn c th hin th s m. Lc ny gi tr c th hin th trn LEDs c th nm trong khong t -9 n 99;

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

45

N TT NGHIP BI 3

GIAO TIP IU KHIN LED 7 ON BNG PHNG PHP QUT


I. Phc tho d n: Bi trc chng ta iu khin thnh cng 2 LEDs 7 on dng phng php thng thng l xut Port iu khin trc tip. Phng php ny tuy n gin nhng s lng io iu khin l rt ln trong trng hp c nhiu LEDs cn iu khin ng thi. Bi ny chng ta s tm s dng phng php qut iu khin ng thi 8 LEDs 7 on hin th thng tin. Phng php qut LEDs c chng ta nghin cu rt k trong mn hc thc tp vi x l 89XX51. Gio trnh ny s p dng thut ton ny vo lp trnh iu khin trong h thng nhng. Trong bi ny chng ta s s dng k thut ngt thi gian mi, dng timer vt l c tch hp sn trong vi iu khin. Do timer c s dng trong chng trnh lin quan n nhng chc nng ca h iu hnh nn chng ta phi t lp trnh chc nng ny thay v dng nhng hm c h tr sn. a. Yu cu d n: D n ny iu khin 8 LEDs 7 on bng phng php qut. Vi phng php iu khin ny, chng ta s lp trnh hin th nhiu hiu ng khc nhau: Hin th s 07101080 ra 8 LEDs; m hin th t XX n YY vi chu k Z do ngi dng quy nh; m gi pht giy hin th 8 LEDs;

b. Phn cng nhim v: Driver: Trong d n ny chng ta s dng chung mt driver. Driver ny c nhng c im sau: Driver dng phng php ngt thi gian timer 0, y l timer vt l tch hp trong vi iu khin. To chu k ngt 1ms, khi n thi im ngt, chng trnh s cp nht thay i trng thi qut LEDs hin th theo d liu c lu tr trong b nh m. Driver s dng hai giao din hm: ioctl() v write(). Trong : 46

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

N TT NGHIP Giao din hm write() nhn mng s nguyn trong khong t 0 n 9 bao gm 8 phn t tng ng vi 8 LEDs 7 on cn hin th. Hm s cp nht d liu trong b nh m hin th ngay sau khi nhn c mng thng tin t ngi dng. Nh vy nu user application mun hin th bt k s no ra LEDs th ch cn gn s vo b m ghi, sau gi giao din hm write() chuyn thng tin t b m ghi trong user sang b m nhn trong driver hin th ra LEDs. **Bn cnh cc s t 0 n 9, driver cn h tr hin th thm cc k t t bit, c quy nh bi nhng m s khc nhau: K t - c quy nh bi m s 10, k t _ c quy nh bi m s 11, k t (khong trng) c quy nh bi m s 12, v mt s k t khc nu mun chng ta c th thm vo. Giao din hm ioctl() thc hin nhiu chc nng khc nhau: 1. Tr hon thi gian vi phn gii 10ms. Ngi dng gi giao din ioctl() vi tham s lnh SWEEP_LED_DELAY v khong thi gian tr hon tng ng thc hin tr hon theo yu cu. 2. Nhn s nguyn (00000000 n 99999999) t user application gii m hin th ra LEDs 7 don. Ngi dng gi giao din ioctl() vi tham s lnh SWEEP_LED_NUMBER_DISPLAY v s nguyn mun hin th. Chng trnh driver s nhn thng tin ny, gii m v ghi vo b nh m hin th trong driver qut ra LEDs. 3. Nhn 3 s nguyn gi, pht, giy t user application, gii m v ghi vo b m hin th ra LEDs i dng HH-MM-SS. Chc nng ny c tham s lnh l SWEEP_LED_TIME_DISPLAY. Application: Trong d n ny chng ta s xy dng mt chng trnh application tng hp thc hin tt c cc hiu ng iu khin LEDs 7 on trn. Application s c xy dng da vo cu trc hm main() c nhiu tham s ngi dng nhp tham s thc thi chng trnh. Chng trnh s nhn tham s ny, la chn trng hp v p ng ng yu cu. C th tng chc nng nh sau: Hin th dy s 01234567 ra 8 LEDs 7 on: 47
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

N TT NGHIP Ngi dng nhp dng lnh theo c php sau:


./<Tn chng trnh> display_number

Trong :
<Tn chng trnh> l tn chng trnh application sau khi bin dch; displaynumber l tham s yu cu xut dy s;

Ngi lp trnh ch cn khai bo b m ghi l mt mng bao gm 8 thnh phn, mi phn t tng ng vi 1 LED. Cp nht b m ghi l cc s t 0 n 7. Cui cng gi giao din hm write() ghi b m ghi sang b m nhn trong dirver hin th ra LEDs. m hin th t XX n YY vi chu k T: Ngi dng nhp dng lnh shell theo c php:
./<Tn chng trnh> count_number XX YY T

Trong :
XX: L s gii hn 1; YY: L s gii hn 2; T: L chu k (n v l 10ms) thay i trng thi.

Chng trnh s m t XX n YY vi chu k m l Tx10ms. Mi ln cp nht trng thi chng trnh s gi giao din hm ioctl() yu cu driver gii m hin th LEDs. m gi pht giy hin th 8 LEDs 7 on: Ngi dng nhp dng lnh shell theo c php:
./<Tn chng trnh> count_time HH MM SS

Chng trnh thc hin m gi pht giy bt u , sau mi chu k 1s thng tin ny s c truyn qua driver. Ti y driver s gii m v hin th ra LEDs 7 on theo dng HH-MM-SS. II. Thc hin: 1. Kt ni phn cng theo s sau:

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

48

N TT NGHIP
J1 8 7 6 5 4 3 2 1 PB8 PB10 PA23 PB16 PA24 PB11 PB9 PB7 R300 R300 R300 R300 R300 R300 R300 R300 R1 R2 R3 R4 R5 R6 R7 R8 VCC Jump 8 R9 1K U1 A1015 8 3 5 R10 1K U2 A1015 8 3 5 VCC VCC R11 1K U3 A1015 8 3 5 R12 1K U4 A1015 8 3 5 VCC VCC R13 1K U5 A1015 8 3 5 VCC R14 1K U6 A1015 8 3 5 VCC R15 1K U7 A1015 8 3 5 VCC R16 1K U8 A1015 8 3 5 7 6 4 2 1 9 10 a b c d e f g + A Dp U16

7 6 4 2 1 9 10

a b c d e f g

7 6 4 2 1 9 10

a b c d e f g

7 6 4 2 1 9 10

a b c d e f g

7 6 4 2 1 9 10

a b c d e f g

7 6 4 2 1 9 10

a b c d e f g

7 6 4 2 1 9 10

a b c d e f g

7 6 4 2 1 9 10

+ A Dp

+ A Dp

+ A Dp

+ A Dp

+ A Dp

+ A Dp

a b c d e f g

U9 J2 8 7 6 5 4 3 2 1 PB0 PB2 PC5 PC6 PC7 PC4 PB3 PB1 R300 R300 R300 R300 R300 R300 R300 R300 R17 R18 R19 R20 R21 R22 R23 R24

U10

U11

U12

U13

U14

Jump 8

2. Chng trnh driver: /*Khai bo th vin cn thit cho cc lnh cn dng trong chng trnh */
#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <mach/at91_tc.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <linux/genhd.h> #include <linux/miscdevice.h> #include <asm/uaccess.h>

/*Cc th vin h tr cho ngt v tr hon thi gian*/


#include <linux/interrupt.h> //Cha hm h tr khai bo ngt #include <linux/clk.h> //Cha hm khi to clock #include <linux/irq.h> #include <linux/time.h> #include <linux/jiffies.h> #include <linux/sched.h> #include <linux/delay.h>

/*Tn driver thit b*/


#define DRVNAME "sweep_seg_led_dev"

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

+ A Dp U15

49

N TT NGHIP
#define DEVNAME "sweep_seg_led"

/*-------------Port Control-----------*/

/*Khai bo cc chn iu khin LEDs 7 on*/ /*Cc chn iu khin tch cc cho LEDs*/
#define P00 #define P01 #define P02 #define P03 #define P04 #define P05 #define P06 #define P07 AT91_PIN_PB8 AT91_PIN_PB10 AT91_PIN_PA23 AT91_PIN_PB16 AT91_PIN_PA24 AT91_PIN_PB11 AT91_PIN_PB9 AT91_PIN_PB7

/*Cc chn iu khin truyn d liu cho LEDs tch cc hin th*/
#define A #define B #define C #define D #define E #define F #define G AT91_PIN_PB0 AT91_PIN_PB2 AT91_PIN_PC5 AT91_PIN_PC6 AT91_PIN_PC7 AT91_PIN_PC4 AT91_PIN_PB3

/*Cc lnh c bn iu khin set() v clear() bit cho cc chn gpio*/


/*Basic commands*/

/*Lnh set() v clear() bit cho cc chn chn LEDs*/


#define SET_P00() #define SET_P01() #define SET_P02() #define SET_P03() #define SET_P04() #define SET_P05() #define SET_P06() #define SET_P07() #define CLEAR_P00() #define CLEAR_P01() #define CLEAR_P02() gpio_set_value(P00,1) gpio_set_value(P01,1) gpio_set_value(P02,1) gpio_set_value(P03,1) gpio_set_value(P04,1) gpio_set_value(P05,1) gpio_set_value(P06,1) gpio_set_value(P07,1) gpio_set_value(P00,0) gpio_set_value(P01,0) gpio_set_value(P02,0)

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

50

N TT NGHIP
#define CLEAR_P03() #define CLEAR_P04() #define CLEAR_P05() #define CLEAR_P06() #define CLEAR_P07() gpio_set_value(P03,0) gpio_set_value(P04,0) gpio_set_value(P05,0) gpio_set_value(P06,0) gpio_set_value(P07,0)

/*Cc lnh set() v clear() bit cho cc chn d liu LEDs*/


#define SET_A() #define SET_B() #define SET_C() #define SET_D() #define SET_E() #define SET_F() #define SET_G() #define CLEAR_A() #define CLEAR_B() #define CLEAR_C() #define CLEAR_D() #define CLEAR_E() #define CLEAR_F() #define CLEAR_G() gpio_set_value(A,1) gpio_set_value(B,1) gpio_set_value(C,1) gpio_set_value(D,1) gpio_set_value(E,1) gpio_set_value(F,1) gpio_set_value(G,1) gpio_set_value(A,0) gpio_set_value(B,0) gpio_set_value(C,0) gpio_set_value(D,0) gpio_set_value(E,0) gpio_set_value(F,0) gpio_set_value(G,0)

/*nh ngha cc s nh danh lnh cho giao din hm ioctl() */


#define SWEEP_LED_DEV_MAGIC 'B' #define SWEEP_LED_DELAY _IO(SWEEP_LED_DEV_MAGIC, 0) #define SWEEP_LED_NUMBER_DISPLAY _IO(SWEEP_LED_DEV_MAGIC, 1) #define SWEEP_LED_TIME_DISPLAY _IO(SWEEP_LED_DEV_MAGIC, 2)

/* Counter is 1, if the device is not opened and zero (or less) if opened. */
static atomic_t sweep_seg_led_open_cnt = ATOMIC_INIT(1);

/*B nh m hin th trong driver, cha nhng s nguyn c gii m sang LEDs 7 on*/
unsigned char DataDisplay[8]={0,1,2,3,4,5,6,7};

/*B gii m LEDs 7 on, bao gm cc m 7 on t 0 n 9, cc k t c bit -, _ v k t rng*/


unsigned char SevSegCode[]= { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x3F, 0x77, 0xFF}; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

51

N TT NGHIP /*Bin lu trng thi LEDs tch cc*/


int i;

/*Con tr nn ca thanh ghi iu khin timer0 tch hp trong vi iu khin*/


void __iomem *at91tc0_base;

/*Con tr cu trc clock ca timer0*/


struct clk *at91tc0_clk;

/*Hm tr hon thi gian dng jiffies trong kernel, thay th cho cc hm tr hon thi gian trong user; Hm tr hon thi gian c phn gii 10ms*/
void sweep_led_delay(unsigned int delay) {

/*Khai bo bin lu thi im tng lai cn tr hon*/


long int time_delay;

/*Cp nht thi im tng lai cn tr hon*/


time_delay = jiffies + delay;

/*So snh thi im hin ti vi thi im tng lai*/


while (time_before(jiffies, time_delay)) {

/*Thc hin chia tin trnh trong qu trnh tr hon thi gian*/
schedule(); } }

/*Hm ghi d liu 8 bits cho LEDs tch cc hin th*/


void sweep_seg_led_write_data_active_led(char data) { (data&(1<<0))? SET_P00():CLEAR_P00(); (data&(1<<1))? SET_P01():CLEAR_P01(); (data&(1<<2))? SET_P02():CLEAR_P02(); (data&(1<<3))? SET_P03():CLEAR_P03(); (data&(1<<4))? SET_P04():CLEAR_P04(); (data&(1<<5))? SET_P05():CLEAR_P05(); (data&(1<<6))? SET_P06():CLEAR_P06(); (data&(1<<7))? SET_P07():CLEAR_P07(); }

/*Hm ghi d liu m 7 on cho LEDS hin th*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

52

N TT NGHIP
void sweep_seg_led_write_data_led(char data) { (data&(1<<0))? SET_A():CLEAR_A(); (data&(1<<1))? SET_B():CLEAR_B(); (data&(1<<2))? SET_C():CLEAR_C(); (data&(1<<3))? SET_D():CLEAR_D(); (data&(1<<4))? SET_E():CLEAR_E(); (data&(1<<5))? SET_F():CLEAR_F(); (data&(1<<6))? SET_G():CLEAR_G(); }

/*Hm chn LEDs tch cc*/


void active_led_choice(char number) { sweep_seg_led_write_data_active_led(~(1<<(number))); }

/*Hm xut d liu cho LEDs hin th*/


void data_led_stransmitt (char data) { sweep_seg_led_write_data_led (SevSegCode[data]); }

/*Gii m s 8 ch s sang tng k t s BCD, lu vo vng nh m hin th LEDs*/


void sweep_led_number_display (unsigned long int data) { DataDisplay[0] = data % 10; DataDisplay[1] = (data % 100)/10; DataDisplay[2] = (data % 1000)/100; DataDisplay[3] = (data % 10000)/1000; DataDisplay[4] = (data % 100000)/10000; DataDisplay[5] = (data % 1000000)/100000; DataDisplay[6] = (data % 10000000)/1000000; DataDisplay[7] = data/10000000; }

/*Gii m gi pht giy thnh nhng k s BCD, v k t c bit lu vo vng nh m hin th LEDs*/
void sweep_led_time_display(int hh, int mm, int ss) { DataDisplay[0] = ss%10; DataDisplay[1] = ss/10; DataDisplay[2] = 10; //K t - ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

53

N TT NGHIP
DataDisplay[3] = mm%10; DataDisplay[4] = mm/10; DataDisplay[5] = 10; //K t - DataDisplay[6] = hh%10; DataDisplay[7] = hh/10; }

/*Hm phc v ngt timer thc hin qut LEDs 7 on, ti mt thi im ch hin th 1 LEDs vi m 7 on ca LED */
static irqreturn_t at91tc0_isr(int irq, void *dev_id) { int status;

/*c thanh ghi trng thi ca timer0 reset li timer sau khi xy ra ngt*/
status = ioread32(at91tc0_base + AT91_TC_SR);

/*Truyn d liu cho LEDs i*/


data_led_stransmitt(DataDisplay[i]);

/*Chn tch cc cho LEDs i*/


active_led_choice(i);

/*Cp nht bin trng thi cho LEDs tip theo*/


i++;

/*Gii hn s LEDs hin th*/


if (i==8) i = 0;

/*Kt thc qu trnh ngt tr li chng trnh driver chnh*/


return IRQ_HANDLED; }

/*Khai bo v nh ngha giao din hm write(), nhn d liu t user application l mt mng 8 bytes cp nht vo b nh m ghi trong driver*/
static unsigned *f_pos) { ssize_t char dis_seg_led_write __iomem buf[], (struct file *filp, loff_t size_t bufsize,

/*B nh m ghi nhn d liu t user*/


unsigned char write_buf[8];

/*Bin lu kch tht tr v khi ghi thnh cng*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

54

N TT NGHIP
int write_size = 0; int i;

/*Thc hin hm copy_from_user() nhn d liu t user n driver */


if (copy_from_user (write_buf, buf, 8) != 0) { return -EFAULT; } else { write_size = bufsize; }

/*Chuyn d liu t b m ghi sang b m hin th LEDs */


for (i=0; i<8; i++) { DataDisplay[i] = write_buf [i]; } return write_size; }

/*Khai bo v nh ngha giao din hm ioctl()*/


static int sweep_seg_led_ioctl(struct inode * inode, struct file * file, unsigned int cmd,unsigned long int arg[]) { int retval=0; switch (cmd) {

/*Trong trng hp lnh delay trong kernel, gi hm sweep_led_delay*/


case SWEEP_LED_DELAY: sweep_led_delay(arg[0]); break;

/*Trong trng hp lnh xut s hin th, gi hm sweep_led_number_display() gii m v cp nht thng tin cho b m hin th LEDs*/
case SWEEP_LED_NUMBER_DISPLAY: sweep_led_number_display(arg[0]); break;

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

55

N TT NGHIP /*Trong trng hp hin th thi gian, gi hm

sweep_led_time_display() gii m v xut ra b nh m hin th dng HH-MM-SS*/


case SWEEP_LED_TIME_DISPLAY: sweep_led_time_display(arg[0], arg[2]); break; arg[1],

/*Trong trng hp khng c lnh h tr th in ra li cho ngi lp trnh*/


default: printk("The exist\n"); retval=-1; break; } } function you type does not

/*Khai bo v nh ngha giao din hm open() */


static int sweep_seg_led_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&sweep_seg_led_open_cnt)) { atomic_inc(&sweep_seg_led_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; }

/*Khai bo v nh ngha giao din hm close*/


static int ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

56

N TT NGHIP
sweep_seg_led_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&sweep_seg_led_open_cnt); return 0; }

/*nh ngha v cp nht cu trc file operations */


struct file_operations sweep_seg_led_fops = { .write .ioctl .open }; = dis_seg_led_write, = sweep_seg_led_ioctl, = sweep_seg_led_open,

.release = sweep_seg_led_close,

/*nh ngha v cp nht cu trc i_node */


static struct miscdevice sweep_seg_led_dev = { .minor .name .fops }; = MISC_DYNAMIC_MINOR, = "sweep_seg_led", = &sweep_seg_led_fops,

/*Hm thc thi khi driver c ci t vo h thng*/


static int __init sweep_seg_led_mod_init(void) { int ret=0;

/*Khai bo cc chn trong gpio nh ngha thnh ch ng ra */


gpio_request (P00, NULL); gpio_request (P01, NULL); gpio_request (P02, NULL); gpio_request (P03, NULL); gpio_request (P04, NULL); gpio_request (P05, NULL); gpio_request (P06, NULL); gpio_request (P07, NULL);

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

57

N TT NGHIP
at91_set_GPIO_periph (P00, 1); at91_set_GPIO_periph (P01, 1); at91_set_GPIO_periph (P02, 1); at91_set_GPIO_periph (P03, 1); at91_set_GPIO_periph (P04, 1); at91_set_GPIO_periph (P05, 1); at91_set_GPIO_periph (P06, 1); at91_set_GPIO_periph (P07, 1);

gpio_direction_output(P00, 0); gpio_direction_output(P01, 0); gpio_direction_output(P02, 0); gpio_direction_output(P03, 0); gpio_direction_output(P04, 0); gpio_direction_output(P05, 0); gpio_direction_output(P06, 0); gpio_direction_output(P07, 0); gpio_request (A, NULL); gpio_request (B, NULL); gpio_request (C, NULL); gpio_request (D, NULL); gpio_request (E, NULL); gpio_request (F, NULL); gpio_request (G, NULL); at91_set_GPIO_periph (A, 1); at91_set_GPIO_periph (B, 1); at91_set_GPIO_periph (C, 1); at91_set_GPIO_periph (D, 1); at91_set_GPIO_periph (E, 1); at91_set_GPIO_periph (F, 1); at91_set_GPIO_periph (G, 1); gpio_direction_output(A, 0); gpio_direction_output(B, 0); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

58

N TT NGHIP
gpio_direction_output(C, 0); gpio_direction_output(D, 0); gpio_direction_output(E, 0); gpio_direction_output(F, 0); gpio_direction_output(G, 0);

/*Khai bo timer0 cho h thng*/


at91tc0_clk = clk_get(NULL,tc0_clk");

/*Cho php clock hot ng*/


clk_enable(at91tc0_clk);

/*Di chuyn con tr timer0 n a ch thanh ghi nn cho timer counter 0*/
at91tc0_base 64); = ioremap_nocache(AT91SAM9260_BASE_TC0,

/*Kim tra li trong qu trnh nh v*/


if (at91tc0_base == NULL) { printk(KERN_INFO failed\n"); ret = -EACCES; goto exit_5; } "at91adc: TC0 memory mapping

/*Cp nht thng s cho timer, khi to nh thi ngt timer0 vi chu k ngt l 1ms*/
// Configure TC0 in waveform mode, TIMER_CLK1 and to generate interrupt on RC compare. // Load 50000 to RC so that with TIMER_CLK1 = MCK/2 = 50MHz, the interrupt will be // generated every 1/50MHz * 50000 = 20nS * 50000 = 1 milli second. // NOTE: Even though AT91_TC_RC is a 32-bit register, only 16-bits are programmble. iowrite32(50000, (at91tc0_base + AT91_TC_RC)); iowrite32((AT91_TC_WAVE | AT91_TC_WAVESEL_UP_AUTO), (at91tc0_base + AT91_TC_CMR)); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

59

N TT NGHIP
iowrite32(AT91_TC_CPCS, (at91tc0_base + AT91_TC_IER)); iowrite32((AT91_TC_SWTRG (at91tc0_base + AT91_TC_CCR)); | AT91_TC_CLKEN),

//Khi to ngt cho timer0


ret = request_irq(AT91SAM9260_ID_TC0, //ID ngt timer0 at91tc0_isr, //Tr n hm phc v ngt 0, // nh ngha c ngt c th chia s "sweep_seg_led_irq",/*Tn ngt hin th trong /proc/interrupts*/ NULL); //D liu ring trong qu trnh chia s ngt

/*In ra thng bo li nu khi to ngt khng thnh cng*/


if (ret != 0) { printk(KERN_INFO ret = -EBUSY; goto exit_6; } "sweep_seg_led_irq: Timer interrupt request failed\n");

/*ng k thit b vo h thng*/


ret = misc_register(&sweep_seg_led_dev);

/*In thng bo cho ngi dng khi thit b ci t thnh cng*/


printk(KERN_INFO "sweep_seg_led: Loaded module\n"); return ret;

/*Gii phng b nh khi c li xy ra*/


exit_6: iounmap(at91tc0_base); exit_5: clk_disable(at91tc0_clk); return ret; }

/*Hm c thc thi khi tho g driver ra khi h thng */


static void __exit sweep_seg_led_mod_exit(void) {

/*Gii phng vng nh dnh cho timer0*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

60

N TT NGHIP
iounmap(at91tc0_base);

/*Gii phng clock dnh cho timer0*/


clk_disable(at91tc0_clk);

/*Gii phng ngt dnh cho timer0*/


free_irq( AT91SAM9260_ID_TC0, // Interrupt number NULL); // Private data for shared interrupts

/*Tho driver ra h thng*/


misc_deregister(&sweep_seg_led_dev);

/*In thng bo cho ngi dng driver c tho g */


printk(KERN_INFO "sweep_seg_led: Unloaded module\n"); }

/*Ci t cc hm vo cc macro init v exit*/


module_init (sweep_seg_led_mod_init); module_exit (sweep_seg_led_mod_exit);

/*Cc thng tin khi qut cho driver */


MODULE_LICENSE("GPL"); MODULE_AUTHOR("coolwarmboy"); MODULE_DESCRIPTION("Character device for for generic gpio api");

3. Chng trnh application: /*Khai bo th vin cn thit cho cc lnh dng trong chng trnh*/
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h>

/*Khai bo s nh danh lnh dng cho hm ioctl*/


#define SWEEP_LED_DEV_MAGIC 'B' #define SWEEP_LED_DELAY _IO(SWEEP_LED_DEV_MAGIC, 0) #define SWEEP_LED_NUMBER_DISPLAY _IO(SWEEP_LED_DEV_MAGIC, 1) #define SWEEP_LED_TIME_DISPLAY _IO(SWEEP_LED_DEV_MAGIC, 2)

/*Bin lu s m t tp tin thit b khi c m*/


int sweep_seg_led_fd;

/*B nh m d liu cho hm ioctl() chp qua user*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

61

N TT NGHIP
unsigned long int ioctl_buf[3]={0,0,0};

/*B nh m cho hm write cha d liu cn hin th ra LEDs*/


unsigned char write_buf[8]={0,8,0,1,0,1,7,0};

/*Cc bin phc v cho chc nng m ca chng trnh*/


unsigned long XX, YY, T, counter;

/*Cc bin phc v cho chc nng m thi gian ca chng trnh*/
unsigned char HH, MM, SS;

/*Hm in hng dn cho ngi dng trong trng hp pht sinh li c php*/
int print_usage (void) { printf ("display_number|count_number|count_time YY|MM T|SS)\n"); return -1; } (XX|HH

/*Hm delay trong user, gi hm delay trong driver*/


void user_delay(unsigned long int delay) { ioctl_buf[0] = delay; ioctl (sweep_seg_led_fd, SWEEP_LED_DELAY, ioctl_buf); }

/*Hm truyn cc thng s gi pht giy sang b nh m*/


void user_transmit_time(unsigned long int HH, unsigned long int MM, unsigned long int SS) { ioctl_buf[0] = HH; ioctl_buf[1] = MM; ioctl_buf[2] = SS; ioctl(sweep_seg_led_fd,SWEEP_LED_TIME_DISPLAY,ioctl_buf ); }

/*Hm main() c khai bo dng tham s nhp t ngi dng la chn chc nng thc thi, v cc thng s cn thit cho tng chc nng */
int main(int argc, char **argv) { int res; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

62

N TT NGHIP /*Trc khi thao tc th phi m tp tin thit b, ng thi kim


tra li trong qu trnh m*/ if { printf("Error device\n"); return -1; } whilst opening /dev/sweep_seg_led ((sweep_seg_led_fd = open("/dev/sweep_seg_led", O_RDWR)) < 0)

/*Phn bit cc trng hp lnh khc nhau*/


switch (argc) { case 2:

/*Thc hin chc nng hin th m s sinh vin*/


if (!strcmp(argv[1], "display_number")) {

/*Gi giao din hm write() ghi vng nh m t user sang driver*/


write (sweep_seg_led_fd, write_buf, 8); } else { return print_usage(); } break; case 5:

/*Trong trng hp m s hin th LEDs*/


if (!strcmp(argv[1], "count_number")) {

/*Cp nht cc tham s t ngi dng*/


T = atoi(argv[4]); XX = atoi(argv[2]); YY = atoi(argv[3]); counter = XX;

/*Thc hin m theo quy nh ca ngi dng*/


while (counter != YY) { ioctl_buf[0] = counter; ioct(sweep_seg_led_fd, SWEEP_LED_NUMBER_DISPLAY, ioctl_buf); user_delay(T); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

63

N TT NGHIP
if (counter < YY) { counter++; } else { counter--; } } ioctl_buf[0] = counter; ioctl(sweep_seg_led_fd, SWEEP_LED_NUMBER_DISPLAY, ioctl_buf);

/*Chc nng m thi gian hin th LEDs*/


} else if (!strcmp(argv[1], "count_time")) {

/*Cp nht gi pht giy t ngi dng*/


HH = atoi(argv[2]); MM = atoi(argv[3]); SS = atoi(argv[4]);

/*Chuyn sang vng nh m ca ioctl()*/


user_transmit_time(HH,MM,SS); user_delay(100);

/*Thc hin m thi gian gi pht giy*/


while (1) { if (SS++ == 59) { SS = 0; if (MM++ == 59) { MM = 0; if (HH++ == 23) HH = 0; } } user_transmit_time(HH,MM,SS); user_delay(100); } } else { return print_usage(); } break; default: return print_usage(); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

64

N TT NGHIP
break; } return 0; }

4. Bin dch v thc thi chng trnh: Bin dch driver bng tp tin Makefile c ni dung sau:
export ARCH=arm export CROSS_COMPILE=arm-none-linux-gnueabiobj-m += 3_Sweep_Seg_led_dev.o all: make -C /home/arm/project/kernel/linux-2.6.30 M=$(PWD) modules clean: make -C /home/arm/project/kernel/linux-2.6.30 M=$(PWD) clean

Bin dch chng trnh ng dng bng dng lnh sau:


arm-none-linux-gnueabi-gcc Sweep_Seg_led_app 3_Sweep_Seg_led_app.c o

Chp tp tin driver v application sau khi bin dch vo kit; Ci t driver vo h thng bng lnh:
insmod 3_Sweep_Seg_led_dev.ko

Chy chng trnh ng dng: Chc nng hin th s:


./Sweep_Seg_led_app display_number

Chc nng m s hin th:


./Sweep_Seg_led_app count_number 1 10 100

Chc nng m thi gian:


./Sweep_Seg_led_app count_time 12 12 12

Ngi hc quan st v kim tra kt qu thc thi d n. 5. Kt lun v bi tp: a. Kt lun: Trong bi ny chng ta iu khin thnh cng 8 LEDs 7 on dng phng php qut. Kin thc quan trng nht trong bi, bn cnh phng php qut led, l cch khi to ngt t timer vt l tch hp trong vi iu khin. Ngi hc cn phi
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

65

N TT NGHIP hiu r cc bc khi to ngt, cch ci t cc thng s cho timer t c cc khong thi gian ngt cn thit b. Bi tp: 1. Ci tin driver iu khin qut LEDs 7 on 3_Sweep_Seg_led_dev.c trn sao cho c th xa c s 0 v ngha khi hin th s. 2. Ci tin driver iu khin qut LEDs 7 on 3_Sweep_Seg_led_dev.c trn sao cho c th hin th c s m trn 8 LEDs 7 on. 3. Vit chng trnh ng dng user application thc hin cc php ton + x v : kt qu hin th trn LEDs 7 on. Cc ton hng c nhp t ngi dng.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

66

N TT NGHIP BI 4

GIAO TIP IU KHIN LCD 16x2


I. Phc tho d n: Bng phng php truy xut cc chn gpio theo mt quy lut no chng ta c th iu khin nhiu thit b khc nhau. Trong nhng bi trc, chng ta iu khin LEDs n, LEDs 7 on, trong bi ny chng ta s thc hnh iu khin mt thit b hin th khc l LCD thuc loi 16x2. L thuyt v nguyn l hot ng ca LCD c nghin cu trong cc ti liu chuyn ngnh khc, hoc cc bn c th tham kho trong datasheet ca thit b. y chng ta khng nhc li m ch tp vo vit dirver v chng trnh iu khin trong h thng nhng. Cc lnh thao tc s c gii thch k trong qu trnh lp trnh. a. Yu cu d n: D n iu khin LCD bao gm cc chc nng sau: Hin th thng tin nhp vo t ngi dng: Ngi dng nhp vo mt chui k t trong mn hnh console (terminal display), chui k t ny c xut hin trong LCD. Cc thng s v ngy thng nm ca h thng c cp nht v hin th m hin th trn LCD: Ngi dng s nhp cc thng s v chu k, gii trong LCD. hn 1, gii hn 2. Thc hin m tng t nh thut ton ca bi qut LEDs 7 on. Cc thng s ny u c hin th trn LCDs. Sau y chng ta s tin hnh phn cng nhim v thc hin ca driver v application. b. Phn cng nhim v: Driver: S dng giao din ioctl() thc hin cc thao tc iu khin LCD c bn nh: Nhn m lnh iu khin t user application sau xut ra cc chn gpio ghi vo thanh ghi lnh ca LCDs;
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

67

N TT NGHIP Nhn d liu k t t user application, xut ra cc chn gpio ghi vo thanh ghi d liu ca LCDs; V mt s lnh khc nh: Tr hon thi gian dng jiffies, di chuyn con tr v u dng hin th, bt tt hin th, ... Application: Chng trnh trong application s dng nhng chc nng ca driver h tr, lp trnh thnh nhng hm c kh nng ln hn thc hin nhng yu cu ca d n. Chng trnh dng phng php lp trnh c tham s la chn t ngi dng thc hin nhim v theo yu cu. Nhng nhim v l: Hin th thng tin t ngi dng: Ngi dng chy chng trnh theo c php sau:
<tn chng trnh> display_string <Chui_k_t_cn_hin_th>

Trong :
<Tn chng trnh> l tn chng trnh ng dng sau khi bin dch; < Chui_k_t_cn_hin_th> l chui thng tin ngi dng mun hin

th ra LCD;
display_string l tham s chc nng phi nhp thc hin nhim v;

Sau khi nhn c yu cu, chng trnh s tch tng k t trong chui va nhp ln lt hin th trn LCDs. Hin th cc thng s ngy thng nm ca h thng ra LCD: Ngi dng nhp c php thc thi chng trnh nh sau:
<tn chng trnh> display_time

Trong :
display_time l tham s chc nng phi nhp thc hin nhim v;

Ngy thng nm c hin th trn LCD c dng:


The present time is: DD/MM/YYYY

m hin th trn LCD: Ngi dng nhp lnh thc thi chng trnh theo c php:
<tn chng trnh> display_counter XX YY T

Trong :
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

68

N TT NGHIP
display_counter l tham s chc nng cn phi nhp thc hin nhim

v;
XX l gii hn 1; YY l gii hn 2;

(**Gii hn 1 v gii hn 2 nm trong khong t 00 n 99);


T l chu k thay i trng thi m, n v l ms;

Chng trnh s thc hin m t XX n YY vi chu k thay i l T(ms). Hin th trn LCD theo dng: Hng 1: XX YY Hng 2: <counter display>

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

69

N TT NGHIP

II. Thc hin: 1. Kt ni phn cng theo s sau:


U1 LCD

LCD
K A D7 D6 D5 D4 D3 D2 D1 D0 E RW RS VEE VDD VSS VCC VCC 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

0
PB11 PA24 PB16 PA23 PB10 PB9 PB8

R1 Bien tro

2. Chng trnh driver:


#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <asm/uaccess.h> #include <asm/io.h> #include <asm/gpio.h> #include <linux/genhd.h> #include <linux/miscdevice.h> #include <asm/atomic.h> #include <linux/jiffies.h> #include <linux/sched.h> #define DRVNAME #define DEVNAME "LCDDriver" "LCDDevice"

/*-------------LCD COMMAND DEFINED---------------*/ #define IOC_LCDDEVICE_MAGIC #define LCD_CONTROL_WRITE #define LCD_DATA_WRITE #define LCD_INIT #define LCD_HOME #define LCD_CLEAR 'B' _IO(IOC_LCDDEVICE_MAGIC, 15) _IO(IOC_LCDDEVICE_MAGIC, 16) _IO(IOC_LCDDEVICE_MAGIC, 17) _IO(IOC_LCDDEVICE_MAGIC, 18) _IO(IOC_LCDDEVICE_MAGIC, 19)

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

70

N TT NGHIP
#define LCD_DISP_ON_C #define LCD_DISP_OFF_C #define LCD_CUR_MOV_LEFT_C #define LCD_CUR_MOV_RIGHT_C #define LCD_DIS_MOV_LEFT_C #define LCD_DIS_MOV_RIGHT_C #define LCD_DELAY_MSEC #define LCD_DELAY_USEC _IO(IOC_LCDDEVICE_MAGIC, 21) _IO(IOC_LCDDEVICE_MAGIC, 22) _IO(IOC_LCDDEVICE_MAGIC, 23) _IO(IOC_LCDDEVICE_MAGIC, 24) _IO(IOC_LCDDEVICE_MAGIC, 25) _IO(IOC_LCDDEVICE_MAGIC, 29) _IO(IOC_LCDDEVICE_MAGIC, 30) _IO(IOC_LCDDEVICE_MAGIC, 31)

/*-------------LCD PIN CONTROL + DATA-----------*/ #define LCD_RW_PIN AT91_PIN_PB9 #define LCD_EN_PIN AT91_PIN_PB10 #define LCD_RS_PIN AT91_PIN_PB8 #define LCD_D4_PIN AT91_PIN_PA23 #define LCD_D5_PIN AT91_PIN_PB16 #define LCD_D6_PIN AT91_PIN_PA24 #define LCD_D7_PIN AT91_PIN_PB11

/*--------------LCD command datas--------------*/ /* LCD memory map */ /*V tr con tr bt u dng u tin*/
#define LCD_LINE0_ADDR 0x00

/*V tr con tr bt u dng th hai*/


#define LCD_LINE1_ADDR 0x40

/*V tr con tr bt u dng th ba*/


#define LCD_LINE2_ADDR 0x14

/*V tr con tr bt u dng th t*/


#define LCD_LINE3_ADDR 0x54

/* M lnh c bn ca LCD */ /*Con tr a ch RAM hin th*/


#define LCD_DD_RAM_PTR 0x80

/*Con tr a ch RAM to k t*/


#define LCD_CG_RAM_PTR 0x40

/*Lnh xa d liu hin th, con tr hin th v 0*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

71

N TT NGHIP
#define LCD_CLEAR_DISPLAY 0x01

/*Lnh a con tr v im bt u dng u tin, d liu b dch s tr


v v tr c*/ #define LCD_RETURN_HOME 0x02

/*Lnh ci dt ch giao tip 4 bits v 2 dng hin th*/


#define LCD_DISP_INIT 0x28

/*Con tr hin th tng sau khi ghi d liu vo RAM hin th*/
#define LCD_INC_MODE 0x06

/*Bt hin th v con tr nhp nhy*/


#define LCD_DISP_ON 0x0C

/*Tt hin th v con tr*/


#define LCD_DISP_OFF 0x08

/*Lnh bt con tr */
#define LCD_CURSOR_ON 0x04

/*Lnh tt con tr*/


#define LCD_CURSOR_OFF 0x00

/*Di chuyn con tr v d liu hin th sang bn tri*/


#define LCD_CUR_MOV_LEFT 0x10

/*Di chuyn con tr v d liu sang bn phi*/


#define LCD_CUR_MOV_RIGHT 0x14

/*D liu hin th c dch sang tri*/


#define LCD_DIS_MOV_LEFT 0x18

/*D liu hin th c dch sang phi*/


#define LCD_DIS_MOV_RIGHT 0x1C

/*Trng thi LDC ang bn, dng kim tra trng thi ca LCD*/
#define LCD_BUSY 0x80

/*Cc lnh Set v Clear bit cn bn*/


#define SET_LCD_RS_Line() gpio_set_value(LCD_RS_PIN,1) #define SET_LCD_BL_Line() gpio_set_value(LCD_BL_PIN,1) #define SET_LCD_EN_Line() gpio_set_value(LCD_EN_PIN,1) #define CLR_LCD_RS_Line() gpio_set_value(LCD_RS_PIN,0) #define CLR_LCD_BL_Line() gpio_set_value(LCD_BL_PIN,0) ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

72

N TT NGHIP
#define CLR_LCD_EN_Line() gpio_set_value(LCD_EN_PIN,0) #define SET_LCD_D4_Line() gpio_set_value(LCD_D4_PIN,1) #define SET_LCD_D5_Line() gpio_set_value(LCD_D5_PIN,1) #define SET_LCD_D6_Line() gpio_set_value(LCD_D6_PIN,1) #define SET_LCD_D7_Line() gpio_set_value(LCD_D7_PIN,1) #define CLR_LCD_D4_Line() gpio_set_value(LCD_D4_PIN,0) #define CLR_LCD_D5_Line() gpio_set_value(LCD_D5_PIN,0) #define CLR_LCD_D6_Line() gpio_set_value(LCD_D6_PIN,0) #define CLR_LCD_D7_Line() gpio_set_value(LCD_D7_PIN,0) /*-------------------------------------------------------*/

/*Nhng lnh trong driver h tr


void lcd_Control_Write(uint8_t data); void lcd_Data_Write(uint8_t data); void lcd_Home(void); void lcd_Clear(void); void lcd_Goto_XY(uint8_t xy);*/

/*Hm tr hon thi gian chuyn n v us sang jiffies*/


void lcd_delay_usec(unsigned int u) { long int time_delay; time_delay = jiffies + usecs_to_jiffies(u); while (time_before(jiffies, time_delay)) { schedule(); } }

/*Hm tr hon thi gian chuyn n v ms sang jiffies*/


void lcd_Delay_mSec (unsigned long m) { long int time_delay; time_delay = jiffies + msecs_to_jiffies(m); while (time_before(jiffies, time_delay)) { schedule(); } }

/*Hm chuyn d liu 4 bit thnh cc trng thi trong chn gpio*/
void lcd_write_data_port(uint8_t data) ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

73

N TT NGHIP
{ (data&(1<<0))? SET_LCD_D4_Line():CLR_LCD_D4_Line(); (data&(1<<1))? SET_LCD_D5_Line():CLR_LCD_D5_Line(); (data&(1<<2))? SET_LCD_D6_Line():CLR_LCD_D6_Line(); (data&(1<<3))? SET_LCD_D7_Line():CLR_LCD_D7_Line(); }

/*Hm ghi d liu 8 bits vo LCD, ghi 2 ln 4 bits vo LCDs c 8


bits v ang ch giao tip 4 bits.*/ void lcd_data_line_write(uint8_t data) {

/*u tin ghi 4 bits cao vo LCDs, sau n 4 bit thp*/ /*Chun b to xung cnh xung cho EN, cho EN ln mc cao*/
SET_LCD_EN_Line();

/*Ghi 4 bit thp vo cc chn d liu*/


lcd_write_data_port((data>>4)&0x000F);

/*To xung cnh xung ghi 4 bit thp vo thanh ghi*/


CLR_LCD_EN_Line();

/*Tr hon mt khong thi gian ch thc thi lnh*/


lcd_delay_usec(50);

/*Tip theo ghi 4 bits thp ca d liu vo thanh ghi*/


SET_LCD_EN_Line(); lcd_write_data_port(data&0x000F); CLR_LCD_EN_Line(); lcd_delay_usec(50); } /*Hm ghi m lnh vo thanh ghi lnh trong LCD*/ void lcd_Control_Write(uint8_t data) {

/*Tr hon thi gian ch thc thi nhng lnh trc */


lcd_delay_usec(50);

/*Chn thanh ghi lnh*/


CLR_LCD_RS_Line();

/*Ghi m lnh vo thanh ghi lnh*/


lcd_data_line_write(data); } ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

74

N TT NGHIP /*Hm ghi d liu vo thanh ghi d liu trong LCDs*/


void lcd_Data_Write(uint8_t data) {

/*Tr hon thi gian ch thc thi nhng lnh trc */


lcd_delay_usec(50);

/*Chn thanh ghi d liu trong LCDs*/


SET_LCD_RS_Line();

/*Ghi d liu vo thanh ghi*/


lcd_data_line_write(data); }

/*---------------------Init the LCD---------------------*/ /*Hm khi to cc thng s cho LCD lm vic theo yu cu ca ngi lp trnh*/
void lcd_Init(void) {

/*Ci t LCD hot ng theo ch giao tip 4 bits*/


lcd_Control_Write(0x33);

/*Tr hon thi gian thc thi lnh*/


lcd_delay_usec(1000); lcd_Control_Write(0x32); lcd_delay_usec(1000);

/*Ci t trng thi ban u ca LCDs*/


lcd_Control_Write(LCD_DISP_INIT);

/*Gi lnh xa d liu hin th trong LCDs*/


lcd_Control_Write(LCD_CLEAR_DISPLAY);

/*Tr hon thi gian 60ms*/


lcd_delay_usec(60000);

/*Ci t ch con tr tng dn sau khi ghi d liu*/


lcd_Control_Write(LCD_INC_MODE);

/*Bt hin th cho LCD*/


lcd_Control_Write(LCD_DISP_ON);

/*Chuyn con tr hin th n v tr bt u dng u tin*/


lcd_Control_Write(LCD_RETURN_HOME); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

75

N TT NGHIP
}

/*Hm chc nng chuyn con tr v v tr bt u dng u tin*/


void lcd_Home(void) { lcd_Control_Write(LCD_RETURN_HOME); }

/*Hm chc nng xa d liu hin th*/


void lcd_Clear(void) { lcd_Control_Write(LCD_CLEAR_DISPLAY); }

/*Hm chc nng bt hin th cho LCD*/


void lcd_Display_On(void) { lcd_Control_Write(LCD_DISP_ON); }

/*Hm tt hin th cho LCDs*/


void lcd_Display_Off(void) { lcd_Control_Write(LCD_DISP_OFF); }

/*Hm dch chuyn d liu hin th v bn tri*/


void lcd_Dis_Mov_Left(void) { lcd_Control_Write(LCD_DIS_MOV_LEFT); }

/*Hm dch chuyn d liu hin th v bn phi*/


void lcd_Dis_Mov_Right(void) { lcd_Control_Write(LCD_DIS_MOV_RIGHT); }

/*Hm di chuyn con tr v bn tri*/


void lcd_Cursor_Move_Left(void) { lcd_Control_Write(LCD_CUR_MOV_LEFT); } ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

76

N TT NGHIP /*Hm d chuyn con tr v bn phi*/


void lcd_Cursor_Move_Right(void) { lcd_Control_Write(LCD_CUR_MOV_RIGHT); } static atomic_t lcd_open_cnt = ATOMIC_INIT(1);

/*Giao din hm ioctl() thc hin chc nng do user application yu cu*/
static int lcd_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { int retval = 0; switch (cmd) {

/*Chc nng nhn m lnh thc thi t user application*/


case LCD_CONTROL_WRITE: lcd_Control_Write(arg); break;

/*Chc nng nhn d liu hin th t user application*/


case LCD_DATA_WRITE: lcd_Data_Write(arg); break;

/*Chc nng tr hon thi gian dng jiffies, chuyn ms thnh jiffies*/
case LCD_DELAY_MSEC: lcd_Delay_mSec(arg); break;

/*Chc nng tr hon thi gian dng jiffies,chuyn us thnh jiffies*/


case LCD_DELAY_USEC: lcd_delay_usec(arg); break;

/*Chc nng chuyn con tr v hng u tin ca hng 1*/


case LCD_HOME: lcd_Home(); break; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

77

N TT NGHIP /*Chc nng xa hin th*/


case LCD_CLEAR: lcd_Clear(); break;

/*Chc nng bthin th*/


case LCD_DISP_ON_C: lcd_Display_On(); break;

/*Chc nng xa hin th*/


case LCD_DISP_OFF_C: lcd_Display_Off(); break;

/*Di chuyn con tr v d liu sang tri*/


case LCD_DIS_MOV_LEFT_C: lcd_Dis_Mov_Left(); break;

/*Di chuyn con tr v d liu sang phi*/


case LCD_DIS_MOV_RIGHT_C: lcd_Dis_Mov_Right(); break;

/*Di chuyn con tr sang tri*/


case LCD_CUR_MOV_LEFT_C: lcd_Cursor_Move_Left(); break;

/*Di chuyn con tr sang phi*/


case LCD_CUR_MOV_RIGHT_C: lcd_Cursor_Move_Right(); break;

/*Chc nng khi to LCD hot ng theo ch 4 bits, 2 dng hin th*/
case LCD_INIT: lcd_Init(); break;

/*Trong trng hp khng c lnh no h tr*/


default: ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

78

N TT NGHIP
retval = -EINVAL; break; } return retval; }

/*Khai bo v nh ngha giao din hm open()*/


static int lcd_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&lcd_open_cnt)) { atomic_inc(&lcd_open_cnt); printk(KERN_ERR result = -EBUSY; goto out; } out: return result; } DRVNAME ": Device with minor ID %d already in use\n", dev_minor);

/*Khai bo v nh ngha giao din hm close()*/


static int lcd_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&lcd_open_cnt); return 0; }

/*Khai bo v nh ngha cc lnh m LCD h tr file operations*/


struct file_operations lcd_fops = { .ioctl .open .release }; ________________________________________________________________________________ = lcd_ioctl, = lcd_open, = lcd_close,

CHNG III: LP TRNH GIAO TIP NGOI VI

79

N TT NGHIP /*Khai bo v nh ngha thit b*/


static struct miscdevice lcd_dev = { .minor .name .fops }; = MISC_DYNAMIC_MINOR, = "lcd_dev", = &lcd_fops,

/*Hm c thc thi khi driver c ci t vo h thng*/


static int __init lcd_mod_init(void) { int i;

/*Khi to cc chn gpio l ng ra*/


gpio_request (LCD_RW_PIN, NULL); gpio_request (LCD_EN_PIN, NULL); gpio_request (LCD_RS_PIN, NULL); gpio_request (LCD_D4_PIN, NULL); gpio_request (LCD_D5_PIN, NULL); gpio_request (LCD_D6_PIN, NULL); gpio_request (LCD_D7_PIN, NULL); at91_set_GPIO_periph (LCD_RW_PIN, 1); at91_set_GPIO_periph (LCD_EN_PIN, 1); at91_set_GPIO_periph (LCD_RS_PIN, 1); at91_set_GPIO_periph (LCD_D4_PIN, 1); at91_set_GPIO_periph (LCD_D5_PIN, 1); at91_set_GPIO_periph (LCD_D6_PIN, 1); at91_set_GPIO_periph (LCD_D7_PIN, 1); gpio_direction_output(LCD_RW_PIN,0); gpio_direction_output(LCD_EN_PIN,0); gpio_direction_output(LCD_RS_PIN,0); gpio_direction_output(LCD_D4_PIN,0); gpio_direction_output(LCD_D5_PIN,0); gpio_direction_output(LCD_D6_PIN,0); gpio_direction_output(LCD_D7_PIN,0);

/*Ln lt in thng bo cho ngi dng, chun b ci t driver*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

80

N TT NGHIP
for (i=5;i>=0;i--) { lcd_delay_usec(1000000); printk("Please wait ... %ds\n",i); }

/*Gi hm khi to LCD*/


lcd_Init();

/*Gi hm xa LCD*/
lcd_Clear();

/*In thng bo cho ngi dng ci t thnh cng*/


printk(KERN_ALERT "Welcome to our LCD world\n");

/*Ci t ci t driver vo h thng*/


return misc_register(&lcd_dev); }

/*Hm thc thi khi driver b g b*/


static void __exit lcd_mod_exit(void) { printk(KERN_ALERT "Goodbye for all best\n"); misc_deregister(&lcd_dev); }

/*Gn hm init v exit vo cc macro*/


module_init (lcd_mod_init); module_exit (lcd_mod_exit);

/*Nhng thng tin tng qut v driver*/


MODULE_LICENSE("GPL"); MODULE_AUTHOR("Coolwarmboy / OpenWrt"); MODULE_DESCRIPTION("Character driver"); device for for generic lcd

3. Chng trnh application: /*Khai bo th vin cho cc lnh cn dng trong chng trnh*/
#include <stdint.h> #include <unistd.h> #include <stdio.h> #include <string.h> #include <stdlib.h> ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

81

N TT NGHIP
#include <getopt.h> #include <fcntl.h> #include <time.h> //Th vin h tr cho cc hm thao tc thi gian #include <sys/types.h> #include <sys/stat.h> #include <linux/ioctl.h>

/*nh ngha cc s nh danh lnh cho giao din hm ioctl() mi s tng ng vi mt chc nng trong driver h tr*/
/*-------------LCD COMMAND DEFINED---------------*/ #define IOC_LCDDEVICE_MAGIC #define LCD_CONTROL_WRITE #define LCD_DATA_WRITE #define LCD_INIT #define LCD_HOME #define LCD_CLEAR #define LCD_DISP_ON_C #define LCD_DISP_OFF_C 'B' _IO(IOC_LCDDEVICE_MAGIC, 15) _IO(IOC_LCDDEVICE_MAGIC, 16) _IO(IOC_LCDDEVICE_MAGIC, 17) _IO(IOC_LCDDEVICE_MAGIC, 18) _IO(IOC_LCDDEVICE_MAGIC, 19) _IO(IOC_LCDDEVICE_MAGIC, 21) _IO(IOC_LCDDEVICE_MAGIC, 22)

#define LCD_CUR_MOV_LEFT_C _IO(IOC_LCDDEVICE_MAGIC, 23) #define LCD_CUR_MOV_RIGHT_C _IO(IOC_LCDDEVICE_MAGIC, 24) #define LCD_DIS_MOV_LEFT_C _IO(IOC_LCDDEVICE_MAGIC, 25) #define LCD_DIS_MOV_RIGHT_C _IO(IOC_LCDDEVICE_MAGIC, 29) #define LCD_DELAY_MSEC #define LCD_DELAY_USEC _IO(IOC_LCDDEVICE_MAGIC, 30) _IO(IOC_LCDDEVICE_MAGIC, 31)

/*nh ngha a ch u tin ca mi dng trong LCD, y iu khin LCD c hai dng 16 k t*/
#define LCD_LINE0_ADDR 0x00 //Start of line 0 in the DD-Ram #define LCD_LINE1_ADDR 0x40 //Start of line 1 in the DD-Ram

/*Xc lp bit quy nh a ch con tr d liu*/


#define LCD_DD_RAM_PTR 0x80 //Address Display Data RAM pointer

/*nh ngha nhng lnh c bn thng s dng, lm cho chng trnh gn d hiu trong qu trnh lp trnh*/
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

82

N TT NGHIP
/*--------------Functions of LCD-----------------*/ #define lcd_Control_Write()ioctl(fd_lcd,LCD_CONTROL_WRITE, data) #define lcd_Data_Write() #define lcd_Init() #define lcd_Home() #define lcd_Clear() #define lcd_Display_On() #define lcd_Display_Off() ioctl(fd_lcd, LCD_DATA_WRITE, data) ioctl(fd_lcd, LCD_INIT) ioctl(fd_lcd, LCD_HOME) ioctl(fd_lcd, LCD_CLEAR) ioctl(fd_lcd, LCD_DISP_ON_C) ioctl(fd_lcd, LCD_DISP_OFF_C) ioctl(fd_lcd, LCD_CUR_MOV_LEFT_C)

#define lcd_Cursor_Move_Left()

#define lcd_Cursor_Move_Right() ioctl(fd_lcd, LCD_CUR_MOV_RIGHT_C) #define lcd_Display_Move_Left() ioctl(fd_lcd, LCD_DIS_MOV_LEFT_C) #define lcd_Display_Move_Right()ioctl(fd_lcd, LCD_DIS_MOV_RIGHT_C) #define lcd_Delay_mSec() ioctl(fd_lcd, LCD_DELAY_MSEC, data) #define lcd_Delay_uSec() ioctl(fd_lcd, LCD_DELAY_USEC, data)

/*Phn khai bo cc bin ton cc*/


int fd_lcd; //Bin lu s m t tp tin khi driver LCD c m int counter_value; //Bin lu gi tr m hin ti cho chc nng m

/*Delay for unsigned long data mSecond*/ /*Hm dch tri k t hin th X v tr, do ngi lp trnh nhp vo*/
void Display_Shift_Left(int X) { int i; for (i=0; i<X; i++) {

/*Gi hm dch tri k t hin th X ln*/


lcd_Display_Move_Left(); } }

/*Hm dch phi k t hin th X v tr, do ngi lp trnh nhp vo*/


void Display_Shift_Right(int X) { int i; for (i=0; i<X; i++) {

/*Gi hm dch phi X ln*/


lcd_Display_Move_Right(); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

83

N TT NGHIP
} }

/*Di chuyn con tr hin th n v tr x, y. Trong x l s th t dng ca LCD bt u t 0; y l s th t ct ca LCD bt u t 0*/


void lcd_Goto_XY(uint8_t x, uint8_t y) {

/*nh ngha thanh ghi d liu con tr ca Data Display RAM*/


register uint8_t DDRAMAddr;

/*So snh s x chn s dng cho ph hp*/


switch(x) {

/*Trong trng hp dng th nht, dng 0. Tin hnh cng gi tr a ch u dng cho s ct y*/
case 0: DDRAMAddr = LCD_LINE0_ADDR+y; break;

/*Trong trng hp dng th hai, dng 1. Tin hnh cng gi tr a ch


u dng cho s ct y*/ case 1: DDRAMAddr = LCD_LINE1_ADDR+y; break;

/*Trong trng hp dng 3, 4. Trng hp ny p dng cho LCD 16x4.


Thut ton cng tng t nh 2 trng hp trn*/

//case 2: DDRAMAddr = LCD_LINE2_ADDR+y; break; for LCD 16x4 or //20x4 only //case 3: DDRAMAddr = LCD_LINE3_ADDR+y; break; /*Trong nhng trng hp khc vn tnh l dng th 1*/
default: DDRAMAddr = LCD_LINE0_ADDR+y; }

/*Cui cng gi hm giao din ioctl() t gi tr a ch nh ngha


pha trn*/ ioctl(fd_lcd, LCD_CONTROL_WRITE, LCD_DD_RAM_PTR | DDRAMAddr); }

/*Hm xut chui k t ti v tr bt u l dng x v ct y*/


void Display_Print_Data(char *string, uint8_t x, uint8_t y) {

/*u tin di chuyn con tr n v tr mong mun x v y*/


lcd_Goto_XY(x,y); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

84

N TT NGHIP /*Xut ln lt tng k t trong chui string ra LCD hin thi. Lp li cho n khi kt thc chui */
while (*string) } } { ioctl(fd_lcd, LCD_DATA_WRITE, *string++);

/*Hm xut mt k t ti v tr bt u l dng x v ct y*/


void Display_Print_Char(int data, uint8_t x, uint8_t y) {

/*Di chuyn con tr n v tr cn in k t ra LCD*/


lcd_Goto_XY(x,y);

/*Gi hm xut k t ra LCD qua giao din ioctl()*/


lcd_Data_Write (); }

/*Chng trnh con khi to hin th LCD*/


void Display_Init_Display (void) {

/*Bin lu s ln chp tt hin th, dng cho vng lp for()*/


int i; /*Gi hm xa hin th ca LCD*/ lcd_Clear();

/* Xut chui k t thng bo khi to LCD thnh cng*/


Display_Print_Data ("LCD display",0,2); Display_Print_Data ("I am your slave!",1,0);

/*Chp tt hin th 3 ln*/


for (i = 0; i < 3; i ++ ) {

/*Gi hm tt hin th*/


lcd_Display_Off();

/*Tr hon thi gian trong 500ms*/


ioctl(fd_lcd, LCD_DELAY_MSEC, 500);

/*Gi hm bt hin th*/


lcd_Display_On();

/*Tr hon thi gian trong 500ms*/


ioctl(fd_lcd, LCD_DELAY_MSEC, 500); } ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

85

N TT NGHIP /*Xa hin th kt thc li cho*/


lcd_Clear(); }

/*Chng trnh con in thng bo li ra LCD*/


void Display_print_error_0(void) { Display_Print_Data ("LCD information:",1,2); Display_Print_Data ("Error while typing!!!",0,0); }

/*Hm in ra hng dn cho ngi dng trong trng hp ngi dng nhp sai c php lnh*/
int print_usage(void) { printf("The command you required is not supported\n"); printf("./4_lcd_app display_string|display_time|display_counter <YY> <Period>\n"); Display_print_error_0(); return -1; } <string>|<XX>

////////////////////////////////////////////////////////////////////// /*Hm xut chui k t h tr cho ch xut k t ca chng trnh*/


void display_string(char *string) { Display_Print_Data("Your string is:",0,0); Display_Print_Data(string,1,0); }

/*Hm cp nht thi gian hin ti v xut ra LCD hin th. H tr cho ch
hin th thi gian ca chng trnh*/ void display_time(void) {

/*Bin lu cu trc thi gian theo dng nm thng ngy gi ... */


struct tm *tm_ptr;

/*Bin lu thi gian hin ti ca h thng*/


time_t the_time;

/*Hin th cc thng tin ban u trn LCD*/


Display_Print_Data ("Date: Display_Print_Data ("Time: / : / : ",0,0); ",1,0);

/*Vng lp cp nht thi gian hin ti v xut d liu ra LCD*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

86

N TT NGHIP
while (1) {

/*Ly thi gian hin ti ca h thng*/


(void) time(&the_time);

/*Chuyn i thi gian hin ti ca h thng sang cu trc thi gian tm*/
tm_ptr = gmtime(&the_time);

dng struc

/*Ln lt chuyn i cc gi tr thi gian sang k t v xut ra LCD. Thut ton chuyn i: Chuyn sang s BCD t s nguyn c 2 ch s; Ln lt cng cc s BCD cho 48 chuyn sang cc k s trong bng m ascii*/ /*Chuyn i v hin th nm ra LCD*/
Display_Print_Char(((tm_ptr->tm_year)/10)+48,0,6); Display_Print_Char(((tm_ptr->tm_year)%10)+48,0,7);

/*Chuyn i v hin th thng ra LCD*/


Display_Print_Char(((tm_ptr->tm_mon+1)/10)+48,0,9); Display_Print_Char(((tm_ptr->tm_mon+1)%10)+48,0,10);

/*Chuyn i v hin th ngy ra LCD*/


Display_Print_Char(((tm_ptr->tm_mday)/10)+48,0,12); Display_Print_Char(((tm_ptr->tm_mday)%10)+48,0,13);

/*Chuyn i v hin th gi ra LCD*/


Display_Print_Char(((tm_ptr->tm_hour)/10)+48,1,6); Display_Print_Char(((tm_ptr->tm_hour)%10)+48,1,7);

/*Chuyn i v hin th gi ra LCD*/


Display_Print_Char(((tm_ptr->tm_min)/10)+48,1,9); Display_Print_Char(((tm_ptr->tm_min)%10)+48,1,10);

/*Chuyn i v hin th gi ra LCD*/


Display_Print_Char(((tm_ptr->tm_sec)/10)+48,1,12); Display_Print_Char(((tm_ptr->tm_sec)%10)+48,1,13);

/*Tr hon cp nht thi gian*/


usleep(200000); } }

//////////////////////////////////////////////////////////////////////
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

87

N TT NGHIP /*Cc hm h tr cho chc nng m s ca chng trnh*/ /*Hm chuyn i s t 00 n 99 thnh 2 ch s hin th ra LCD ti v tr tng ng start_v_pos (ct bt u) v h_pos(dng bt u)*/
void Display_Number(int number, int start_v_pos, int h_pos) { Display_Print_Char((number/10)+48,h_pos,start_v_pos); Display_Print_Char((number%10)+48,h_pos,start_v_pos+1); }

/*Chng trnh con m chnh trong chc nng m s*/


void display_counter(int lmt1, int lmt2, int period_ms) {

/*Bin lu chu k thi gian us */


long int period_us;

/*Bin lu s ln chp tt hin th khi qu trnh m thnh cng*/


int i;

/*In thng tin c nh ban u ln LCD */


Display_Print_Data ("Start: End: ",0,0); Display_Print_Data ("Count Value:",1,0);

/*Hin th s gii hn Start*/


Display_Number(lmt1,6,0);

/*Hin th s gii hn End*/


Display_Number(lmt2,13,0);

/*Cp nht gi tr ban u cho counter_value*/


counter_value = lmt1;

/*Chuyn thi gian ms sang us dng cho hm usleep()*/


period_us = period_ms*1000;

/*Qu trnh m bt u, m t gi tr Start cho n gi tr End*/


while (counter_value != lmt2) {

/*Hin th gi tr m hin ti ln LCD*/


Display_Number(counter_value,12,1);

/*Tr hon thi gian m*/


usleep(period_us);

/*Tng hoc gim gi tr m hin ti cho n khi bng vi gi tr End*/


if (counter_value < lmt2) { counter_value++; } else { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

88

N TT NGHIP
counter_value--; } }

/*Khi qu trnh m kt thc in ra thng bo cho ngi dng bit*/


Display_Print_Data("Count commplete!",1,0);

/*Chp tt 3 ln trong vi tng s 1Hz*/


for (i = 0; i < 3; i ++ ) { lcd_Display_Off(); ioctl(fd_lcd, LCD_DELAY_MSEC, 500); lcd_Display_On(); ioctl(fd_lcd, LCD_DELAY_MSEC, 500); } }

/*Chng trnh chnh khai bo di dng nhn tham s t ngi dng*/


int main(int argc, char **argv) {

/*M tp tin thit b trc thao tc, ly v s m t tp tin lu trong bin fd_lcd. Kim tra li trong qu trnh thao tc*/
if ((fd_lcd = open("/dev/lcd_dev", O_RDWR)) < 0) { printf("Error whilst opening /dev/lcd_dev\n"); return -1; }

/*Gi cc hm khi to LCD ban u*/


printf("LCD initializing ...\n"); lcd_Init(); lcd_Clear(); Display_Init_Display();

/*So snh cc tham s la chn chc nng thc thi chng trnh*/
switch (argc) { case 2:

/*Trong trng hp hin th thi gian*/


if (!strcmp(argv[1],"display_time")) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

89

N TT NGHIP
display_time(); } else { return print_usage(); } break; case 3:

/*Trong trng hp hin th chui k t*/


if (!strcmp(argv[1],"display_string")) { display_string(argv[2]); } else { return print_usage(); } break; case 5:

/*Trong trng hp m s hin th trong khong t 00 n 99*/


if (!strcmp(argv[1],"display_counter")) { display_counter(atoi(argv[2]),atoi(argv[3]), atoi(argv[4])); } else { return print_usage(); } break; default:

/*Trong trng hp khng c lnh no h tr in ra thng bo hng dn cho ngi dng */


return print_usage(); break; } return 0; }

4. Bin dch v thc thi chng trnh: Ngi hc t bin dch chng trnh driver v chng trnh application. Sau khi bin dch chp vo kt tin hnh kim tra kt qu trong tng trng hp tng ng vi tng chc nng khc nhau ca chng trnh. Rt ra nhn xt v kinh nghim thc hin.
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

90

N TT NGHIP III. Kt lun v bi tp:

a. Kt lun: Trong bi ny chng ta nghin cu thm mt ng dng na trong vic iu khin cc chn gpio bng cc lnh set v clear tng chn c bn. Chng ta thc hnh s dng cc lnh thao tc vi thi gian trong vic cp nht v hin th trn thit b phn cng LCD. Chng trnh driver v application trong d n ny mc d iu khin thnh cng LCD nhng chng trnh vn cn cha ti u nh: Nhng thao tc iu khin LCD vn cn nm trong user application qu nhiu, kh p dng driver sang nhng d n khc. Cc bn s thc hin ti u ha hot ng ca driver LCD thng qua nhng bi tp yu cu trong phn sau. b. Bi tp: 1. Thm chc nng di chuyn con tr n v tr x v y bt k trn LCD trong driver iu khin LCD trong v d trn. Trong : x l v tr ct, y l v tr dng ca LCD 16x2. Gi : Chc nng tng t nh hm void lcd_Goto_XY(uint8_t x, uint8_t y) trong user application nhng chuyn qua driver thc hin thng qua giao din hm ioctl(). 2. Thm chc nng hin th chui k t vo driver iu khin LCD theo yu cu sau: Driver nhn chui k t thng qua giao din hm write() c gi t user application; Chng trnh driver thc hin ghi nhng k t ny vo LCD hin th. **Chc nng ny ca driver tng t nh hm void

Display_Print_Data(char *string, uint8_t x, uint8_t y) trong user application. 3. Bin dch driver v lu vo th vin c th s dng trong nhng d n khc.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

91

N TT NGHIP BI 5

GIAO TIP IU KHIN GPIO NG VO M XUNG


I. Phc tho d n: Trong cc bi trc chng ta ch s dng cc chn ca Vi X L ch gpio ng ra (output). Khi s dng cc chn ca Vi X L ch output th chng ta c th iu khin cc thit b ngoi vi (led n, led 7 on, ic), nhng trong thc t c nhng trng hp Vi X L phi cp nht cc tn hiu t bn ngoi (tn hiu ca nt nhn, ma trn phm, ). Trong nhng trng hp ny chng ta phi dng chn ca Vi X L ch gpio ng vo (input). Ngoi ra, trong cc d n trc, vi mt ng dng chng ta vit mt chng trnh Driver v mt chng trnh User Application. Vi phng php lp trnh ny, chng ta phn no hiu c im mnh ca vic lp trnh ng dng bng phng php nhng trong vic chia nhim v cho Driver v User Application iu khin thit b. Nhng trong d n ny chng ta s lm quen vi phng php lp trnh nhng mi l s dng mt User Application iu khin nhiu Driver khc nhau ( c ngha l vi mt ng dng chng ta c th vit nhiu Driver khc nhau v dng mt chng trnh User Applicaton iu khin cc Driver ny). C th ni phng php ny s lm ni bt ln im mnh ca vic lp trnh ng dng trn h thng nhng mt cch r rt hn so vi phng php lp trnh thng thng cho Vi X L. i vi cc thit b, modun khc nhau chng ta c th vit cc Driver iu khin cc modun ny (mi modun mt Driver) v c th chy cc Driver ny cng lc vi. Nh vy chng ta c th iu khin nhiu thit b trong cng mt lc mt cch c lp. Ch : trnh s xung khc gia cc Driver vi nhau chng ta khng c s dng mt chn ca Vi X L cho nhiu Driver. Mt chn ca Vi X L ch c dng cho mt Driver duy nht. a. Yu cu d n: Trong d n ny chng ta s m xung t bn ngoi (nt nhn) v hin th s xung m c trn 8 led 7 on theo phng php qut.
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

92

N TT NGHIP C php lnh ca chng trnh nh sau:


./< counter_display_7seg_app > <start>

Trong :
< counter_display_7seg_app > l tn chng trnh User Application sau

khi bin dch.


< start > l lnh bt u chng trnh m xung.

b. Phn cng nhim v: Driver: trong d n ny Driver s c hai nhim v l: Nhim v th nht: cp nht xung m t bn ngoi, nu c xung tc ng th s gi tn hiu sang cho User Application. Nhim v th hai: nhn d liu t User Application, iu khin modun Led 7 on theo phng php qut th hin th s xung m c. Nh ni t trc, trong d n ny chng ta s vit hai Driver. Driver th nht lm nhim v th nht. Driver th hai lm nhim v th hai. User Application: c nhim v cp nht tn hiu ca Driver th nht, nu tn hiu bo c xung th s tng bin m xung ln mt n v, sau truyn bin m xung ny sang cho Driver th hai hin th ln modun Led 7 on.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

93

N TT NGHIP II. Thc hin: 1. Kt ni phn cng:


J1 8 7 6 5 4 3 2 1 Jump 8 PB8 PB10 PA23 PB16 PA24 PB11 PB9 PB7 R300 R300 R300 R300 R300 R300 R300 R300 R1 R2 R3 R4 R5 R6 R7 R8 VCC R9 1K U1 A1015 8 3 8 3 R10 1K U2 A1015 8 3 VCC VCC R11 1K U3 A1015 8 3 R12 1K U4 A1015 8 3 VCC VCC R13 1K U5 A1015 8 3 VCC R14 1K U6 A1015 8 3 VCC R15 1K U7 A1015 8 3 Dp 7 6 4 2 1 9 10 a b c d e f g VCC R16 1K U8 A1015

7 6 4 2 1 9 10

+ A

+ A

+ A

+ A

+ A

+ A

+ A

a b c d e f g

a b c d e f g

a b c d e f g

a b c d e f g

a b c d e f g

a b c d e f g

a b c d e f g

U9 J2 8 7 6 5 4 3 2 1 Jump 8 SW1 PB6 PB0 PB2 PC5 PC6 PC7 PC4 PB3 R300 R300 R300 R300 R300 R300 R300 R17 R18 R19 R20 R21 R22 R23

U10

U11

U12

U13

U14

U15

+ A U16

Dp

7 6 4 2 1 9 10

Dp

7 6 4 2 1 9 10

Dp

7 6 4 2 1 9 10

Dp

7 6 4 2 1 9 10

Dp

7 6 4 2 1 9 10

Dp

7 6 4 2 1 9 10

Dp

2. Chng trnh driver: Driver th nht: Tn update_input_dev.c /* Khai bo cc th vin cn thit cho chng trnh */
#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/interrupt.h> #include <mach/at91_tc.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <linux/genhd.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #include <linux/clk.h> #include <linux/irq.h> #include <linux/time.h> #include <linux/jiffies.h> #include <linux/sched.h> ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

94

N TT NGHIP
#include <linux/delay.h> #include <linux/timer.h>

/* Khai bo tn Driver v tn thit b */


#define DRVNAME #define DEVNAME "update_input_dev" "update_input"

/* nh ngha chn ca Vi X L dng trong chng trnh*/


#define COUNTER_PIN AT91_PIN_PB6

/* Khai bo bin kim tra Driver c m hay cha */


static atomic_t update_input_open_cnt = ATOMIC_INIT(1);

/* Chng trnh cp nht trng thi ca chn Vi X L (COUNTER_PIN) dng m xung t bn ngoi */
static { ssize_t update_input_read (struct file *filp, char __iomem buf[], size_t bufsize, loff_t *f_pos)

/* Khai bo b m c */
char driver_read_buf[1];

/* Nu chn COUNTER_PIN c ni t (gi tr c vo t chn ny l 0) th cho driver_read_buf[0] bng 0, ngc li th th cho driver_read_buf[0] = 1 */
if(gpio_get_value(COUNTER_PIN) == 0) driver_read_buf[0] = 0; else driver_read_buf[0] = 1;

/* Truyn driver_read_buf sang cho User Application, nu qu trnh truyn tht bi th bo li cho ngi dng bit */
if(copy_to_user(buf,driver_read_buf,bufsize) != 0) { printk("Can't read Driver \n"); return -EFAULT; } }

/* Chng trnh m Driver */


static int update_input_open(struct inode *inode, struct file *file) { int result = 0; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

95

N TT NGHIP
unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&update_input_open_cnt)) { atomic_inc(&update_input_open_cnt); printk(KERN_ERR result = -EBUSY; goto out; } out: return result; } DRVNAME ": Device with minor ID %d already in use\n", dev_minor);

/* Chng trnh ng Driver */


static int update_input_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&update_input_open_cnt); return 0; }

/* Cu trc file_operations ca Driver */


struct file_operations update_input_fops = { .read = update_input_read, .open }; static struct miscdevice update_input_dev = { .minor .name .fops }; = MISC_DYNAMIC_MINOR, = "update_input", = &update_input_fops, = update_input_open, .release = update_input_close,

/* Chng trnh khi to ca Driver, c thc hin khi ngi dng gi lnh insmod */
static int __init update_input_mod_init(void) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

96

N TT NGHIP
int ret=0;

/* Khai bo khi to chn COUNTER_PIN ch gpio ng vo c in tr ko ln bn trong */


gpio_free(COUNTER_PIN); gpio_request (COUNTER_PIN, NULL); at91_set_GPIO_periph (COUNTER_PIN, 1); gpio_direction_input(COUNTER_PIN); at91_set_deglitch(COUNTER_PIN,1); misc_register(&update_input_dev); printk(KERN_INFO "sweep_seg_led: Loaded module\n"); return ret; } static void __exit update_input_mod_exit(void) { misc_deregister(&update_input_dev); printk(KERN_INFO "sweep_seg_led: Unloaded module\n"); } module_init (update_input_mod_init); module_exit (update_input_mod_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("TranCamNhan"); MODULE_DESCRIPTION("Character api"); device for for generic gpio

Driver th hai: Tn sweep_7seg_led_dev.c /* Khai bo cc th vin cn thit cho chng trnh */


#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/interrupt.h> #include <mach/at91_tc.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <linux/genhd.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

97

N TT NGHIP
#include <linux/clk.h> #include <linux/irq.h> #include <linux/time.h> #include <linux/jiffies.h> #include <linux/sched.h> #include <linux/delay.h> #include <linux/timer.h>

/* Khai bo tn Driver v tn thit b */


#define DRVNAME #define DEVNAME "sweep_7seg_led_dev" "sweep_7seg_led"

/* nh ngha cc chn ca Vi X L s dng trong chng trnh */


#define P00 #define P01 #define P02 #define P03 #define P04 #define P05 #define P06 #define P07 #define A #define B #define C #define D #define E #define F #define G AT91_PIN_PB8 AT91_PIN_PB10 AT91_PIN_PA23 AT91_PIN_PB16 AT91_PIN_PA24 AT91_PIN_PB11 AT91_PIN_PB9 AT91_PIN_PB7 AT91_PIN_PB0 AT91_PIN_PB2 AT91_PIN_PC5 AT91_PIN_PC6 AT91_PIN_PC7 AT91_PIN_PC4 AT91_PIN_PB3

/* nh ngha lnh Set v Clear cc chn ca Vi X L */


#define SET_P00() #define SET_P01() #define SET_P02() #define SET_P03() #define SET_P04() #define SET_P05() #define SET_P06() #define SET_P07() gpio_set_value(P00,1) gpio_set_value(P01,1) gpio_set_value(P02,1) gpio_set_value(P03,1) gpio_set_value(P04,1) gpio_set_value(P05,1) gpio_set_value(P06,1) gpio_set_value(P07,1)

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

98

N TT NGHIP
#define CLEAR_P00() gpio_set_value(P00,0) #define CLEAR_P01() #define CLEAR_P02() #define CLEAR_P03() #define CLEAR_P04() #define CLEAR_P05() #define CLEAR_P06() #define CLEAR_P07() #define SET_A() #define SET_B() #define SET_C() #define SET_D() #define SET_E() #define SET_F() #define SET_G() #define CLEAR_A() #define CLEAR_B() #define CLEAR_C() #define CLEAR_D() #define CLEAR_E() #define CLEAR_F() #define CLEAR_G() gpio_set_value(P01,0) gpio_set_value(P02,0) gpio_set_value(P03,0) gpio_set_value(P04,0) gpio_set_value(P05,0) gpio_set_value(P06,0) gpio_set_value(P07,0) gpio_set_value(A,1) gpio_set_value(B,1) gpio_set_value(C,1) gpio_set_value(D,1) gpio_set_value(E,1) gpio_set_value(F,1) gpio_set_value(G,1) gpio_set_value(A,0) gpio_set_value(B,0) gpio_set_value(C,0) gpio_set_value(D,0) gpio_set_value(E,0) gpio_set_value(F,0) gpio_set_value(G,0)

/*nh ngha s nh danh lnh v lnh s dng trong ioctl */


#define SWEEP_LED_DEV_MAGIC 'B' #define UPDATE_DATA_SWEEP_7SEG _IO(SWEEP_LED_DEV_MAGIC,1)

/* Khai bo cc bin cn thit s dng trong chng trnh */


static atomic_t sweep_7seg_led_open_cnt = ATOMIC_INIT(1); char DataDisplay[8]={0,12,12,12,12,12,12,12}; char SevSegCode[]={ 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x3F, 0x77, 0xFF}; char ChooseLedActive[]={ 0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f}; int i=0;

/* Khai bo cu trc timer o trong kernel vi tn my_timer */


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

99

N TT NGHIP
struct timer_list my_timer;

/* Chng trnh chn Led 7 on tch cc */


void choose_led_active(char data) { (data&(1<<0))? SET_P00():CLEAR_P00(); (data&(1<<1))? SET_P01():CLEAR_P01(); (data&(1<<2))? SET_P02():CLEAR_P02(); (data&(1<<3))? SET_P03():CLEAR_P03(); (data&(1<<4))? SET_P04():CLEAR_P04(); (data&(1<<5))? SET_P05():CLEAR_P05(); (data&(1<<6))? SET_P06():CLEAR_P06(); (data&(1<<7))? SET_P07():CLEAR_P07(); }

/* Chng trnh vit d liu hin th ra cc chn Vi X L */


void write_data_led(char data) { (data&(1<<0))? SET_A():CLEAR_A(); (data&(1<<1))? SET_B():CLEAR_B(); (data&(1<<2))? SET_C():CLEAR_C(); (data&(1<<3))? SET_D():CLEAR_D(); (data&(1<<4))? SET_E():CLEAR_E(); (data&(1<<5))? SET_F():CLEAR_F(); (data&(1<<6))? SET_G():CLEAR_G(); }

/* Chng trnh chuyn mt s c nhiu ch s ra cc s BCD */


void hex_to_bcd (unsigned long int data) { DataDisplay[0] = data % 10; DataDisplay[1] = (data % 100)/10; DataDisplay[2] = (data % 1000)/100; DataDisplay[3] = (data % 10000)/1000; DataDisplay[4] = (data % 100000)/10000; DataDisplay[5] = (data % 1000000)/100000; DataDisplay[6] = (data % 10000000)/1000000; DataDisplay[7] = data/10000000;

/* Chng trnh xa s 0 v ngha */


if (data/10000000 == 0) { DataDisplay[7] = 12; if ((data % 10000000)/1000000 == 0) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

100

N TT NGHIP
DataDisplay[6] = 12; if ( (data % 1000000)/100000 == 0) { DataDisplay[5] = 12; if ((data % 100000)/10000 == 0) { DataDisplay[4] = 12; if ( (data % 10000)/1000 == 0) { DataDisplay[3] = 12; if( (data % 1000)/100 == 0) { DataDisplay[2] = 12; if( (data % 100)/10 == 0) DataDisplay[1] = 12; } } } } } } }

/* Chng trnh phc v ngt: c mi 1ms chng trnh ny s c hin mt ln, chng trnh ny c nhim v chn ln lc chn cc Led tch cc v xut d liu hin th ng vi tng Led */
void sweep_dis_irq(unsigned long data) { choose_led_active(ChooseLedActive[i]); write_data_led(SevSegCode[DataDisplay[i]]); i++; if(i==8) i=0;

/* Khi to li gi tr ca timer o vi chu k l 1ms*/


mod_timer (&my_timer, jiffies + 1); }

/* chng trnh nhn d liu t User Application v chuyn d liu va nhn sang cc s BCD */
static int sweep_7seg_led_ioctl(struct inode * inode, struct file * file, unsigned int cmd,unsigned long int arg) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

101

N TT NGHIP
int retval=0; switch (cmd) { case UPDATE_DATA_SWEEP_7SEG: hex_to_bcd(arg); break; default: printk("The function you type does not exist\n"); retval=-1; break; } } static int sweep_7seg_led_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&sweep_7seg_led_open_cnt)) { atomic_inc(&sweep_7seg_led_open_cnt); printk(KERN_ERR result = -EBUSY; goto out; } out: return result; } static int sweep_7seg_led_close(struct inode * inode, struct file * file){ smp_mb__before_atomic_inc(); atomic_inc(&sweep_7seg_led_open_cnt); return 0; } struct file_operations sweep_7seg_led_fops = { .ioctl .open }; static struct miscdevice sweep_7seg_led_dev = { ________________________________________________________________________________ = sweep_7seg_led_ioctl, = sweep_7seg_led_open, DRVNAME ": Device with minor ID %d already in use\n", dev_minor);

.release = sweep_7seg_led_close,

CHNG III: LP TRNH GIAO TIP NGOI VI

102

N TT NGHIP
.minor .name .fops }; static int __init sweep_7seg_led_mod_init(void) { int ret=0; = MISC_DYNAMIC_MINOR, = "sweep_7seg_led", = &sweep_7seg_led_fops,

/* Khi to cc chn ca Vi X L ch ng ra, c in tr ko ln */


gpio_request (P00, NULL); gpio_request (P01, NULL); gpio_request (P02, NULL); gpio_request (P03, NULL); gpio_request (P04, NULL); gpio_request (P05, NULL); gpio_request (P06, NULL); gpio_request (P07, NULL); at91_set_GPIO_periph (P00, 1); at91_set_GPIO_periph (P01, 1); at91_set_GPIO_periph (P02, 1); at91_set_GPIO_periph (P03, 1); at91_set_GPIO_periph (P04, 1); at91_set_GPIO_periph (P05, 1); at91_set_GPIO_periph (P06, 1); at91_set_GPIO_periph (P07, 1); gpio_direction_output(P00, 0); gpio_direction_output(P01, 0); gpio_direction_output(P02, 0); gpio_direction_output(P03, 0); gpio_direction_output(P04, 0); gpio_direction_output(P05, 0); gpio_direction_output(P06, 0); gpio_direction_output(P07, 0); gpio_request (A, NULL); gpio_request (B, NULL); gpio_request (C, NULL); gpio_request (D, NULL); gpio_request (E, NULL); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

103

N TT NGHIP
gpio_request (F, NULL); gpio_request (G, NULL); at91_set_GPIO_periph (A, 1); at91_set_GPIO_periph (B, 1); at91_set_GPIO_periph (C, 1); at91_set_GPIO_periph (D, 1); at91_set_GPIO_periph (E, 1); at91_set_GPIO_periph (F, 1); at91_set_GPIO_periph (G, 1); gpio_direction_output(A, 0); gpio_direction_output(B, 0); gpio_direction_output(C, 0); gpio_direction_output(D, 0); gpio_direction_output(E, 0); gpio_direction_output(F, 0); gpio_direction_output(G, 0);

/* Khi to timer o */
init_timer (&my_timer); my_timer.expires = jiffies+1; //chu k u tin l 1ms my_timer.data = 0; my_timer.function = sweep_dis_irq; add_timer (&my_timer); misc_register(&sweep_7seg_led_dev); printk(KERN_INFO "sweep_seg_led: Loaded module\n"); return ret; } static void __exit sweep_7seg_led_mod_exit(void){ del_timer_sync(&my_timer); misc_deregister(&sweep_7seg_led_dev); printk(KERN_INFO "sweep_seg_led: Unloaded module\n"); } module_init (sweep_7seg_led_mod_init); module_exit (sweep_7seg_led_mod_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("TranCamNhan"); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

104

N TT NGHIP
MODULE_DESCRIPTION("Character api"); device for for generic gpio

3. Chng trnh application: User Application: counter_display_7seg_app.c /* Khai bo cc th vin cn thit dng trong chng trnh*/
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h> #include <pthread.h> #include <unistd.h>

/* nh ngha s nh danh lnh v lnh dng trong ioctl*/


#define SWEEP_LED_DEV_MAGIC 'B' #define UPDATE_DATA_SWEEP_7SEG _IO(SWEEP_LED_DEV_MAGIC,1)

/* Khai bo cc bin cn thit trong chng trnh */


int update_input_fd; int sweep_7seg_led_fd;

/* Chng trnh in ra trn mng hnh c php lnh s dng chng trnh */
int print_usage(void) { printf("./counter_display_7seg_app <number>\n"); return -1; }

/* Chng trnh chnh */


int main(int argc, char **argv) { char user_read_buf[1]; long int counter = 0;

/* M Driver update_input_dev.ko */
if ((update_input_fd = open("/dev/update_input", O_RDWR)) < 0) { printf("Error device\n"); return -1; ________________________________________________________________________________ whilst opening /dev/update_input

CHNG III: LP TRNH GIAO TIP NGOI VI

105

N TT NGHIP
}

/* M Driver sweep_7seg_led_dev.ko */
if ((sweep_7seg_led_fd = open("/dev/sweep_7seg_led", O_RDWR)) < 0) { printf("Error device\n"); return -1; } if (argc != 2) print_usage(); else if (!strcmp (argv[1],"start")) while(1) { whilst opening /dev/sweep_7seg_led

/* Chng trnh c trng thi chn m xung t Driver update_input_dev. */


if(read(update_input_fd,user_read_buf,1)<0) printf("User: read from driver fail\n"); else {

/* Nu chn m xung mc thp th s tng bin counter ln mt n v v truyn bin counter ny sang cho Driver sweep_7seg_led_dev.ko */
if (user_read_buf[0] ==0) { usleep(50000); //Delay chng di counter++; ioctl(sweep_7seg_led_fd, UPDATE_DATA_SWEEP_7SEG, counter); printf("value counter: %d\n",counter);

/* Nu chn m xung vn mc thp th tip tc cp nht trng thi ca chn ny, khi no trng thi ca chn ny ln cao th mi ngng cp nht trng thi chn ny */
while(user_read_buf[0] ==0) { read(update_input_fd,user_read_buf,1); } usleep(50000);//Delay chng di } } } else ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

106

N TT NGHIP
print_usage(); return 0; }

III. Kt lun v bi tp: 1. Kt Lun: Nh vy trong d n ny chng ta m xung cnh xung chn PB6 ca Vi X L v hin th s xung m c ra 8 Led 7 on theo phng php qut. Chng ta vit hai Driver khc nhau v mt User Application thc hin yu cu ca d n ny. Thc ra i vi d n ny chng ta c th ch cn vit mt Driver v mt User Application l c th thc hin c yu cu. Nn vi cch vit chng trnh nh bi ny l nhm gii thiu n cho ngi hc phng php vit nhiu Driver cho mt ng dng, chng ta c th p dng phng php ny gii quyt cc ng dng c yu cu phc tp hn. Trong bi ny chng ta cng tp lm quen vi vic s dng ngt timer o ca kernel vi chu k 1ms. Ch : Trong bi ny chng ta thay i gi tr ca s HZ l 1000. Ngha l chng ta s c 1000 tick trong 1 giy trong kernel ( mi tick cch nhau 1ms). 2. Bi tp: 1. Vit chng trnh m ln t 5 n 55 v v li 5 hin th trn modun 8 Led 7 on, c xa s 0 v ngha. Vit 2 Driver v mt chng trnh User Application. 2. Vit chng trnh m ln xung nm trong khong 0 n 255 hin th trn modun 8 Led 7 on, xa s 0 v ngha. S dng hai nt nhn, mt nt nhn dng m ln, mt nt nhn dng m xung. Vit 2 Driver v mt chng trnh User Application.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

107

N TT NGHIP BI 6

GIAO TIP IU KHIN LED MA TRN 8x8


I. Phc tho d n: Hin nay, ma trn Led l linh kin in t c s dng ph bin trong cng nghip qung co. Khng ging nh Led 7 on ch c th hin th nhng con s, ma trn Led c th hin th c tt c cc k t, hnh nh m ngi dng mong mun. Ngoi ra ma trn Led cn hin th c nhiu hiu ng a dng khc nhau nh: dch tri, dch phi, chuyn ng ca s vt. Ngoi thc t, ma trn Led c nhiu loi khc nhau vi kch thc khc nhau, s lng Led khc nhau, s lng mu Led khc nhau. Thng thng mt ma trn Led c t nht 8x8 Led n trn n, v s lng Led trn mt ma trn Led rt ln nn chng ta khng th dng phng php truy xut trc tip tng Led c. Nn hin th c cc k t hnh nh trn ma trn Led chng ta phi dng phng php qut. K thut qut ma trn Led chng ta c hc trong mn Thc Tp Vi X L nn trong quyn sch ny chng ti s khng trnh by li. Chng ta ch tp trung vo vic lm th no qut v iu khin ma trn Led bng h thng nhng. a. Yu cu d n: Trong d n ny chng ta s iu khin ma trn Led 8X8 hai mu xanh hin th tt c cc k t c trn bn phm my vi tnh. V ma trn Led ch c 8 hng v 8 ct nn mi ln chng ta ch hin th c mt k t. C php lnh khi thc thi nh sau:
<tn chng trnh> <k t mun hin th>

Trong :
<tn chng trnh> l tn chng trnh sau khi bin dch xong. <k t mun hin th> l k t mun hin th trn ma trn Led.

b. Phn cng nhim v: Driver: Nhn d liu l m Asscii ca k t mun hin th t User Application thng qua hm write(), chuyn i m Asscii ny sang m ma trn (mt k t m Asscii tng ng vi 5 byte ca m ma trn) v qut modun ma trn Led theo cc m ma trn ny.
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

108

N TT NGHIP User Application: Nhn tham s t ngi dng v chuyn tham s ny sang cho Driver. II. Thc hin: 1. Kt ni phn cng theo s sau:
RN1

U1 +12V SERIN 3 SRCK 13 RCK 12 G\ 9 8 +5V GND 2 19 11 10 SERIN SRCK RCK G Q0 Q1 Q2 Q3 Q4 SRCLR Q5 Q6 Q7 VDD GND SO GND GND NC NC 6B595 H8 H7 H6 H5 C-D1 C-D2 C-D3 C-D4 C-D5 C-D6 C-D7 C-D8 24 23 22 21 20 19 18 17 16 15 14 13 H8 H7 H6 H5 4 5 6 7 14 15 16 17 18 GND GND 1 20 4 5 6 7 14 15 16 17 18 1 20

1 2 3 4 5 6 7 8 9 +12V 1H1 1H2 1H3 1H4 1H5 1H6 1H7 1H8 Q1 R1 H1 1H1 1H2 R2 H2 1H3 Q2 R3 H3 1H4 Q3 R4 H4 1H5 Q4 R5 H5 1H6 Q5 R6 H6 1H7 U2 H1 H2 H3 H4 4 5 6 7 14 15 16 17 18 1 20 1 2 3 4 5 6 7 8 9 10 11 12 H1 H2 H3 H4 C-X1 C-X2 C-X3 C-X4 C-X5 C-X6 C-X7 C-X8 Q6 R7 H7 1H8 Q7 R8 H8 Q8

J1 HSERIN HSRCK HRCK HG\ 1 2 3 4 J2 XSERIN XSRCK XRCK XG\ 1 2 3 4 J3 DSERIN DSRCK DRCK DG\ 1 2 3 4 PB8 PB10 PA23 PB16 PA24 PB11 PB9 PB7

GND

U3 XSERIN 3 XSRCK13 XRCK 12 XG\ 9 8 +5V GND 2 19 11 10 SERIN SRCK RCK G Q0 Q1 Q2 Q3 Q4 SRCLR Q5 Q6 Q7 VDD GND SO GND GND NC NC 6B595

U4 Q0 SERIN Q1 SRCK Q2 RCK Q3 G Q4 Q5 SRCLR Q6 Q7 VDD SO GND GND NC GND NC 6B595 3 13 12 9 8 2 19 11 10 +5V GND DSERIN DSRCK DRCK DG\

8x8 matrix 2 colour

2. Vit chng trnh: Driver: Tn Matrix_Led_Display_dev.c /* khai bo cc th vin cn thit trong chng trnh */
#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/interrupt.h> #include <mach/at91_tc.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <linux/genhd.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #include <linux/clk.h> #include <linux/irq.h> #include <linux/time.h> #include <linux/jiffies.h> ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

109

N TT NGHIP
#include <linux/sched.h> #include <linux/delay.h>

/* khai bo tn Driver v tn thit b */


#define DRVNAME #define DEVNAME "matrix_led_dev" "matrix_led"

/* khai bo cc chn dng iu khin modum ma trn Led */


#define DATA_C #define CLOCK_C #define LATCH_C #define OE_C #define DATA_R #define CLOCK_R #define LATCH_R #define OE_R AT91_PIN_PB8 AT91_PIN_PB10 AT91_PIN_PA23 AT91_PIN_PB16 AT91_PIN_PA24 AT91_PIN_PB11 AT91_PIN_PB9 AT91_PIN_PB7

/* cc lnh to mc High v Low cho cc chn iu khin modun Led */


#define SET_DATA_C() #define SET_CLOCK_C() #define SET_LATCH_C() #define SET_OE_C() #define SET_DATA_R() #define SET_CLOCK_R() #define SET_LATCH_R() #define SET_OE_R() #define CLEAR_DATA_C() #define CLEAR_CLOCK_C() #define CLEAR_LATCH_C() #define CLEAR_OE_C() #define CLEAR_DATA_R() #define CLEAR_CLOCK_R() #define CLEAR_LATCH_R() #define CLEAR_OE_R() gpio_set_value(DATA_C,1) gpio_set_value(CLOCK_C,1) gpio_set_value(LATCH_C,1) gpio_set_value(OE_C,1) gpio_set_value(DATA_R,1) gpio_set_value(CLOCK_R,1) gpio_set_value(LATCH_R,1) gpio_set_value(OE_R,1) gpio_set_value(DATA_C,0) gpio_set_value(CLOCK_C,0) gpio_set_value(LATCH_C,0) gpio_set_value(OE_C,0) gpio_set_value(DATA_R,0) gpio_set_value(CLOCK_R,0) gpio_set_value(LATCH_R,0) gpio_set_value(OE_R,0)

/* khai bo cc bin cn dng trong chng trnh */


static atomic_t matrix_led_open_cnt = ATOMIC_INIT(1); int i=0; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

110

N TT NGHIP /* DataDisplay l mng cha d liu hin th ra ma trn Led (d liu dch ra IC 6B595 iu khin hng), mng c 8 phn t ng vi d liu hng ca 8 ct ma trn Led */
unsigned char DataDisplay[8]; unsigned char MatrixCode[5];

/*mng ColumnCode to d liu mt bit dch chuyn trn 8 ct ca ma trn Led */


unsigned char ColumnCode[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

/* bng m font Asscii sang ma trn Led*/


unsigned char font[]={ 0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0xFF,0xA0,0xFF,0xFF, 0xFF,0xFF,0xF8,0xF4,0xFF, 0xEB,0x80,0xEB,0x80,0xEB, 0xDB,0xD5,0x80,0xD5,0xED, 0xD8,0xEA,0x94,0xAB,0x8D, 0xC9,0xB6,0xA9,0xDF,0xAF, 0xFF,0xFF,0xF8,0xF4,0xFF, 0xFF,0xE3,0xDD,0xBE,0xFF, 0xFF,0xBE,0xDD,0xE3,0xFF, 0xD5,0xE3,0x80,0xE3,0xD5, 0xF7,0xF7,0xC1,0xF7,0xF7, 0xFF,0xA7,0xC7,0xFF,0xFF, 0xF7,0xF7,0xF7,0xF7,0xF7, 0xFF,0x9F,0x9F,0xFF,0xFF, 0xFF,0xC9,0xC9,0xFF,0xFF, 0xC1,0xAE,0xB6,0xBA,0xC1, 0xFF,0xBD,0x80,0xBF,0xFF, 0x8D,0xB6,0xB6,0xB6,0xB9, 0xDD,0xBE,0xB6,0xB6,0xC9, 0xE7,0xEB,0xED,0x80,0xEF, 0xD8,0xBA,0xBA,0xBA,0xC6, 0xC3,0xB5,0xB6,0xB6,0xCF, 0xFE,0x8E,0xF6,0xFA,0xFC, 0xC9,0xB6,0xB6,0xB6,0xC9, //SPACE //! //' //# //$ //% //& //' //( //) //* //+ //, ////x /// //0 //1 //2 //3 //4 //5 //6 //7 //8 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

111

N TT NGHIP
0xF9,0xB6,0xB6,0xD6,0xE1, 0xFF,0xC9,0xC9,0xFF,0xFF, 0xFF,0xA4,0xC4,0xFF,0xFF, 0xF7,0xEB,0xDD,0xBE,0xFF, 0xEB,0xEB,0xEB,0xEB,0xEB, 0xFF,0xBE,0xDD,0xEB,0xF7, 0xFD,0xFE,0xAE,0xF6,0xF9, 0xCD,0xB6,0x8E,0xBE,0xC1, 0x83,0xF5,0xF6,0xF5,0x83, 0xBE,0x80,0xB6,0xB6,0xC9, 0xC1,0xBE,0xBE,0xBE,0xDD, 0xBE,0x80,0xBE,0xBE,0xC1, 0x80,0xB6,0xB6,0xB6,0xBE, 0x80,0xF6,0xF6,0xFE,0xFE, 0xC1,0xBE,0xB6,0xB6,0xC5, 0x80,0xF7,0xF7,0xF7,0x80, 0xFF,0xBE,0x80,0xBE,0xFF, 0xDF,0xBF,0xBE,0xC0,0xFE, 0x80,0xF7,0xEB,0xDD,0xBE, 0x80,0xBF,0xBF,0xBF,0xFF, 0x80,0xFD,0xF3,0xFD,0x80, 0x80,0xFD,0xFB,0xF7,0x80, 0xC1,0xBE,0xBE,0xBE,0xC1, 0x80,0xF6,0xF6,0xF6,0xF9, 0xC1,0xBE,0xAE,0xDE,0xA1, 0x80,0xF6,0xE6,0xD6,0xB9, 0xD9,0xB6,0xB6,0xB6,0xCD, 0xFE,0xFE,0x80,0xFE,0xFE, 0xC0,0xBF,0xBF,0xBF,0xC0, 0xE0,0xDF,0xBF,0xDF,0xE0, 0xC0,0xBF,0xCF,0xBF,0xC0, 0x9C,0xEB,0xF7,0xEB,0x9C, 0xFC,0xFB,0x87,0xFB,0xFC, 0x9E,0xAE,0xB6,0xBA,0xBC, 0xFF,0x80,0xBE,0xBE,0xFF, 0xFD,0xFB,0xF7,0xEF,0xDF, 0xFF,0xBE,0xBE,0x80,0xFF, //9 //: //// //< //= //> //? //@ //A //B //C //D //E //F //G //H //I //J //K //L //M //N //O //P //Q //R //S //T //U //V //W //X //Y //Z //[ //\ //] 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

112

N TT NGHIP
0xFB,0xFD,0xFE,0xFD,0xFB, 0x7F,0x7F,0x7F,0x7F,0x7F, 0xFF,0xFF,0xF8,0xF4,0xFF, 0xDF,0xAB,0xAB,0xAB,0xC7, 0x80,0xC7,0xBB,0xBB,0xC7, 0xFF,0xC7,0xBB,0xBB,0xBB, 0xC7,0xBB,0xBB,0xC7,0x80, 0xC7,0xAB,0xAB,0xAB,0xF7, 0xF7,0x81,0xF6,0xF6,0xFD, 0xF7,0xAB,0xAB,0xAB,0xC3, 0x80,0xF7,0xFB,0xFB,0x87, 0xFF,0xBB,0x82,0xBF,0xFF, 0xDF,0xBF,0xBB,0xC2,0xFF, 0xFF,0x80,0xEF,0xD7,0xBB, 0xFF,0xBE,0x80,0xBF,0xFF, 0x83,0xFB,0x87,0xFB,0x87, 0x83,0xF7,0xFB,0xFB,0x87, 0xC7,0xBB,0xBB,0xBB,0xC7, 0x83,0xEB,0xEB,0xEB,0xF7, 0xF7,0xEB,0xEB,0xEB,0x83, 0x83,0xF7,0xFB,0xFB,0xF7, 0xB7,0xAB,0xAB,0xAB,0xDB, 0xFF,0xFB,0xC0,0xBB,0xBB, 0xC3,0xBF,0xBF,0xDF,0x83, 0xE3,0xDF,0xBF,0xDF,0xE3, 0xC3,0xBF,0xCF,0xBF,0xC3, 0xBB,0xD7,0xEF,0xD7,0xBB, 0xF3,0xAF,0xAF,0xAF,0xC3, 0xBB,0x9B,0xAB,0xB3,0xBB, 0xFB,0xE1,0xE0,0xE1,0xFB, 0xE3,0xE3,0xC1,0xE3,0xF7, 0xF7,0xE3,0xC1,0xE3,0xE3, 0xEF,0xC3,0x83,0xC3,0xEF, }; void __iomem *at91tc0_base; ________________________________________________________________________________ //^ //_ //' //a //b //c //d //e //f //g //h //I //j //k //l //m //n //o //p //q //r //s //t //u //v //w //x //y //z //^ //-> //<// 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

0xFF,0xFF,0xFF,0xFF,0xFF //BLANK CHAR 95

CHNG III: LP TRNH GIAO TIP NGOI VI

113

N TT NGHIP
struct clk *at91tc0_clk;

/*chng trnh vit d liu hng ra cc port ca IC 6B595 iu khin hng */


void row_write_data(unsigned char data) { int j; for (j=0;j<8;j++) {

/ *set hoc clear chn DATA_R ty thuc vo gi tr ca data */


(data&(1<<j))? SET_DATA_R():CLEAR_DATA_R();

/* to xung chn CLOCK_R dch d liu ra IC 6B595 */


SET_CLOCK_R(); CLEAR_CLOCK_R(); }

/* to xung chn LATCH_R cht d liu trong IC 6B595 */


SET_LATCH_R(); CLEAR_LATCH_R(); }

/*chng trnh vit d liu ct ra cc port ca IC 6B595 iu khin ct */


void column_write_data(unsigned char data) { int j; for (j=0;j<8;j++) { (data&(1<<j))? SET_DATA_C():CLEAR_DATA_C(); SET_CLOCK_C(); CLEAR_CLOCK_C(); } SET_LATCH_C(); CLEAR_LATCH_C(); }

/* chng trnh phc v ngt, c 1ms chng trnh phc v ngt ny s c thc hin mt ln */
static irqreturn_t at91tc0_isr(int irq, void *dev_id) { int status;

// Read TC0 status register to reset RC compare status.


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

114

N TT NGHIP
status = ioread32(at91tc0_base + AT91_TC_SR);

/*set chn OE_C v OE_R cch ly d liu bn trong 6B595 v d liu xut ra cc chn ca 6B595 */
SET_OE_C(); SET_OE_R();

/* vit d liu hng v ct tng ng ra modun ma trn Led */


row_write_data(DataDisplay[i]); column_write_data(ColumnCode[i]);

/*clear chn OE_C v OE_R xut d liu bn trong 6B595 ra cc chn d liu ca 6B595 */
CLEAR_OE_C(); CLEAR_OE_R();

/* bin i = 0 ng vi v tr ct u tin ca ma trn Led, i = 1 ng vi v tr ct th 2 ca ma trn Led, tng t i = 7 ng vi v tr ct cui cng ca ma trn Led */
i++;

/* khi v tr qut n ct th 8 ca ma trn Led th ta quay li v tr th nht */


if (i==8) { i = 0; } return IRQ_HANDLED; }

/* chng trnh chuyn m Asscii sang m ma trn Led */


void asscii_to_matrix_led (unsigned char { MatrixCode[0] = font[data * 5 +0]; MatrixCode[1] = font[data * 5 +1]; MatrixCode[2] = font[data * 5 +2]; MatrixCode[3] = font[data * 5 +3]; MatrixCode[4] = font[data * 5 +4]; } data)

/* chng trnh nhn d liu t User Application */


static ssize_t matrix_led_write (struct file *filp, unsigned char __iomem buf[], size_t bufsize, loff_t *f_pos) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

115

N TT NGHIP
unsigned char write_buf[1]; int write_size = 0;

/*nhn d liu t user v chp vo write_buf */


if (copy_from_user (write_buf, buf, 1) != 0) { return -EFAULT; } else { write_size = bufsize;

/*trong bng m Asscii k t khong trng c gi tr l 32, nhng trong bng font ma trn Led k t khong trng li l 5 byte u tin trong mng nn khi chuyn t m Asscii sang m ma trn Led chng ta phi dng (m Asscii 32) */
asscii_to_matrix_led(write_buf[0]-32); printk("asscii to matrix led %d complete\n", write_buf[0]);

/* chp m ma trn ca k t mun hin th vo mng hin th*/


DataDisplay[0] = ~0xFF; DataDisplay[1] = ~MatrixCode[0]; DataDisplay[2] = ~MatrixCode[1]; DataDisplay[3] = ~MatrixCode[2]; DataDisplay[4] = ~MatrixCode[3]; DataDisplay[5] = ~MatrixCode[4]; DataDisplay[6] = ~0xFF; DataDisplay[7] = ~0xFF; } return write_size; } static int matrix_led_open(struct inode *inode, struct file *file) { int result = 0; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

116

N TT NGHIP
unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&matrix_led_open_cnt)) { atomic_inc(&matrix_led_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; } static int matrix_led_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&matrix_led_open_cnt); return 0; } struct file_operations matrix_led_fops = { .write .open }; static struct miscdevice matrix_led_dev = { .minor .name .fops }; static int __init matrix_led_mod_init(void) { int ret=0; ________________________________________________________________________________ = MISC_DYNAMIC_MINOR, = "matrix_led", = &matrix_led_fops, = matrix_led_write, = matrix_led_open,

.release = matrix_led_close,

CHNG III: LP TRNH GIAO TIP NGOI VI

117

N TT NGHIP
gpio_request (DATA_C, NULL); gpio_request (CLOCK_C, NULL); gpio_request (LATCH_C, NULL); gpio_request (OE_C, NULL); gpio_request (DATA_R, NULL); gpio_request (CLOCK_R, NULL); gpio_request (LATCH_R, NULL); gpio_request (OE_R, NULL); at91_set_GPIO_periph (DATA_C, 1); at91_set_GPIO_periph (CLOCK_C, 1); at91_set_GPIO_periph (LATCH_C, 1); at91_set_GPIO_periph (OE_C, 1); at91_set_GPIO_periph (DATA_R, 1); at91_set_GPIO_periph (CLOCK_R, 1); at91_set_GPIO_periph (LATCH_R, 1); at91_set_GPIO_periph (OE_R, 1);

gpio_direction_output(DATA_C, 0); gpio_direction_output(CLOCK_C, 0); gpio_direction_output(LATCH_C, 0); gpio_direction_output(OE_C, 0); gpio_direction_output(DATA_R, 0); gpio_direction_output(CLOCK_R, 0); gpio_direction_output(LATCH_R, 0); gpio_direction_output(OE_R, 0); at91tc0_clk = clk_get(NULL, // Device pointer - not required. "tc0_clk"); // Clock name. clk_enable(at91tc0_clk); at91tc0_base = ioremap_nocache(AT91SAM9260_BASE_TC0, 64); if (at91tc0_base == NULL) { printk(KERN_INFO "at91adc: TC0 memory mapping failed\n"); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

118

N TT NGHIP
ret = -EACCES; goto exit_5; }

/* Configure TC0 in waveform mode, TIMER_CLK1 and to generate interrupt on RC compare. Load 50000 to RC so that with TIMER_CLK1 = MCK/2 = 50MHz, the interrupt will be generated every 1/50MHz * 50000 = 20nS * 50000 = 1 milli second. NOTE: Even though AT91_TC_RC is a 32-bit register, only 16-bits are programmble.
*/ iowrite32(50000, (at91tc0_base + AT91_TC_RC)); iowrite32((AT91_TC_WAVE | AT91_TC_WAVESEL_UP_AUTO), (at91tc0_base + AT91_TC_CMR)); iowrite32(AT91_TC_CPCS, (at91tc0_base + AT91_TC_IER)); iowrite32((AT91_TC_SWTRG | AT91_TC_CLKEN), (at91tc0_base + AT91_TC_CCR));

/*Install interrupt for TC0*/


ret = request_irq(AT91SAM9260_ID_TC0, // Interrupt number at91tc0_isr, // Pointer to the interrupt sub-routine 0, // Flags - fast, shared or contributing to entropy pool "matrix_led_irq", // Device name to show as owner in /proc/interrupts NULL); // Private data for shared interrupts if (ret != 0) { printk(KERN_INFO "matrix_led_irq: Timer interrupt request failed\n"); ret = -EBUSY; goto exit_6; } misc_register(&matrix_led_dev); printk(KERN_INFO "matrix_led: Loaded module\n"); return ret; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

119

N TT NGHIP
exit_6: iounmap(at91tc0_base); exit_5: clk_disable(at91tc0_clk); return ret; } static void __exit matrix_led_mod_exit(void) { iounmap(at91tc0_base); clk_disable(at91tc0_clk);

// Free TC0 IRQ.


free_irq(AT91SAM9260_ID_TC0, //Interrupt number NULL); // Private data for shared interrupts misc_deregister(&matrix_led_dev); printk(KERN_INFO "matrix_led: Unloaded module\n"); } module_init (matrix_led_mod_init); module_exit (matrix_led_mod_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("TranCamNhan"); MODULE_DESCRIPTION("Character device for for generic gpio api");

User Application: Tn Matrix_Led_Display_app.c /* khai bo cc th vin cn dng trong chng trnh */


#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h> ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

120

N TT NGHIP
#include <pthread.h>

/* khai bo cc bin cn dng trong chng trnh */


int matrix_led_fd; unsigned long int ioctl_buf[3]={0,0,0}; unsigned char write_buf[1];

/* chng trnh in ra mn hnh c php lnh hin th ch ra ma trn Led */


void print_usage(){ printf("matrixled_app <letter>\n"); exit(0); }

/* chng trnh chnh */


int main(int argc, unsigned char **argv) { int res;

/* m tp tin thit b trc khi thao tc */


if ((matrix_led_fd = open("/dev/matrix_led", O_RDWR)) < 0) {

/* nu qu trnh m tp tin tht bi th in ra mn hnh bo li cho ngi dng bit v tr v m li */


printf("Error whilst opening /dev/matrix_led device\n"); return -1; } if (argc != 2) {

/* khi ngi dng sai c php lnh th in ra hng dn c php lnh */


print_usage(); } else

/* nu ngi dng ng c php lnh th tin hnh chp d liu vo write_buf[0] v truyn qua cho driver bng hm write()*/
write_buf[0] = argv[1][0]; write(matrix_led_fd, write_buf, 1); printf ("User: sent %s to driver\n",argv[1][0]); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

121

N TT NGHIP
return 0; }

3. Bin dch v thc thi chng trnh: Bin dch chng trnh, np vo Kit KM9260 v chy chng trnh. III. M rng d n:

V modun ma trn Led ch c 8 hng v 8 ct nn d n ny ch c th xut mi ln 1 k t. xut c nhiu k t hn, cng nh c th hin th c mt chui k t, mt cu th chng ta phi dng thm hiu ng dch ch. Chng ta c th dch ch t tri sang phi hoc t phi sang tri. Chng trnh sau y c th hin th mt chui k t bt k nhp t bn phm vi k t khong trng l du _ (v cu trc lnh ca chng trnh main trong User Application, nu dng khong trng th chng trnh main s hiu l cc tham s argv khc nhau, khuyt dim ny s c khc phc cui d n ny), c th s dng hiu ng dch tri, dch phi, ng yn v c th thay i tc dch ch. C php lnh khi s dng nh sau:
<tn chng trnh> <tn lnh> <tham s>

Trong :
<tn chng trnh> l tn chng trnh sau khi bin dch <tn lnh> l cc lnh dng iu khin ma trn Led. C cc lnh nh: update_content: thay i ni dung mun hin th, lnh ny c tham s l

chui k t mun hin th.


update_speed: thay i tc dch ch, lnh ny c tham s l tc dch

ch thay i t 1 n 100. ng vi gi tr 1 th tc dch ch l chm nht, 100 l tc dch ch l nhanh nht


shift_left: hiu ng dch tri, lnh ny khng c tham s. shift_right: hiu ng dch tri, lnh ny khng c tham s. pause: hiu ng ng yn hnh nh ang c hin th, lnh ny khng c tham

s.
<tham s> l tham s ca lnh.

Chng trnh:
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

122

N TT NGHIP Driver: Tn Matrix_Led_Shift_Display_dev.c /* khai bo cc th vin cn thit cho chng trnh*/


#include <linux/module.h> #include <linux/errno.h> #include <linux/init.h> #include <linux/interrupt.h> #include <mach/at91_tc.h> #include <asm/gpio.h> #include <asm/atomic.h> #include <linux/genhd.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #include <linux/clk.h> #include <linux/irq.h> #include <linux/time.h> #include <linux/jiffies.h> #include <linux/sched.h> #include <linux/delay.h> /* khai bo tn thit b v tn driver */ #define DRVNAME #define DEVNAME "matrix_led_dev" "matrix_led"

/* khai bo cc chn ca vi x l dng trong d n ny */


#define DATA_C #define CLOCK_C #defineLATCH_C #define OE_C #define DATA_R #define CLOCK_R #define LATCH_R #define OE_R AT91_PIN_PB8 AT91_PIN_PB10 AT91_PIN_PA23 AT91_PIN_PB16 AT91_PIN_PA24 AT91_PIN_PB11 AT91_PIN_PB9 AT91_PIN_PB7

/*lnh set v clear cc chn khai bo phn trn */


#define SET_DATA_C() #define SET_CLOCK_C() #define SET_LATCH_C() #define SET_OE_C() #define SET_DATA_R() gpio_set_value(DATA_C,1) gpio_set_value(CLOCK_C,1) gpio_set_value(LATCH_C,1) gpio_set_value(OE_C,1) gpio_set_value(DATA_R,1)

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

123

N TT NGHIP
#define SET_CLOCK_R() #define SET_LATCH_R() #define SET_OE_R() #define CLEAR_DATA_C() gpio_set_value(CLOCK_R,1) gpio_set_value(LATCH_R,1) gpio_set_value(OE_R,1) gpio_set_value(DATA_C,0)

#define CLEAR_CLOCK_C() gpio_set_value(CLOCK_C,0) #define CLEAR_LATCH_C() gpio_set_value(LATCH_C,0) #define CLEAR_OE_C() #define CLEAR_DATA_R() gpio_set_value(OE_C,0) gpio_set_value(DATA_R,0)

#define CLEAR_CLOCK_R() gpio_set_value(CLOCK_R,0) #define CLEAR_LATCH_R() gpio_set_value(LATCH_R,0) #define CLEAR_OE_R() gpio_set_value(OE_R,0)

/*nh ngha cc lnh ioctl dng trong chng trnh */


#define MATRIX_LED_DEV_MAGIC 'B' #define SHIFT_LEFT _IOWR(MATRIX_LED_DEV_MAGIC, 1,unsigned long) #define SHIFT_RIGHT _IOWR(MATRIX_LED_DEV_MAGIC, 2,unsigned long) #define UPDATE_SPEED _IOWR(MATRIX_LED_DEV_MAGIC, 3,unsigned long) #define PAUSE _IOWR(MATRIX_LED_DEV_MAGIC, 4,unsigned long)

/* Khai bo cc bin cn thit trong chng trnh */


static atomic_t matrix_led_open_cnt = ATOMIC_INIT(1); int letter,i=0,cycle=0,slip=0,shift=0,shift_speed = 50,pause=0; unsigned char DataDisplay[100]; unsigned char MatrixCode[5]; unsigned char ColumnCode[] ={0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; unsigned char font[] = { 0xFF,0xFF,0xFF,0xFF,0xFF,//SPACE 0xFF,0xFF,0xA0,0xFF,0xFF,//! 0xFF,0xFF,0xF8,0xF4,0xFF,//' 0xEB,0x80,0xEB,0x80,0xEB,//# 0xDB,0xD5,0x80,0xD5,0xED,//$ 0xD8,0xEA,0x94,0xAB,0x8D,//% 0xC9,0xB6,0xA9,0xDF,0xAF,//& 0xFF,0xFF,0xF8,0xF4,0xFF,//' 0xFF,0xE3,0xDD,0xBE,0xFF,//( 0xFF,0xBE,0xDD,0xE3,0xFF,//) 0xD5,0xE3,0x80,0xE3,0xD5,//* 1 2 3 4 5 6 7 8 9 10 0

0xF7,0xF7,0xC1,0xF7,0xF7,//+ 11 ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

124

N TT NGHIP
0xFF,0xA7,0xC7,0xFF,0xFF,//, 0xF7,0xF7,0xF7,0xF7,0xF7,//0xFF,0x9F,0x9F,0xFF,0xFF,//x 0xFF,0xC9,0xC9,0xFF,0xFF,/// 0xC1,0xAE,0xB6,0xBA,0xC1,//0 0xFF,0xBD,0x80,0xBF,0xFF,//1 0x8D,0xB6,0xB6,0xB6,0xB9,//2 0xDD,0xBE,0xB6,0xB6,0xC9,//3 0xE7,0xEB,0xED,0x80,0xEF,//4 0xD8,0xBA,0xBA,0xBA,0xC6,//5 0xC3,0xB5,0xB6,0xB6,0xCF,//6 0xFE,0x8E,0xF6,0xFA,0xFC,//7 0xC9,0xB6,0xB6,0xB6,0xC9,//8 0xF9,0xB6,0xB6,0xD6,0xE1,//9 0xFF,0xC9,0xC9,0xFF,0xFF,//: 0xFF,0xA4,0xC4,0xFF,0xFF,//// 0xF7,0xEB,0xDD,0xBE,0xFF,//< 0xEB,0xEB,0xEB,0xEB,0xEB,//= 0xFF,0xBE,0xDD,0xEB,0xF7,//> 0xFD,0xFE,0xAE,0xF6,0xF9,//? 0xCD,0xB6,0x8E,0xBE,0xC1,//@ 0x83,0xF5,0xF6,0xF5,0x83,//A 0xBE,0x80,0xB6,0xB6,0xC9,//B 0xC1,0xBE,0xBE,0xBE,0xDD,//C 0xBE,0x80,0xBE,0xBE,0xC1,//D 0x80,0xB6,0xB6,0xB6,0xBE,//E 0x80,0xF6,0xF6,0xFE,0xFE,//F 0xC1,0xBE,0xB6,0xB6,0xC5,//G 0x80,0xF7,0xF7,0xF7,0x80,//H 0xFF,0xBE,0x80,0xBE,0xFF,//I 0xDF,0xBF,0xBE,0xC0,0xFE,//J 0x80,0xF7,0xEB,0xDD,0xBE,//K 0x80,0xBF,0xBF,0xBF,0xFF,//L 0x80,0xFD,0xF3,0xFD,0x80,//M 0x80,0xFD,0xFB,0xF7,0x80,//N 0xC1,0xBE,0xBE,0xBE,0xC1,//O 0x80,0xF6,0xF6,0xF6,0xF9,//P 40 41 42 43 44 45 46 47 48 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

125

N TT NGHIP
0xC1,0xBE,0xAE,0xDE,0xA1,//Q 0x80,0xF6,0xE6,0xD6,0xB9,//R 0xD9,0xB6,0xB6,0xB6,0xCD,//S 0xFE,0xFE,0x80,0xFE,0xFE,//T 0xC0,0xBF,0xBF,0xBF,0xC0,//U 0xE0,0xDF,0xBF,0xDF,0xE0,//V 0xC0,0xBF,0xCF,0xBF,0xC0,//W 0x9C,0xEB,0xF7,0xEB,0x9C,//X 0xFC,0xFB,0x87,0xFB,0xFC,//Y 0x9E,0xAE,0xB6,0xBA,0xBC,//Z 0xFF,0x80,0xBE,0xBE,0xFF,//[ 0xFD,0xFB,0xF7,0xEF,0xDF,//\ 0xFF,0xBE,0xBE,0x80,0xFF,//] 0xFB,0xFD,0xFE,0xFD,0xFB,//^ 0x7F,0x7F,0x7F,0x7F,0x7F,//_ 0xFF,0xFF,0xF8,0xF4,0xFF,//' 0xDF,0xAB,0xAB,0xAB,0xC7,//a 0x80,0xC7,0xBB,0xBB,0xC7,//b 0xFF,0xC7,0xBB,0xBB,0xBB,//c 0xC7,0xBB,0xBB,0xC7,0x80,//d 0xC7,0xAB,0xAB,0xAB,0xF7,//e 0xF7,0x81,0xF6,0xF6,0xFD,//f 0xF7,0xAB,0xAB,0xAB,0xC3,//g 0x80,0xF7,0xFB,0xFB,0x87,//h 0xFF,0xBB,0x82,0xBF,0xFF,//i 0xDF,0xBF,0xBB,0xC2,0xFF,//j 0xFF,0x80,0xEF,0xD7,0xBB,//k 0xFF,0xBE,0x80,0xBF,0xFF,//l 0x83,0xFB,0x87,0xFB,0x87,//m 0x83,0xF7,0xFB,0xFB,0x87,//n 0xC7,0xBB,0xBB,0xBB,0xC7,//o 0x83,0xEB,0xEB,0xEB,0xF7,//p 0xF7,0xEB,0xEB,0xEB,0x83,//q 0x83,0xF7,0xFB,0xFB,0xF7,//r 0xB7,0xAB,0xAB,0xAB,0xDB,//s 0xFF,0xFB,0xC0,0xBB,0xBB,//t 0xC3,0xBF,0xBF,0xDF,0x83,//u 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 66 67 68 69 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

126

N TT NGHIP
0xE3,0xDF,0xBF,0xDF,0xE3,//v 0xC3,0xBF,0xCF,0xBF,0xC3,//w 0xBB,0xD7,0xEF,0xD7,0xBB,//x 0xF3,0xAF,0xAF,0xAF,0xC3,//y 0xBB,0x9B,0xAB,0xB3,0xBB,//z 0xFB,0xE1,0xE0,0xE1,0xFB,//^ 0xE3,0xE3,0xC1,0xE3,0xF7,//-> 0xF7,0xE3,0xC1,0xE3,0xE3,//<0xEF,0xC3,0x83,0xC3,0xEF,// }; void __iomem *at91tc0_base; struct clk *at91tc0_clk; void row_write_data(unsigned char data) { int j; for (j=0;j<8;j++){ (data&(128>>j))? SET_DATA_R():CLEAR_DATA_R(); SET_CLOCK_R(); CLEAR_CLOCK_R(); } SET_LATCH_R(); CLEAR_LATCH_R(); } void column_write_data(unsigned char data) { int j; for (j=0;j<8;j++){ (data&(1<<j))? SET_DATA_C():CLEAR_DATA_C(); SET_CLOCK_C(); CLEAR_CLOCK_C(); } SET_LATCH_C(); CLEAR_LATCH_C(); } static irqreturn_t at91tc0_isr(int irq, void *dev_id) { int status; 86 87 88 89 90 91 93 93 94

0xFF,0xFF,0xFF,0xFF,0xFF//BLANK CHAR 95

// Read TC0 status register to reset RC compare status.


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

127

N TT NGHIP
status = ioread32(at91tc0_base + AT91_TC_SR); if (shift!=0) { if (cycle < shift_speed) { SET_OE_C(); SET_OE_R(); row_write_data(DataDisplay[slip+i]); column_write_data(ColumnCode[i]); CLEAR_OE_C(); CLEAR_OE_R(); i++; if (i==8) { i = 0; cycle++; } } else { cycle = 0; if (pause==0) { if (shift==1) { slip++; if (slip == letter*5+8) { slip = 0; } } else { slip--; if (slip == 0) { slip = letter*5+8; } } } } } return IRQ_HANDLED; } void asscii_to_matrix_led (unsigned char MatrixCode[0] = font[data * 5 +0]; ________________________________________________________________________________ data) {

CHNG III: LP TRNH GIAO TIP NGOI VI

128

N TT NGHIP
MatrixCode[1] = font[data * 5 +1]; MatrixCode[2] = font[data * 5 +2]; MatrixCode[3] = font[data * 5 +3]; MatrixCode[4] = font[data * 5 +4]; } static int matrix_led_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg[]){ int retval; switch (cmd) { case SHIFT_LEFT: shift = 1; pause = 0; break; case SHIFT_RIGHT: shift = 2; pause = 0; break; case UPDATE_SPEED: shift_speed = 101 - arg[0]; break; case PAUSE: pause =1; break; default: printk ("Driver: Don't have this operation \n"); retval = -EINVAL; break; } return retval; } static ssize_t matrix_led_write (struct file *filp, unsigned char __iomem buf[], size_t bufsize, loff_t *f_pos) { unsigned char write_buf[100] ; int write_size = 0,letter_byte; if (copy_from_user (write_buf, buf, bufsize) != 0) { return -EFAULT; } else { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

129

N TT NGHIP
write_size = bufsize; printk("write size: %d\n",write_size); DataDisplay[0] = 0x0; DataDisplay[1] = 0x0; DataDisplay[2] = 0x0; DataDisplay[3] = 0x0; DataDisplay[4] = 0x0; DataDisplay[5] = 0x0; DataDisplay[6] = 0x0; DataDisplay[7] = 0x0; for (letter=0;letter < write_size;letter++){ if (write_buf[letter] == 95) { write_buf[letter] = 32; } asscii_to_matrix_led(write_buf[letter]-32); for(letter_byte=0;letter_byte < 5; letter_byte) { DataDisplay[letter*5+8+letter_byte] = ~MatrixCode[letter_byte]; } } DataDisplay[letter*5+8+0] = 0x0; DataDisplay[letter*5+8+1] = 0x0; DataDisplay[letter*5+8+2] = 0x0; DataDisplay[letter*5+8+3] = 0x0; DataDisplay[letter*5+8+4] = 0x0; DataDisplay[letter*5+8+5] = 0x0; DataDisplay[letter*5+8+6] = 0x0; DataDisplay[letter*5+8+7] = 0x0; slip = 0; cycle = 0; i = 0; } return write_size; } static int ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

130

N TT NGHIP
matrix_led_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&matrix_led_open_cnt)) { atomic_inc(&matrix_led_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; } static int matrix_led_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&matrix_led_open_cnt); return 0; } struct file_operations matrix_led_fops = { .write .ioctl .open }; static struct miscdevice matrix_led_dev = { .minor .name .fops }; static int __init matrix_led_mod_init(void) { int ret=0; ________________________________________________________________________________ = MISC_DYNAMIC_MINOR, = "matrix_led", = &matrix_led_fops, = matrix_led_write, = matrix_led_ioctl, = matrix_led_open,

.release = matrix_led_close,

CHNG III: LP TRNH GIAO TIP NGOI VI

131

N TT NGHIP
gpio_request (DATA_C, NULL); gpio_request (CLOCK_C, NULL); gpio_request (LATCH_C, NULL); gpio_request (OE_C, NULL); gpio_request (DATA_R, NULL); gpio_request (CLOCK_R, NULL); gpio_request (LATCH_R, NULL); gpio_request (OE_R, NULL); at91_set_GPIO_periph (DATA_C, 1); at91_set_GPIO_periph (CLOCK_C, 1); at91_set_GPIO_periph (LATCH_C, 1); at91_set_GPIO_periph (OE_C, 1); at91_set_GPIO_periph (DATA_R, 1); at91_set_GPIO_periph (CLOCK_R, 1); at91_set_GPIO_periph (LATCH_R, 1); at91_set_GPIO_periph (OE_R, 1);

gpio_direction_output(DATA_C, 0); gpio_direction_output(CLOCK_C, 0); gpio_direction_output(LATCH_C, 0); gpio_direction_output(OE_C, 0); gpio_direction_output(DATA_R, 0); gpio_direction_output(CLOCK_R, 0); gpio_direction_output(LATCH_R, 0); gpio_direction_output(OE_R, 0); at91tc0_clk = clk_get(NULL,//Device pointer - not required. "tc0_clk"); // Clock name. clk_enable(at91tc0_clk); at91tc0_base = ioremap_nocache(AT91SAM9260_BASE_TC0, 64); if (at91tc0_base == NULL) { printk(KERN_INFO "TC0 memory mapping failed\n"); ret = -EACCES; goto exit_5; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

132

N TT NGHIP
} iowrite32(50000, (at91tc0_base + AT91_TC_RC)); iowrite32((AT91_TC_WAVE | AT91_TC_WAVESEL_UP_AUTO), (at91tc0_base + AT91_TC_CMR)); iowrite32(AT91_TC_CPCS, (at91tc0_base + AT91_TC_IER)); iowrite32((AT91_TC_SWTRG | AT91_TC_CLKEN), (at91tc0_base + AT91_TC_CCR)); //Install interrupt for TC0. ret = request_irq( AT91SAM9260_ID_TC0, at91tc0_isr, 0, "matrix_led_irq",NULL); if (ret != 0) { printk(KERN_INFO "matrix_led_irq: Timer interrupt request failed\n"); ret = -EBUSY; goto exit_6; } misc_register(&matrix_led_dev); printk(KERN_INFO "matrix_led: Loaded module\n"); return ret; exit_6: iounmap(at91tc0_base); exit_5: clk_disable(at91tc0_clk); return ret; } static void __exit matrix_led_mod_exit(void){ iounmap(at91tc0_base); clk_disable(at91tc0_clk); // Free TC0 IRQ. free_irq( AT91SAM9260_ID_TC0, // Interrupt number NULL); // Private data for shared interrupts misc_deregister(&matrix_led_dev); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

133

N TT NGHIP
printk(KERN_INFO "matrix_led: Unloaded module\n"); } module_init (matrix_led_mod_init); module_exit (matrix_led_mod_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("TranCamNhan"); MODULE_DESCRIPTION("Character device for for generic gpio api");

User Application: Tn Matrix_Led_Shift_Display_app.c


#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/ioctl.h> #include <pthread.h> #define MATRIX_LED_DEV_MAGIC #define SHIFT_LEFT #define SHIFT_RIGHT #define UPDATE_SPEED #define PAUSE int matrix_led_fd; unsigned long ioctl_buf[3]={0,0,0}; unsigned char write_buf[100]; void print_usage(){ printf("matrixled_app update_content <sentence which you want to display on MatrixLed, Space = '_'>\n"); printf("matrixled_app 100>\n"); printf("matrixled_app printf("matrixled_app shift_left\n"); shift_right\n"); update_speed <speed from 1 to 'B' _IOWR(MATRIX_LED_DEV_MAGIC, 1,unsigned long) _IOWR(MATRIX_LED_DEV_MAGIC, 2,unsigned long) _IOWR(MATRIX_LED_DEV_MAGIC, 3,unsigned long)

_IOWR(MATRIX_LED_DEV_MAGIC, 4,unsigned long)

printf("matrixled_app pause\n"); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

134

N TT NGHIP
exit(0); } int main(int argc, unsigned char **argv) { int res,i; if ((matrix_led_fd = open("/dev/matrix_led", O_RDWR)) < 0) { printf("Error whilst opening /dev/matrix_led device\n"); return -1; } if (argc == 2) { if (!strcmp (argv[1],"pause")){ ioctl(matrix_led_fd,PAUSE,ioctl_buf); } else if (!strcmp(argv[1],"shift_left")){ ioctl(matrix_led_fd,SHIFT_LEFT,ioctl_buf); }else if (!strcmp(argv[1],"shift_right")){ ioctl(matrix_led_fd,SHIFT_RIGHT,ioctl_buf); }else print_usage(); }else if (argc == 3) { if (!strcmp(argv[1],"update_speed")){ ioctl_buf[0] = atoi(argv[2]); ioctl(matrix_led_fd,UPDATE_SPEED,ioctl_buf); }else if (!strcmp(argv[1],"update_content")){ for (i=0;i<strlen(argv[2]);i++){ write_buf[i] = argv[2][i]; } write(matrix_led_fd, write_buf, strlen(argv[2])); printf("Update Content Complete: <%s> \n",argv[2]); }else print_usage(); }else print_usage(); return 0; }

IV.

Kt lun v bi tp:

1. Kt lun:
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

135

N TT NGHIP Trong d n ny chng ta s dng phng php qut hin th mt k t bt k, mt chui k t bt k trn ma trn Led 8X8. Chng trnh ca chng ta c 2 phn l Driver v User Application. Nh ni trong phn trn, trong chng trnh ny khi chng ta mun hin th khong trng trn ma trn Led th chng ta phi nhp d liu l du _ nn s gy ra s kh chu khi s dng i vi ngi dng chng trnh v chng ta khng th hin th du _ trn ma trn Led c. khc phc vn ny, th trong phn lnh update_content thay v chng ta nhp d liu vo tham s argv[2] ca lnh main th chng ta np d liu ny vo trong mt bin kiu chui bng lnh gets(). Sau truyn bin ny sang cho Driver, lc chng ta c th khc phc c khuyt im ca chng trnh trn. Ngoi ra chng trnh trn ch hin th ma trn Led mt mu. V vy chng ta c th m rng ng dng bng cch vit thm Driver hin th hai mu da vo Driver trn. 2. Bi tp : 1. Vit chng trnh (Driver v User Application) hin th d liu trn ma trn Led mt mu c cc hiu ng dch tri, dch phi, dng yn, thay i tc dch v nhp d liu mun hin th bng lnh gets(). 2. Vit chng trnh (Driver v User Application) hin th d liu trn ma trn Led hai mu c cc hiu ng dch tri, dch phi, dng yn, thay i tc dch, chn c mu ch hin th v nhp d liu mun hin th bng lnh gets().

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

136

N TT NGHIP BI 6

GIAO TIP IU KHIN ADC0809

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

137

N TT NGHIP BI 7

GIAO TIP IU KHIN MODULE I2C


7-1I. TNG QUAN V I2C: Gii thiu I2C:

I2C l chun truyn thng ni tip do hng in t Phiilip xy dng vo nm 1990. I2C c kh nng truyn ni tip a ch, ngha l trong mt bus c th c nhiu hn mt thit b lm Master. Chun I2C thng c tm thy trong nhng thit b in t nh EEPROM 24CXX, realtime DS1307,... v mt s thit b khc. (Cc kin thc v I2C c trnh bi sau y c su tm t trang web www.hocavr.com). Chun I2C c kt ni theo dng sau:

Trong chun I2C c hai ng dy dng truyn v nhn d liu: SDA, v SCL. Trong SDA l ng d liu truyn nhn. D liu truyn nhn l cc bit 0 v 1 tng ng vi mc thp v mc cao. V tr bit trong d liu c ng b ha bi xung clock thng qua ng SCL. Nh vy ng SCL l ng cung cp xung dng b d liu. C hai ng SCL v SDA iu c cu hnh cc gp h (Open-collector) v th khi c lp t trong h thng cn phi c in tr ko ln Vcc to mc thp v mc cao trong qu trnh truyn d liu. Cc thit b trong truyn theo chun I2C trong cng mt h thng c kt ni song song, mi thit b iu c da ch ring dng phn bit vi nhau trong qu trnh truyn v nhn d liu. Ti mt thi im ch c hai thit b, mt thit b ng vai tr l slave v mt thit b ng vai tr l master, truyn v nhn d liu. Cc thit b khc trong cng mt bus b v hiu ha.
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

138

N TT NGHIP II. Cc thut ng v giao thc truyn trong I2C: Sau y l cc thut ng thng c s dng trong ch truyn ni tip I2C, trong mi thut ng chng ta s tm hiu v nh ngha v vai tr trong giao thc. Trn c s s hiu r cch thc hot ng ca chun I2C: Master: L thit b khi ng qu trnh truyn nhn. Thit b ny s pht ra cc bit d liu trn ng SDA v xung ng b trn ng SCL. (Trong gio trnh ny Master l chip ARM9260). Slave: L thit b phc v cho Master khi c yu cu. Mi mt thit b c mt a ch ring. a ch thit b c quy nh nh sau: Mi loi thit b khc nhau (chng hn EEPROM, Realtime, hay ADC, ...) nh sn xut s quy nh mt a ch khc nhau, c gi l a ch thit b. Bn cnh cn c a ch phn bit gia cc thit b cng loi (Chng hn nhiu EEPROM 24CXX c kt ni chung vi nhau), a ch ny c ngi s dng thit b quy nh. SDA-Serial Data: L ng truyn d liu ni tip. ng ny s m nhn nhim v truyn thng tin v a ch v d liu theo th t tng bit. Lu trong chun I2C th bit MSB c truyn trc nht, cui cng l LSB, cch truyn ny ngc vi chun truyn ni tip UART. SCL-Serial clock: L ng gi nhp cho truyn v nhn d liu. Nhip ng b d liu do thit b ng vai tr l Master pht ra. Quy nh ca qu trnh truyn d liu ny l: Ti thi dim mc cao ca SCL d liu trn chn SDA khng c thay i trng thi. D liu trn chn SDA chi c quyn thay i trng thi khi xung SCL mc thp. Khi chn SCL mc cao, nu SDA thay i trng thi th thit b I2C nhn ra l cc bit Start hoc Stop; START transmition: L trng thi bt u qu trnh truyn v nhn d liu c quy nh: trng thi chn SCL mc cao v chn SDA chuyn trng thi t mc cao xung mc thp, cnh xung. STOP stransmition: L trng thi kt thc qu trnh truyn v nhn d liu c quy nh: trng thi chn SCL mc cao v chn SDA chuyn trng thi t mc thp ln mc cao; Address: L a ch thit b, thng thng c quy nh c 7 bit;
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

139

N TT NGHIP Data: L d liu truyn nhn, thng thng c quy nh c 8 bit; Repeat Start-Bt u lp li: Khong gia hai trng thi Start v Stop l khong bn ca ng truyn, cc Master khc khng c tc ng vo ng truyn trong khong ny. Trng hp sau khi kt thc truyn nhn m Master khng gi trng thi Stop m gi thm trng thi Start tip tc truyn nhn d liu, qu trnh ny gi l Repeat Start. Trng hp ny xut hin khi Master mun ly hoc truyn d liu lin tip t cc Slave. Address Packet Format-nh dng gi d liu: Trong mng I2C tt c cc thit b u c th l Master hay Slave. Mi thit b c mt a ch c nh gi l Device address. Khi mt Master mun giao tip vi mt Slave, trc ht n s to ra mt trng thi START tip theo s gi a ch thit b ca Slave cn giao tip trn ng truyn, th th xut hin thut ng gi a ch (Address packet). Gi a ch trong I2C c nh dng 9 bits trong 7 bits u (gi l SLA, c gi lin sau START) cha a ch Slave (Mt s trng hp a ch c 10 bits), mt bit READ/WRITE v mt bit ACK (Acknowledge) xc nhn thng tin a ch. a ch c di 7 bits nn s thit b ti a c th giao tip l 128 thit b. Nhng c mt s a ch khng c hiu l a ch thit b. Cc a ch l 1111xxx (tc l cc a ch ln hn hoc bng 120 khng c dng). Ring a ch 0 c dng cho cuc gi chung. Bit READ/WRITE c truyn theo sau 7 bits a ch l bit bo cho Slave bit l Master mun c hay ghi d liu vo Slave. Nu bit ny bng 0 (mc thp) th qu trnh ghi d liu t Master n Slave c yu cu, nu bit ny bng 1 th Master mun c d liu t Slave v. 8 bits trn (SLA+RD/WR) c Master pht ra sau khi pht START, nu mt Slave trn mng nhn ra rng a ch m Master yu cu trng khp vi a ch ca mnh, no s p tr li Master bng cch dp tr li bng tn hiu xc nhn ACK bng cch ko chn SDA xung thp trong xung gi nhp th 9. Ngc li nu khng c Slave p ng li, th chn SDA vn gi mc cao trong xung gi nhp th 9 th gi l tn hiu khng xc nhn NOT ACK, lc ny Master cn phi c nhng ng x ph hp ty theo mi trng hp c th, v d Master c th gi trng thi STOP v sau pht li a ch Slave khc... Nh vy, trong 9 bit ca gi a ch th ch c 8 bits c gi t Master, bit cn li l do Slave. V d Master mun yu cu c d liu t Slave c a ch
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

140

N TT NGHIP 43, n cn pht ra cho Slave mt byte nh sau: (43<<1)+1, trong (43<<1) l ch s 43 v bn tri 1 v tr v 7 bits a ch nm cc v tr cao trong gi a ch, sau cng gi tr ny vi 1 tc l qu trnh c d liu c yu cu. Hnh bn di m t qu trnh pht gi a ch thit b t Master n Slave;

General call- Cuc gi chung: Khi Master pht i gi a ch c dng 0 (thc cht l 0+W) tc n mun thc hin mt cuc gi chung n tt c cc Slave. Tt nhin cho php hay khng cho php l do cuc gi chung quyt nh. Nu Slave c ci t cho php cuc gi chung, chng s dp li Master bng bit ACK. Cuc gi chung thng xuy ra khi Master mun gi d liu chung n tt c cc Slave. Ch l cuc gi chung c dng 0+R l v ngha v khng bao gi c trng hp l Master nhn d liu t tt c cc Slave vo cng mt thi im. Data Packet Format-nh dng gi d liu: Sau khi a ch c pht i, Slave s p ng li Master bng ACK th qu trnh truyn nhn d liu bt u gia cp Master v Slave ny. Tu vo bit R/W trong gi a ch, d liu c th c truyn theo hng t Master n Slave hay t Slave n Master. D di chuyn theo hng no th gi d liu lun bao gm 9 bits trong 8 bits u l d liu, 1 bit cui l ACK. 8 bits d liu do thit b pht gi v bit ACK do thit b nhn to ra. V d Master tin hnh gi d liu n Slave, n s pht ra 8 bits d liu, Slave nhn v pht ra ACK (ko SDA xung 0 chn th 9) sau Master s quyt nh gi tip byte d liu khc hay khng. Nu Slave pht tn hiu NOT ACK (khng tc ng chn SDA xung mc thp xung gi nhp th 9) sau khi nhn d liu th Master s kt thc qu trnh gi bng cch pht i trng thi STOP. Hnh bn di m t nh dng gi d liu trong I2C.
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

141

N TT NGHIP

Phi hp gi a ch v gi d liu: Mt qu trnh truyn nhn thng c bt u t Master. Master pht i mt bit trng thi START sau gi gi a ch SLA+R/W trn ng truyn. Tip theo nu c mt Slave p ng li, d liu c th truyn nhn lin tip trn ng truyn (1 hoc nhiu byte lin tip). Khung truyn thng thng c m t nh hnh bn di.

Multi-Master Bus-ng truyn a thit b ch: Nh trnh by trn, I2C l chun truyn thng a thit b ch, ngha l ti mt thi im c th c nhiu hn 1 thit b lm Master nu cc thit b ny pht ra bit trng thi START cng mt lc. Nu cc Master c cng yu cu v thao tc i vi Slave th chng c th cng tn ti v qu trnh truyn nhn c th thnh cng. Tuy nhin trong a s trng hp s c mt s Master b tht lc. Mt Master b tht lc khi n truyn/nhn mt mc cao trong khi mt Master khc truyn/nhn mc thp. III. Kt lun: Chng ta tm hiu nhng kin thc cn bn nht v chun giao tip I2C, trong bao gm nh ngha v cc thut ng, cu trc gi a ch v gi d liu. Th nhng y ch mi l cc kin thc cn bn chung nht gip cho chng ta hiu nguyn l hot ng ca h thng giao tip I2C. Trong nhng bi sau, chng ta s tm hiu cch m h thng linux dng qun l ng truyn I2C giao tip vi cc thit b Slave khc. ng thi s a ra nhng bi tp v d vit chng trnh user
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

142

N TT NGHIP giao tip vi eeprom 24c08. Trn c s nhng phng php lp trnh ny ngi hc c th p dng iu khin cc thit b hot ng theo chun I2C khc.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

143

N TT NGHIP 7-2I2C TRONG LINUX:

I. Gii thiu: Giao tip theo chun I2C c chia lm 2 thnh phn, khi to giao thc truyn t Master v quy nh giao thc nhn ca Slave. y chip AT91SAM9260 s ng vai tr l Master c iu khin bi h iu hnh nhng Linux. V Slave l cc thit b ngoi vi do h h thng Linux iu khin. Giao thc truyn ca Master phi ph hp vi giao thc nhn ca Slave th chng mi c th thc hin thnh cng vic truyn v nhn d liu vi nhau. Bi ny s nghin cu cc giao thc m h iu hnh Linux h tr giao tip vi nhiu thit b ngoi vi khc nhau. sau khi hiu nguyn l hot ng ca tng thit b Slave chng ta c th p dng vo iu khin d dng. Cc kin thc c lin quan n chun I2C ca h iu hnh Linux c vit rt y trong th mc Documentation/I2C ca m ngun kernel. Nhng thng tin sau y c bin son t ti liu ny, nu c nhng vn khng c trnh by r cc bn c th tham kho thm. Linux quy nh nhng thut ng sau thun tin cho vic m t cc giao thc I2C:
S P (1 bit) : (1 bit) :

Start bit Stop bit Read/Write bit. Rd = 1, Wr = 0. Bit ACK hoc bit NOT ACK. L 7 bits a ch thit b (device address). a ch ny c th m rng ln thnh 10 bits. L 8 bits a ch ca thanh ghi trong thit b. Mi thit b bao gm c nhiu nh khc nhau, mi nh cha mt thng tin ring v c duy nht mt a ch. L 8 bits d liu truyn/nhn, trong ch truyn theo byte. Trong ch truyn theo word, c hiu l 8 bits cao DataHigh hoc 8 bits thp DataLow.

Rd/Wr (1 bit) : A, NA (1 bit) : Addr (7 bits):

Comm

(8 bits):

Data

(8 bits):

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

144

N TT NGHIP
Count (8 bits):

L 8 bits quy nh s bytes ca khi d liu trong ch truyn/nhn d liu theo khi.

Lu : Nhng tham s cha trong du ngoc vung [..] c hiu l c truyn t thit b Slave n Master ngc li c truyn t Master n Slave. V d:
Data : L d liu truyn t Master n Slave; [Data]: L d liu truyn t Slave n Master;

Linux xy dng mt giao thc giao tip vi chun I2C mang tn SMBus (System Management Bus) giao tip vi cc thit b c quy nh theo chun I2C. C nhiu thit b ngoi vi khc nhau th cng s c nhiu cu trc giao tip khc nhau tng ng vi tng chc nng truy xut m thit b h tr. Nhim v ca ngi lp trnh l phi la chn giao thc SMBus ph hp giao tip vi thit b cn iu khin. Phn tip theo s trnh by cc giao thc SMBus thng c s dng m Linux h tr. II. Cc giao din hm trong driver I2C: a. Gii thiu v driver I2C trong Linux: Thng thng cc thit b I2C c iu khin bi lp kernel, thng qua cc lnh c nh ngha trong m ngun Linux. Th nhng chng ta cng c th s dng nhng giao din c nh ngha sn trong driver I2C do Linux h tr. Ngha l thay v iu khin trc tip thng qua cc hm trong kernel, chng ta s iu khin gin tip thng qua cc giao din hm trong driver. Cc giao din hm ny s gi cc hm trong kernel h tr iu khin Slave theo yu cu t user. Driver I2C c cha trong th mc drivers/I2C ca m ngun Linux. Thng thng chng ta s dng cc hm trong tp tin driver I2C-device.c. Trong tp tin
I2C-dev.c nh ngha cc giao din hm nh: read(), write() v ioctl() v

mt s nhng giao din khc phc v cho ng v m tp tin thit b. Trong


read() v write() dng c v ghi vo thit b Slave theo dng tng khi.

Ngoi ra bng cch dng giao din hm ioctl() chng ta c th thc hin tt c cc theo tc c/ghi trn thit b Slave v mt s nhng thao tc khc nh nh a ch thit b, kim tra cc hm chc nng, chn ch giao tip 8 bits hay 10 bits a ch.
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

145

N TT NGHIP Tip theo chng ta s tm hiu cc giao din read(), write() v ioctl(). b. Giao tip vi thit b I2C Slave thng qua driver I2C: thun tin cho vic tm hiu v ng dng cc hm giao din sao cho thun li nht, chng ta s tm hiu theo hng nghin cu cc bc thc hin v gii thch tng on chng trnh v d. Cc on chng trnh v d ny nm trong user application, s dng cc hm h tr trong driver I2C. Bc 1: u tin mun giao tip vi Bus I2C chng ta phi xc nh s tn ti ca giao din tp tin thit b trong th mc /dev/. Thng th tp tin thit b ny c tn l /dev/i2c-0. Nu khng c tp tin thit b ny trong thc mc /dev/ chng ta phi bin dch li m ngun kernel v check vo mc bin dch driver I2C. Sau khi bin dch xong, ci t vo kit v khi ng li h thng. Bc 2: Trong user application, m tp tin thit b I2C-0 chun b thao tc; /*Bin lu s m t tp tin khi thit b c m*/
int fd_I2C;

/*Gi giao din hm m tp tin thit b*/


fd_I2C = open(/dev/I2C-0, O_RDWR);

/*Kim tra li trong qu trnh m tp tin thit b*/


if (fd_I2C < 0) {

/* ERROR HANDLING; you can check errno to see what went wrong */ /*Nu c li xy ra th thot chng trnh ang gi*/
exit(1); }

Bc 3: Xc nh a ch thit b mun giao tip; Bng cch gi giao din hm ioctl() vi tham s I2C_SLAVE nh sau: /*Bin lu a ch thit b cn giao tip*/
int addr = 0x40;

/*Gi hm ioctl() xc nh a ch thit b vi s nh danh lnh l I2C_SLAVE*/


if (ioctl(fd_I2C, I2C_SLAVE, addr) < 0) {

/*ERROR HANDLING; you can check errno to see what went wrong*/
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

146

N TT NGHIP /*Thot khi chng trnh khi c li xy ra*/


exit(1); }

Bc 4: S dng cc hm giao din read(), write() v ioctl() truyn/nhn d liu vi Slave. Dng giao din hm read c d liu t Slave: /*Khai bo bin m lu gi tr tr v khi gi hm read()*/
char buf[10];

/*Gi hm read() c d liu hin ti ca thit b Slave, kch tht c v l 1 byte*/


if (read(fd_I2C, buf, 1) != 1) {

/* ERROR HANDLING: I2C transaction failed */ /*Trong trng hp c li xy ra thot khi chng trnh thc thi*/
exit (1); }

/*Lc ny d liu cha trong b nh m buf[0]*/ Cu trc giao thc ny nh sau:


S Addr Rd [A] [Data] NA P

Trong trng hp c v nhiu byte lin tip, chng ta cng dng giao din hm read() nhng vi di n: read(fd_I2C, buf, n); Khi cu trc ca giao thc ngy nh sau:
S Addr Rd [A] [Data] [A] [Data] ... [A] [Data] NA P

**Trong mt s thit b Slave dng I2C, c h tr mt thanh ghi dng lu a ch hin ti truy xut d liu, do khi gi hm read() d liu c v s l ni dung ca nh c a ch lu trong thanh ghi ny. Khi c 1 byte th ni dung ca thanh ghi a ch ny s tng ln 1 n v. Dng giao din hm write ghi d liu vo Slave: Chng ta cng c th dng giao din hm write() ghi d liu v Slave. Khi cu trc ca giao thc ny nh sau: Trong trng hp ghi 1 byte vo thit b Slave:
S Addr Wr [A] Data [A] P

Trong trng hp ghi nhiu byte vo thit b Slave: 147

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

N TT NGHIP
S Addr Wr [A] Comm [A] Data [A] ... Data [A] P

V d sau s minh ha cch ghi b nh m c di 3 bytes vo thit b Slave:


buf[0] = Data0; buf[1] = Data1; buf[2] = Data2; if (write(fd_I2C, buf, 3) ! =3) {

/* ERROR HANDLING: I2C transaction failed */


}

Dng giao din hm ioctl() truyn/nhn d liu v cc chc nng iu khin khc trong driver I2C, mi chc nng s tng ng vi cc tham s lnh khc nhau. ioctl(file, I2C_SLAVE, long addr) : Dng thay i a ch

thit b mun giao tip. a ch ny l gi tr a ch khi cha thm bit R/W vo v tr bit th 8 (LSB) ca gi a ch. ioctl(file, I2C_TENBIT, long select): Dng quy nh ch

giao tip 8 bits hay 10 bits a ch. Ch giao tip a ch 10 bits nu


select khc 0, ch giao tip a ch 7 bit nu select bng 0. V mc

nh l ch giao tip 7 bits a ch. Hm ny ch hp l khi driver I2C c h tr I2C_FUNC_10BIT_ADDR. ioctl(file, I2C_PEC, long select): Dng khi ng hay tt ch

kim tra li trong qu trnh truyn. Bt ch kim tra li khi select khc 0, tt ch kim tra li khi select bng 0. Mc nh l tt kim tra li. Hm ny ch hp l khi driver c h tr I2C_FUNC_SMBUS_PEC;
ioctl(file, I2C_FUNCS, unsigned long *funcs): Dng kim

tra chc nng *funcs ca driver I2C c h tr hay khng.


ioctl(file, I2C_RDWR, struct I2C_rdwr_ioctl_data *msgset):

Dng kt hp hay qu trnh c v ghi trong c ngn cch bi trng thi STOP. Hm ch hp l khi driver c h tr chc nng I2C_FUNC_I2C. Hm ny c tham s l
struct

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

148

N TT NGHIP
I2C_rdwr_ioctl_data *msgset. Vi cu trc I2C_rdwr_ioctl_data

c nh ngha nh sau:
struct I2C_rdwr_ioctl_data { struct I2C_msg *msgs;

/* Con tr n mng d liu ca I2C /* S lng I2C_msg mun c v

*/
int nmsgs;

ghi */
}

vi cu trc struct I2C_msg li c nh ngha nh sau:


struct I2C_msg { __u16 addr; __u16 flags; #define I2C_M_TEN #define I2C_M_RD #define I2C_M_NOSTART #define I2C_M_REV_DIR_ADDR #define I2C_M_IGNORE_NAK #define I2C_M_NO_RD_ACK #define I2C_M_RECV_LEN __u16 len; __u8 * buf; } 0x0010 0x0001 0x4000 0x2000 0x1000 0x0800 0x0400

Nh vy mi mt phn t msg[] s cha mt con tr khc, con tr ny chnh l b m c hay ghi ty thuc vo gi tr ca c I2C_M_RD c bt tng ng cho tng msg[]. Bn cnh msg[] cn c thng s a ch thit b, chiu di b nh m, ... ioctl(file, I2C_SMBUS, struct I2C_smbus_ioctl_data *args):

Bn thn hm ny khng gi thc thi mt chc nng c th. M n s gi thc thi mt trong nhng hm sau y ty vo cc tham s cha trong *arg. Cc chc nng c s dng ty theo quy nh ca tham s *args. III. Cc giao thc SMBus: 1. Giao thc SMBus Quick Command: c nh ngha theo dng hm sau:
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

149

N TT NGHIP
__s32 I2C_smbus_write_quick(int file, __u8 value);

Giao thc ny ch truyn mt bit cho thit b Slave nm ti v tr ca bit R/W c cu trc nh sau:
A Addr Rd/Wr [A] P

2. Giao thc SMBus Receive Byte: c nh ngha theo dng hm sau:


__s32 I2C_smbus_read_byte(int file);

Giao thc ny ra lnh c mt byte ti a ch hin ti t thit b Slave. Thng thng lnh ny c dng sau cc lnh khc dng quy nh a ch mun c. Giao thc c cu trc nh sau:
S Addr Rd [A] [Data] NA P

3. Giao thc SMBus Send Byte: c nh ngha theo dng hm sau:


__s32 I2C_smbus_write_byte(int file, __u8 value);

Giao thc ny dng truyn mt byte xung thit b Slave c cu trc:


S Addr Wr [A] Data [A] P

4. Giao thc SMBus Read Byte: c nh ngha theo dng hm sau:


__s32 I2C_smbus_read_byte_data(int file, __u8 command);

Giao thc ny dng nhn mt byte c a ch thanh ghi l command trong thit b Slave. Giao thc ny tng ng vi hai giao thc send byte v receive byte hot ng lin tip nhng khng c bit STOP ngn cch gia hai giao thc ny. Cu trc ca giao thc SMBus nh sau:
S Addr Wr [A] Comm [A] S Addr Rd [A] [Data] NA P

5. Giao thc SMBus Read Word: c nh ngha theo dng hm sau:


__s32 I2C_smbus_read_word_data(int file, __u8 command);

Giao thc ny dng c mt word data, bao gm byte thp v byte cao bt u ti a ch command. Giao thc c cu trc:
S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P

6. Giao thc SMBus Write Byte: c nh ngha theo dng hm sau:


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

150

N TT NGHIP
__s32 value); I2C_smbus_write_byte_data(int file, __u8 command, __u8

Giao thc ny dng ghi mt byte d liu n thanh ghi c a ch command c cu trc nh sau:
S Addr Wr [A] Comm [A] Data [A] P

7. Giao thc SMBus Write Word: c nh ngha theo dng hm sau:


__s32 I2C_smbus_write_word_data(int file, __u8 command, __u16 value);

Giao thc ny dng ghi mt word d liu c 2 byte, HighByte v LowByte, n thanh ghi c a ch bt du l command. Giao thc c cu trc:
S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P

8. Giao thc SMBus Block Read: Giao thc ny c nh ngha theo dng hm sau:
__s32 *values); I2C_smbus_read_block_data(int file, __u8 command, __u8

Dng c t thit b Slave mt khi d liu c chiu di ln ti 32 bytes (Ty theo kh nng ca thit b Slave) c a ch bt u t command vi s byte c c quy nh trong tham s count. Giao thc thc ny c cu trc sau:
S Addr Wr [A] Comm [A] S Addr Rd [A] [Count] A [Data] A [Data] A ... A [Data] NA P

9. Giao thc SMBus Block Write: c nh ngha theo dng hm sau:


__s32 I2C_smbus_write_block_data(int file, __u8 command, __u8 length,

__u8 *values); Giao thc ny dng ghi mt khi d liu c chiu di quy nh bi length (ti a l 32 bits) ti a ch bt u l command. Giao thc c cu trc nh sau:
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P

**Trn y l 9 giao thc cn bn v thng s dng nht trong giao tip theo chun I2C. y ch mi l nhng giao thc do Linux quy nh sn cho Master khi
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

151

N TT NGHIP mun thao tc vi thit b Slave. giao tip thnh cng vi mi thit b, trc tin chng ta phi tm hiu quy nh v cch thc giao tip ca thit b , sau s p dng mt hay nhiu giao thc SMBus trn thc hin mt tc v c th do thit b Slave h tr. IV. Kt lun: Trong bi ny chng ta nghin cu nhng nguyn l v cc bc cn bn v thao tc truyn d liu theo chun I2C trong driver I2C_dev. Driver I2C do Linux h tr bao gm tt c nhng giao thc ph hp vi cc thit b Slave khc nhau. Trong cc bi sau, chng ta s i tm hiu giao thc truyn nhn ca mt s thit b Slave ng thi s p dng cc hm trong driver I2C iu khin truy xut d liu t cc thit b ny.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

152

N TT NGHIP 7-3THC HNH GIAO TIP EEPROM I2C 24C08:

I. Gii thiu chung v EEPROM: ** quyn sch ny c s tp trung v ng hng, trong phn ny chng ti khng trnh by mt cch chi tit cu to v nguyn l hot ng m ch trnh by giao thc truyn d liu theo chun I2C ca EEPROM 24C08. t p dng nhng lnh hc trong hai bi trc vo iu khin thnh cng thit b Slave ny. 1. M t: EEPROM 24C08 c nhng chc nng sau: Dung lng 8Kb (1KB); L ROM c th lp trnh v xa bng xung in; Ch truyn theo chun I2C;

2. S chn:

Trong : A0, A1, A2: L 3 chn a ch ng vo dng chn a ch phn bit nhiu eeprom ghp song song vi nhau. i vi eeprom 24C08 ch c 1 chn A2 c php chn la a ch. Nh vy ch c 2 eeprom 24C08 c ni chung vi nhau trn 1 bus I2C. SDA v SCL: L chn d liu v chn clock trong chun I2C; WP: L chn bo v chng ghi vo eeprom; VCC v GND l hai chn cp ngun cho eeprom;

3. a ch thit b: a ch thit b eeprom 24C08 c quy nh nh trong hnh v sau:

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

153

N TT NGHIP

4. Giao thc ghi d liu: EEPROM 24Cxx c hai ch ghi d liu, ghi theo tng byte v ghi theo tng block. a. Ghi theo tng byte: Ch ny c minh ha bng giao thc sau:

b. Ghi theo tng block: Ch ny c minh ha bng giao thc sau:

**EEPROM 24C08 c th h tr ch ghi d liu theo trang c di ln ti 16 bytes. 5. Giao thc c d liu: EEPROM 24Cxx c 3 ch c d liu, c ti a ch hin ti, c ngu nhin v c theo tun t; a. c ti a ch hin ti: Ch ny c minh ha bng giao thc sau:

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

154

N TT NGHIP b. c ngu nhin: Ch ny c minh ha bng giao thc sau:

c. c theo tun t: Ch ny c minh ha bng giao thc sau:

II. D n iu khin EEPROM 24C08: 1. Phc tho d n: Mc ch ca d n l lm cho ngi hc c kh nng s dng nhng hm trong driver I2C h tr iu khin EEPROM 24C08. Bn cnh cn gip ngi hc rn luyn cch vit mt chng trnh user application s dng th vin lin kt ng. a. Yu cu d n: Chng trnh c xy dng thao tc vi eeprom 24Cxx vi cc chc nng sau: Ghi mt chui thng tin bao gm 256 bytes vo cc nh trong eeprom 24Cxx bt u t 0 kt thc 255. thc hin chc nng ny, ngi s dng chng trnh nhp cu lnh thc thi theo c php sau:
./<tn chng trnh> write_numbers

c ln lt thng tin ca cc nh c a ch t 0 n 255 trong eeprom 24Cxx xut ra mn hnh hin th. thc hin chc nng ny ngi s dng chng trnh phi nhp cu lnh thc thi theo c php sau:

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

155

N TT NGHIP
./<tn chng trnh> read_numbers

Ghi chui k t c nhp t ngi dng vo eeprom bt u t nh c a ch 00h, s k t c ghi ph thuc vo chiu di ca chui k t. thc hin chc nng ny, ngi s dng chng trnh phi nhp cu lnh thc thi theo c php sau:
./<tn chng trnh> write_string

c chui k t t eeprom bt u t nh c a ch 00h, s k t mun c do ngi s dng chng trnh quy nh. thc hin chc nng ny ngi dng phi nhp cu lnh thc thi theo c php sau:
./<tn chng trnh> read_string <s k t mun c>

b. Phn cng nhim v: Driver: S dng driver I2C c h tr sn trong kernel. (Cc hm chc nng h tr trong driver I2C c chng ti trnh by k trong bi trc). Application: Chng trnh trong user c xy dng thnh nhiu lp con khc nhau, c chia thnh cc tp tin nh: 24cXX.h, 24cXX.c v eeprom.c; Tp tin chng trnh chnh mang tn eeprom.c cha hm main() c khai bo di dng cu trc tham s thu thp thng tin t ngi dng. eeprom.c gi cc hm c nh ngha trong cc tp tin khc (Ch yu l tp tin 24cXX.h). eeprom.c thc hin 4 nhim v: o M tp tin thit b driver I2C mang tn I2C-0 trong th mc /dev/ sau quy nh cc thng s nh: a ch Slave thit b, s bits a ch thanh ghi, ... lu vo cu trc eeprom s dng trong nhng ln tip theo. Ty theo tham s la chn ca ngi dng m thc hin mt trong 4 chc nng sau: o Ghi ln lt cc s t 00h n FFh n cc nh c a ch t 00h n FFh trong eeprom 24Cxx; o c ni dung ca cc nh t 00h n FFh ln lt ghi ra mn hnh hin th;
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

156

N TT NGHIP o Ghi chui k t c nhp t ngi dng vo eeprom 24Cxx, vi gii hn s k t do eeprom quy nh. V tr ghi bt u t a ch 00h. o c chui k t c lu trong epprom ghi ra mn hnh hin th, vi kch tht c do ngi lp trnh quy nh (nhp t tham s ngi dng); 2. Thc hin: a. Kt ni phn cng: Cc bn kt ni phn cng theo s sau y:

b. Chng trnh dirver: Driver c s dng trong d n ny mang tn I2C-0 trong th mc /dev/. Nhng chc nng lnh trong driver c trnh by k trong bi trc. c. Chng trnh application: Tp tin chng trnh chnh: eeprom.c /*Khai bo th vin cho cc hm cn dng trong chng trnh*/
#include <stdio.h> #include <fcntl.h> #include <getopt.h> #include <unistd.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include "24cXX.h" /*Gn tp tin nh ngha 24cXX.h vo chng trnh chnh

*/ /*Hm in hng dn cho ngi dng trong trng hp nhp sai c php*/
void use(void) { ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

157

N TT NGHIP
printf("./i2c read_numbers|read_string|write_numbers|write_string for read_string>|<string_to_write_string>)"); exit(1); } (<number

/*Hm thc hin chc nng c ni dung ca eeprom struct eeprom *e, t nh c a ch int addr, kch tht mun c l int size. Mi ln c, thng tin c xut ra mn hnh di dng s hex.*/
static int read_from_eeprom(struct eeprom *e, int addr, int size) {

/*Khai bo bin lu k t c v v bin m c v mt khi k t*/


int ch, i;

/*Vng lp c thng tin t eeprom ti a ch addr n size, sau khi c tng gi tr addr ln 1 n v*/
for(i = 0; i < size; ++i, ++addr) {

/*c thng tin t eeprom ti a ch addr ng thi kim tra li trong qu trnh c*/
if((ch = eeprom_read_byte(e, addr)) < 0)

/*In ra thng bo trong trng hp c li xy ra*/


printf("read error\n");

/*C mi 16 ln in thng tin th xung hng mt ln*/


if( (i % 16) == 0 ) printf("\n %.4x| ", addr);

/*C mi 8 ln tin thng tin th thm mt khong trng*/


else if( (i % 8) == 0 ) printf(" } "); printf("%.2x ", ch);

/*In hai k t xung hng khi kt thc qu trnh c thng tin*/


printf("\n\n"); return 0; }

/*Hm thc hin chc nng ghi s t 00 n ff bt u t a ch addr*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

158

N TT NGHIP
static int write_to_eeprom(struct eeprom *e, int addr) {

/*Bin m iu khin vng lp ghi d liu vo eeprom*/


int i;

/*Vng lp t 0 n 256, mi ln c tng gi tr addr ln 1 n v chun


b cho ln c tip theo*/ for(i=0; i<256; i++, addr++) {

/*Ghi thng tin ra mn hnh trc khi ghi vo eeprom*/


if( (i % 16) == 0 ) printf("\n %.4x| else if( (i % 8) == 0 ) printf(" "); printf("%.2x ", i); ", addr);

/*Ghi d liu vo eeprom ti a ch addr, kim tra li trong qu trnh ghi d liu*/
if(eeprom_write_byte(e, addr, i)<0) printf("write error\n"); }

/*In k t xung dng khi qu trnh c kt thc*/


printf("\n"); return 0; }

/*Hm thc hin chc nng ghi chui thng tin t ngi dng vo eeprom*/
int test_write_ee(struct eeprom *e, char *data, int size) { int i;

/*Vng lp ghi tng k t trong chui char *data vo eeprom ti a ch i*/


for(i=0;i<size;i++){

/*Ghi k t data[i] vo a ch i trong eeprom ng thi kim tra li trong qu trnh ghi d liu*/
if(eeprom_write_byte(e, i, data[i])<0){ printf("write error\n"); return -1; } ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

159

N TT NGHIP
}

/*In thng bo khi qu trnh ghi kt thc*/


printf("Writing finishes!"); printf("\n"); return 0; }

/*Hm thc hin chc nng c k t t eeprom bt u t a ch 00, kch tht l size*/
int test_read_ee(struct eeprom *e, int size) { int i; char ch;

/*c k t t 0 n size ghi ra mn hnh hin th*/


for(i=0;i<size;i++) { if((ch = eeprom_read_byte(e, i)) < 0) { printf("read error\n"); return -1; }

/*Dng hm putchat() ghi k t ra mn hnh hin th*/


putchar(ch); } printf("\n"); return 0; } int main(int argc,char** argv) {

/*Khai bo cu trc eeprom lu nhng thng tin loi eeprom, s bit a ch thanh ghi, .. cu trc c nh ngha trong tp tin 24cXX.h*/
struct eeprom e;

/*S k t nhp vo*/


int number_of_char;

/*Thng bo m tp tin thit b*/


printf("Open /dev/i2c-0 with 8 bit mode\n");

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

160

N TT NGHIP /*M tp tin thit b i2c, cp nht a ch eeprom, hm eeprom c nh ngha trong tp tin 24cXX.c v 24cXX.h*/
if(eeprom_open("/dev/i2c-0",0x50,EEPROM_TYPE_8BIT_ADDR, &e) < 0) printf("unable to open eeprom device file \n");

/*Trong trng hp thc hin chc nng c gi tr nh t 00h n ffh ghi ra mn hnh hin th*/
if (!strcmp(argv[1],"read_numbers")){ fprintf(stderr,"Reading 256 bytes from 0x0\n"); read_from_eeprom(&e,0,256);

/*Trong trng hp thc hin chc nng 1, ghi s t 00 n ff ln cc nh trong eeprom bt u t a ch 00h*/
} else if (!strcmp(argv[1],"write_numbers")) { fprintf(stderr, "Writing 0x00-0xff into 24C08 \n"); write_to_eeprom(&e,0); printf("Writing finishes!");

/*Trong trng hp thc hin chc nng c chui thng tin t eeprom hin th ra mn hnh*/
} else if (!strcmp(argv[1],"read_string")) { number_of_char = atoi(argv[2]); printf("Reading eeprom from address 0x00 with size %d \n",number_of_char); printf ("The read string is: "); test_read_ee(&e,number_of_char);

/*Trong trng hp thc hin chc nng ghi chui thng tin t ngi dng vo eeprom*/
} else if (!strcmp(argv[1],"write_string")) { number_of_char = strlen(argv[2]); fprintf(stderr, "Writing eeprom from address 0x00 with size %d \n",number_of_char); test_write_ee(&e,argv[2],number_of_char);

/*Trong trng hp c li xy ra do c php*/


} else { use(); exit(1); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

161

N TT NGHIP
} eeprom_close(&e); return 0; }

Hai tp tin sau c dng nh ngha nhng hm c s dng trong eeprom.c, truy xut trc tip n cc hm trong driver I2C-0 iu khin eeprom. Nu c nhu cu cc bn c th c thm nghin cu ngha ca tng hm trong tp tin 24cXX.c. Nu khng chng ta s s dng nhng hm chc nng c nh ngha trong tp tin 24cXX.h nh l nhng hm h tr sn trong th vin lin kt tnh. Tp tin th vin: 24Cxx.h /*Khai bo tp tin nh ngha 24cXX.h*/
#ifndef _24CXX_H_ #define _24CXX_H_

/*Gn th vin ca driver i2c-dev cho chun i2c*/


#include <linux/i2c-dev.h> #include <linux/i2c.h>

/*nh ngha hng s quy nh ch truy xut a ch*/


#define EEPROM_TYPE_UNKNOWN 0 #define EEPROM_TYPE_8BIT_ADDR #define EEPROM_TYPE_16BIT_ADDR 1/*Ch truy xut a ch 8 bits*/ 2/*Ch truy xut a ch 16 bits*/

/*nh ngha cu trc eeprom Cu trc ny bao gm nhng thng tin sau: char *dev: con tr char lu tn ng dn thit b int addr: Bin lu a ch thit b Slave int fd: Bin lu s m t tp tin thit b khi c m int type: Bin lu kiu eeprom truy xut*/
struct eeprom { char *dev; int addr; int fd; int type; }; ________________________________________________________________________________ // device file i.e. /dev/i2c-N // i2c address // file descriptor // eeprom type

CHNG III: LP TRNH GIAO TIP NGOI VI

162

N TT NGHIP /* Hm eeprom_open() dng m tp tin thit b Slave eeprom; Bao gm cc thng s sau: char *dev_fqn: ng dn n tp tin thit b mun m; int addr: a ch ca thit b Slave mun m; int type: Loi eeprom cn truy xut; struct eeprom: Sau khi m thnh cng tp tin thit b vi ia ch addr, loi eeprom type, ... Cc thng tin ny s c cp nht trong cc field tng ng ca cu trc struct eeprom; */
int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom*);

/* Hm eeprom_close() dng ng thit b eeprom sau khi truy xut xong; Hm bao gm cc tham s sau: struct eeprom *e: L con tr thit b eeprom mun ng, sau khi ng nhng thng tin trong cc field ca thit b *e c khi phc li trng thi ban u; */
int eeprom_close(struct eeprom *e);

/* Hm eeprom_read_byte() dng c mt byte d liu c a ch __u16 mem_addr ca thit b struct eeprom* e; Gi tr c c s tr v lm gi tr ca hm; Lu : Trc khi s dng hm ny, phi m bo l thit b struct eeprom* e c cp nht a ch trc bng cch gi hm eeprom_oepn() v hm ny s gi thc thi hm ioctl(fd, I2C_SLAVE, address); c h tr trong driver /dev/i2c-N */
int eeprom_read_byte(struct eeprom* e, __u16 mem_addr);

/*

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

163

N TT NGHIP Hm eeprom_read_current_byte() c gi tr nh c a ch hin ti cha trong thanh ghi a ch ca eeprom struct eeprom *e; */
int eeprom_read_current_byte(struct eeprom *e);

/* Hm eeprom_write_byte() dng ghi gi tr __u8 data vo nh c a ch __u16 mem_addr ca thit b struct eeprom *c; */
int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data); #endif

Tp tin chng trnh con: 24cXX.c /*Tp tin 24cXX c nhim v ding95 ngha nhng hm khai bo trong tp tin 24cXX.h*/
#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <linux/fs.h> #include <sys/types.h> #include <sys/ioctl.h> #include <errno.h> #include <assert.h> #include <string.h> #include "24cXX.h"

/*Hm i2c_smbus_access() nh ngha mt giao thc tng qut trong truyn|nhn d liu thng qua chun i2c. N bao hm tt c nhng giao thc khc, vic la chn giao thc thc hin do cc tham s trong hm quy nh; Hm bao gm nhng tham s cn bn nh sau: int file: S m t tp tin thit b c m trong h thng; char read_write: C cho bit l lnh c hay ghi vo Slave; __u8 command: Byte d liu mun ghi vo Slave; Thng th command c vai tr l a ch thanh ghi trong thit b mun truy xut;
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

164

N TT NGHIP int size: L kch thc tnh theo bytes ca khi d liu mun truy xut; union i2c_smbus_data *data: L cu trc d liu truyn nhn trong smBus i2c;*/
static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,int size, union i2c_smbus_data *data){

/*Khai bo bin lu cu trc d liu truyn nhn trong ioctl*/


struct i2c_smbus_ioctl_data args;

/*Cp nht thng tin c hay ghi*/


args.read_write = read_write;//read/write

/*Cp nht thng tin command cho cu lnh*/


args.command = command;

/*Cp nht kch tht d liu mun c hay ghi*/


args.size = size;//size of data

/*Lu d liu tr v trong trng hp c, D liu mun ghi trong trng


hp ghi */ args.data = data; return ioctl(file,I2C_SMBUS,&args); }

/* Hm i2c_smbus_read_byte() c v gi tr ca nh c a ch lu trong thanh ghi a ch ca eeprom; Hm c tham s l int file: L s m t tp tin thit b c m. */
static inline __s32 i2c_smbus_read_byte(int file){

/*Bin cu trc d liu truy xut t thit b I2C*/


union i2c_smbus_data data; if(i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&dat a)) return -1; else return 0x0FF & data.byte; }

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

165

N TT NGHIP /*Hm i2c_smbus_write_byte() dng ghi d liu c chiu di 1 byte vo eeprom nhm mc ch l cp nht gi tr cho thanh ghi a ch trong eeprom; Hm c cc tham s nh sau: int file: S m t tp tin thit b c m; __u8 value: Gi tr mun ghi vo eeprom, ni dng hn l a ch mun cp nht*/
static inline __s32 i2c_smbus_write_byte(int file, __u8 value) { return i2c_smbus_access(file,I2C_SMBUS_WRITE,value, I2C_SMBUS_BYTE,NULL); }

/*Hm i2c_smbus_read_byte_data() c nhim v c gi tr ca nh c a ch c th trong eeprom; Hm c cc tham s sau: int file: S m t tp tin thit b c m; __u8 command: a ch nh mun c;*/
static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command){ union i2c_smbus_data data; if(i2c_smbus_access(file,I2C_SMBUS_READ,command,I2C_SMBUS_BYT E_DATA,&data)) return -1; else return 0x0FF & data.byte; }

/* i2c_smbus_write_byte_data() dng ghi 1 byte vo nh c a ch c th trong eeprom; Cc tham s c th hm nh sau: int file: S m t tp tin thit b ang dc m thao tc; __u8 command: a ch thanh ghi mun ghi d liu; __u8 value: Gi tr d liu mun ghi; */
static inline __s32 ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

166

N TT NGHIP
i2c_smbus_write_byte_data(int file, __u8 command,__u8 value){ union i2c_smbus_data data; data.byte = value; return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, I2C_SMBUS_BYTE_DATA, &data); }

/*Hm
static command) {

i2c_smbus_read_word_data()
inline __s32

cng

tng

nh
file,

hm
__u8

i2c_smbus_read_byte_data() nhng d liu tr v l mt word c 32 bits*/


i2c_smbus_read_word_data(int

union i2c_smbus_data data; if(i2c_smbus_access(file,I2C_SMBUS_READ,command,I2C_SMBUS_WOR D_DATA,&data)) return -1; else return 0x0FFFF & data.word; }

/*Hm
static {

i2c_smbus_write_word_data
inline __s32

cng

tng

nh
file,

hm
__u8

i2c_smbus_write_byte_data() nhng d liu tr v l mt word c 32 bits */


i2c_smbus_write_word_data(int command,__u16 value) union i2c_smbus_data data; data.word = value; return i2c_smbus_access(file,I2C_SMBUS_WRITE,command, I2C_SMBUS_WORD_DATA, &data); }

/*nh ngha hm ghi 1 byte vo thit b struct eeprom *e*/


static int i2c_write_1b(struct eeprom *e, __u8 buf) { int r;

/*we must simulate a plain I2C byte write with SMBus functions*/
r = i2c_smbus_write_byte(e->fd, buf); if(r < 0) fprintf(stderr,"Error i2c_write_1b: %s\n", strerror(errno)); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

167

N TT NGHIP
usleep(10); return r; }

/*nh ngha hm ghi 2 bytes vo thit b struct eeprom *e*/


static int i2c_write_2b(struct eeprom *e, __u8 buf[2]) { int r;

//we must simulate a plain I2C byte write with SMBus functions
r = i2c_smbus_write_byte_data(e->fd, buf[0], buf[1]); if(r < 0) fprintf(stderr, "Error i2c_write_2b: %s\n", strerror(errno)); usleep(10); return r; }

/*nh ngha hm ghi 2 bytes vo thit b struct eeprom *e*/


static int i2c_write_3b(struct eeprom *e, __u8 buf[3]) { int r;

// we must simulate a plain I2C byte write with SMBus functions //the __u16 data field will be byte swapped by the SMBus protocol
r = i2c_smbus_write_word_data(e->fd, buf[0], buf[2] << 8 | buf[1]); if(r < 0) fprintf(stderr, "Error i2c_write_3b: %s\n", strerror(errno)); usleep(10); return r; }

/*nh ngha hm m thit b struct eeprom *e*/


int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom* e) {

/*nh ngha cc bin lu thng tin v hm h tr ca i2c: funcs; S m t tp tin thit b fd; Bin lu m li tr v khi truy xut: r*/
int funcs, fd, r; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

168

N TT NGHIP /*Xa cc thng tin trong cu trc struct eepom *e*/


e->fd = e->addr = 0; e->dev = 0;

/*M tp tin thit b theo ng dn dev_fqn*/


fd = open(dev_fqn, O_RDWR);

/*Kim tra li trong qu trnh m thit b/


if(fd <= 0) { fprintf(stderr, strerror(errno)); return -1; } "Error eeprom_open: %s\n",

/*Gi hm ioctl trong driver kim tra nhng hm trong driver h tr*/
if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0)) { fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno)); return -1; }

/*Ln lt kim tra nhng hm trong driver h tr*/


CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE ); CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE ); CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE_DATA ); CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE_DATA ); CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_WORD_DATA ); CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_WORD_DATA );

/*Gi hm ioctl() quy nh a ch ca thit b mun truy xut*/


if( ( r = ioctl(fd, I2C_SLAVE, addr)) < 0) { fprintf(stderr, "Error eeprom_open: %s\n", strerror(errno)); return -1; }

/*Cp nht cc thng tin sau khi m thit b thnh cng vo cu trc struct eeprom *e phc v cho nhng ln truy xut thit b trong nhng ln tip theo*/
e->fd = fd; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

169

N TT NGHIP
e->addr = addr; e->dev = dev_fqn; e->type = type; return 0; }

/*nh ngha hm ng ng thit b struct eeprom *e*/


int eeprom_close(struct eeprom *e) {

/*Gi giao din hm close ng tp tin thit b*/


close(e->fd);

/*Khi phc li cc thng tin ban u trong cu trc struct eeprom *e*/
e->fd = -1; e->dev = 0; e->type = EEPROM_TYPE_UNKNOWN; return 0; }

/*Cc hm h tr c d liu t eeprom*/ /*Hm c gi tr trong nh c a ch mem_addr*/


int eeprom_read_byte(struct eeprom* e, __u16 mem_addr) {

/*Bin lu m li tr v cho hm trong trng hp c li xy ra nu khng c li th r v gi tr ca nh c c*/


int r;

/*Gi hm ioctl() c chc nng xa b nh m c trong kernel*/


ioctl(e->fd, BLKFLSBUF);

/*Kim tra tng loi eeprom l loi a ch 8 bits hay 16 bits*/ /*Trong trng hp l loi eeprom c a ch 8 bits*/
if(e->type == EEPROM_TYPE_8BIT_ADDR) {

/*Ch ly 8 bits thp ca mem_addr lu vo b m a ch*/


__u8 buf = mem_addr & 0x0ff;

/*Gi hm ghi 1 byte a ch vo eeprom*/


r = i2c_write_1b(e, buf);

/*Trong trng hp epprom loi 16 bits a ch*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

170

N TT NGHIP
} else if(e->type == EEPROM_TYPE_16BIT_ADDR) {

/*nh ngha mng 2 bin 8 bits lu byte a ch thp v byte a ch cao*/


__u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };

/*Ghi mng 2 bytes a ch vo eeprom bng cch gi hm i2c_write_2b()*/


r = i2c_write_2b(e, buf);

/*Cc trng hp cn li in ra li v khng c loi eeprom c h tr*/


} else { fprintf(stderr, "ERR: unknown eeprom type\n"); return -1; }

/*Nu ghi a ch b li th thot chng trnh v in ra m li*/


if (r < 0) return r;

/*Nu khng c li xy ra tip tc c gi tr ti nh va cp nht a ch*/


r = i2c_smbus_read_byte(e->fd); return r; }

/*Hm h tr eeprom ghi mt byte vo a ch c th trong eeprom*/


int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data) {

/*Ban u xc nh a ch cn ghi d liu*/ /*Trong trng hp eeprom c a ch 8 bits*/


if(e->type == EEPROM_TYPE_8BIT_ADDR) {

/*Ghi 2 bytes, byte u tin l a ch ca nh; byte tip theo l d liu cn ghi*/ /*Khai bo mng lu 2 bytes thng tin*/
__u8 buf[2] = { mem_addr & 0x00ff, data };

/*Gi hm ghi 2 bytes vo eeprom*/


return i2c_write_2b(e, buf);

/*Trong trng hp eeprom c a ch 16 bits*/ /*u tin ghi 2 bytes (16 bits) a ch vo eeprom cui cng ghi 1 bytes d liu*/
} else if(e->type == EEPROM_TYPE_16BIT_ADDR) {

/*Khai bo mng cha 3 bytes thng tin*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

171

N TT NGHIP
__u8 buf[3] = { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };

/*Gi hm ghi 3 bytes vo eeprom*/


return i2c_write_3b(e, buf); }

/*Cc trng hp khc khng thuc loi eeprom c h tr*/


fprintf(stderr, "ERR: unknown eeprom type\n"); return -1; }

3. Bin dch v thc thi chng trnh: Bin dch chng trnh bng cu lnh sau:
arm-none-linux-gnueabi-gcc eeprom.c o eeprom

Chp chng trnh bin dch vo kit v tin hnh kim tra cc chc nng m chng trnh h tr. III. Kt lun: n y chng ta hon thnh vic ng dng nhng giao din hm trong driver I2C do linux h tr iu khin thnh cng mt thit b Slave l eeprom 24c08. Bng cch p dng k thut tng t trong chng trnh, chng ta c th t mnh xy dng cc chng trnh khc iu khin tt c nhng thit b hot ng theo chun I2C. Do thi gian c hn nn chng ti ch a ra mt chng trnh v d v I2C. Trong bi tip theo chng ta s nghin cu mt driver khc l driver truyn ni tip theo chun UART.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

172

N TT NGHIP BI 8

GIAO TIP IU KHIN ADC ON CHIP


8-1 - TNG QUAN V ADC ON CHIP: I. M t chung: a. c tnh tng qut: ADC tch hp trong vi iu khin AT91SAM9260 c nhng c tnh ni bt sau: 2 knh chuyn i tng t s; phn gii c th la chn 8 bits hoc 10 bits; Tc chuyn i ch 10 bits l 312K sample/sec; Chuyn i theo phng php xp x lin tip; C th cho php khng cho php i vi tng knh chuyn i; Ngun xung kch c th la chn: Hardware-Software trigger; Externel trigger pin; Timer/Counter 0 to 2 output; b. Cc chn c s dng trong module ADC: K hiu VDDANA ADVREF AD0-AD1 ADTRG II. c tnh hot ng: ADC s dng xung ADC thc hin qu trnh chuyn i ca mnh. Tc xung chuyn i c th c thay i ty theo mc ch bng cc bits la chn tn s PRESCAL trong thanh ghi Mode Register (ADC_MR). Tc chuyn i c th nm trong khong t MCK/2 khi PRESCAL=0 n MCK/128 khi PRESCAL=63. Gi tr in p chuyn i nm trong khong t 0V n gi tr din p trn chn ADVREF v s dng phng php chuyn i ADC xp x lin tip.
________________________________________________________________________________

M t Ngun cung cp cho module analog; in p tham chiu; Knh ng vo tng t 0 v 1; Ngun xung trigger bn ngoi;

CHNG III: LP TRNH GIAO TIP NGOI VI

173

N TT NGHIP phn gii ca ADC c th la chn gia hai gi tr l 8 bits v 10 bits. Ch chuyn i ADC 8 bits c ci t bng cch set bit LOWRES trong thanh ghi ADC Mode (ADC_MR). Gi tr chuyn i ADC c th c c trong 8 bits thp ca thanh ghi Channel Data Register x (ADC_CDRx). Ch chuyn i ADC 10 bits c ci dt bng cch clear bit LOWRES trong thanh ghi ADC_MR. Lc ny gi tr chuyn i ADC c c trong 2 bytes thp v cao ca thanh ghi ADC_CDRx. (Trong user interface ca module). Qu trnh chuyn di ADC c thc hin theo cc bc sau: Khi to chn ng vo tng t theo ch ko xung mc 0; Chn mode hot ng cho ADC; Reset li ADC bng cch set bit SWRST trong thanh ghi ADC_CR; Cho php hay khng cho php cc knh chuyn i ADC hot ng; To mt xung trigger cho bit START trong thanh ghi ADC_CR; Ch cho n khi xut hin mc cao ca bit DRDY trong thanh ghi ADC_SR; c gi tr chuyn i trong cc thanh ghi tng ng vi tng knh chuyn i; Trong 3 bc cui cng c thc hin lin tc cp nht d liu chuyn i. III. Mt s cng thc quan trng: a. Cng thc tnh tc xung ADC: ADCClock = MCK/((PRESCAL+1)*2); b. Cng thc tnh thi gian khi ng: Start Up Time = (STARTUP + 1)*8/ADCClock; c. Cng thc tnh thi gian ly mu v gi: Sample & Hold Time = (SHTIM + 1) / ADCClock;

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

174

N TT NGHIP 8-2 - IU KHIN NHIT DNG ADC ON CHIP: I. Phc tho d n: Vi nhng kin thc v ADC On Chip trong bi trc chng ta s kt hp vi nhng lnh truy xut thanh ghi trong linux thit k mt ng dng n gin o nhit d dng LM35 hin th trn LED 7 on. a. Yu cu d n: Yu cu ca d n ny nh sau: - Ngi s dng nhp vo hai thng s nhit , nhit gii hn trn v nhit gii hn di; - nh thi mi 1s cp nht nhit hin ti mt ln; - iu khin mt LED sng tt theo quy lut: + LED sng khi nhit hin ti ln hn hoc bng nhit gii hn trn; + LED tt khi nhit hin ti nh hn hoc bng nhit gii hn di; b. Phn cng nhim v: Chng trnh driver: Chng trnh s dng 2 driver tng ng vi hai module khc nhau: Driver iu khin c gi tri chuyn i ADC trong CHIP v mt driver iu khin qut LED 7 on. Nhim v c th ca tng driver nh sau: Driver ADC: C tn at91adc_dev.ko - Khi to ADC trong CHIP; - S dng giao din hm read() truyn nhit chuyn c chuyn i sang user. Khi gi hm read() Driver s thc hin nhng cng vic sau: o Kch hot b chuyn i ADC hot ng; o Ch cho n khi ADC chuyn i xong; o c gi tr chuyn i; o Truyn sang user gi tr c c; - S dung giao din ioctl() SET v CLEAR mt chn gpio iu khin ng c. Giao din hm ioctl() c hai s nh danh lnh: ADC_SET_MOTOR v ADC_CLEAR_MOTOR tng ng vi set v clear chn GPIO. Driver LED 7 on: C tn l led_seg_dev.ko Thc hin qut 8 led 7 on hin th nhng gi tr nhit : Nhit gii hn trn, nhit gii hn di v nhit hin ti; - S dng giao din hm write() nhn cc thng tin t nhit t user hin th ra led; - S dng phng php ngt timer mm cp nht qut LED hin th; Phng php iu khin ny cng tng t nh trong bi thc hnh led 7 on. Nhit hin th trn LEDs theo dng sau:
<AA> < BB> <CC> ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

175

N TT NGHIP Trong : <AA> l gi tr nhit gii hn di; (Gii hn t 00 n 99); <BB> l gi tr nhit hin ti, kh nng hin th t 00 n 99; <CC> l gi tr nhit gii hn trn; (Gii hn hin th t 00 n 99); Chng trnh application: mang tn at91adc_app.c Xy dng chng trnh application theo hng c tham s nhp t ngi dng. chy chng trnh, chng ta nhp cu lnh thc thi theo c php sau:
./at91adc_app <AA> <CC>

Chng trnh application thc hin nhng tc v: - Khi ng 2 driver: at91adc_dev v led_seg_dev; - nh thi gian 1s cp nht v so snh nhit hin ti vi cc nhit gii hn trn di iu khin ng c cho ph hp. II. Thc hin: 1. Kt ni phn cng: Cc bn thc hin kt ni phn cng theo s sau:
3V3

U1 1 PC0(AD0) C1 10uF LM35_TEMPERATE 2 3 VDD VOUT GND

2. Chng trnh driver: Driver ADC: C tn at91adc_dev.ko /*Khai bo cc th vin cn dng cho cc hm trong chng trnh*/
#include #include #include #include #include #include #include #include #include #include #include #include #include #include <linux/module.h> <linux/errno.h> <linux/init.h> <asm/uaccess.h> <mach/gpio.h> <asm/gpio.h> <linux/genhd.h> <linux/miscdevice.h> <asm/atomic.h> <linux/jiffies.h> <linux/sched.h> <linux/fs.h> <linux/clk.h> <mach/at91_adc.h>

#define DRVNAME "at91adcDriver" ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

176

N TT NGHIP
#define DEVNAME "at91adcDevice" 'B' _IO(AT91ADC_DEV_MAGIC, 10) _IO(AT91ADC_DEV_MAGIC, 11)

/*nh ngha s nh danh lnh cho giao din hm ioctl ca driver ADC*/
#define AT91ADC_DEV_MAGIC

/*S nh danh lnh bt motor*/


#define AT91ADC_SET_MOTOR

/*S nh danh lnh tt motor*/


#define AT91ADC_CLEAR_MOTOR #define GPIO_MOTOR

/*nh ngha chn gpio cho chn iu khin motor*/


AT91_PIN_PC15 gpio_set_value(GPIO_MOTOR,1) gpio_set_value(GPIO_MOTOR,0)

/*nh ngha dng rt gn cho lnh set clear gpio*/


#define at91adc_set_motor() #define at91adc_clear_motor()

/*Khai bo bin con tr cha a ch nn ca cc thanh ghi thao tc vi ADC on chip*/


void __iomem *at91adc_base;

/*Khai bo bin con tr cu trc clock cp xung cho ADC hot ng*/
struct clk *at91adc_clk; static atomic_t at91adc_open_cnt = ATOMIC_INIT(1);

/*Hm h tr c d liu t ADC */


unsigned int at91adc_read_current_value(void) {

/*Khai bo mng cha 100 gi tr c c t ADC*/


int current_value[100];

/*Khai bo bin lu gi tr trung bnh ca cc gi tr trong mng current_value[100]*/


int average=0;

/*Bin iu khin h tr cho vng lp*/


int i;

/*Vng lp h tr cho vic c cc d liu ca ADC*/


for (i = 0; i<100; i++) {

/*To xung trigger cho bit START trong thanh ghi ADC_CR*/
iowrite32(AT91_ADC_START, (at91adc_base + AT91_ADC_CR));

/*Ch cho n khi qu trnh chuyn i hon thnh, ngha l khi bit ADC_DRDY c set ln mc cao*/
while((ioread32(at91adc_base+AT91_ADC_SR)&AT91_ADC_DRDY)==0) schedule();

/*Chp gi tr chuyn i cha trong thanh ghi ADC_CHR(0) vo mt phn t trong mng b nh m trong kernel*/
current_value[i]=ioread32(at91adc_base + AT91_ADC_CHR(0)); }

/*Tnh tng cc gi tr cha trong mng*/


for (i=0; i<100; i++) { average += current_value[i]; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

177

N TT NGHIP
}

/*Tr v gi tr trung bnh ca cc phn t trong mng*/


return average/100; }

/*Khai bo v nh ngha giao din hm read cung cp thng tin gi tr chuyn i cho user application*/
static ssize_t at91adc_read (struct file *filp, __iomem buf[], size_t bufsize, loff_t *f_pos) { unsigned char

/*Khai bo b m cho hm read*/


unsigned int buf_read[1];

/*Gi hm h tr c d liu c lp trnh trn*/


buf_read [0]=at91adc_read_current_value();

/*Gi hm truyn d liu sang user application khi c yu cu c kim tra li trong qu trnh truyn*/
if (copy_to_user(buf, buf_read, bufsize) != 0) { printk ("Error whilst copying to user\n"); return -1; } return 2; }

/*Giao din hm ioctl() thc hin set v clear cc chn iu khin ng c theo yu cu t user application*/
static int at91adc_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long *arg) { int retval; switch (cmd) {

/*Trong trng hp lnh set chn iu khin ng c ln mc 1*/


case AT91ADC_SET_MOTOR: at91adc_set_motor(); break;

/*Trong trng hp lnh set chn iu khin ng c xung mc 0*/


case AT91ADC_CLEAR_MOTOR: at91adc_clear_motor(); break;

/*Trong trng hp khng c lnh h tr tr v m li*/


default: retval = -EINVAL; break; } return retval; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

178

N TT NGHIP
}

/*Khai bo v nh ngha giao din hm open*/


static int at91adc_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev);

/*FIXME: We should really allow multiple applications to open the device *at the same time, as long as the apps access different IO pins. *The generic gpio-registration functions can be used for that. *Two new IOCTLs have to be introduced for that. Need to check userspace *compatibility first. --mb */
if (!atomic_dec_and_test(&at91adc_open_cnt)) { atomic_dec(&at91adc_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; }

/*Khai bo v nh ngha giao din hm close*/


static int at91adc_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&at91adc_open_cnt); return 0; } struct file_operations at91adc_fops = { .read = at91adc_read, .ioctl = at91adc_ioctl, .open = at91adc_open, .release = at91adc_close, }; static struct miscdevice at91adc_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "at91adc_dev", .fops = &at91adc_fops, }; static int __init at91adc_mod_init(void) { int ret;

/*Khi to cu hnh lm vic cho ADC on chip*/


________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

179

N TT NGHIP /*Yu cu to xung cho ADC hot ng */ at91adc_clk = clk_get(NULL, /*Device pointer - not required.*/ "adc_clk"); /*Clock name*/ /*Cho php ngun xung hot ng*/
clk_enable(at91adc_clk);

/*nh v con tr nn adc vo a ch nn vt l ca cc thanh ghi iu khin adc*/


at91adc_base=ioremap_nocache(AT91SAM9260_BASE_ADC,/*Physical address*/ 64);/*Number of bytes to be mapped*/

/*Kim tra li trong qu trnh nh v*/


if (at91adc_base == NULL) { printk(KERN_INFO "at91adc: failed\n"); ret = -EACCES; goto exit_3; } at91_set_A_periph(AT91_PIN_PC0, 0); ADC memory mapping

/*Khi to chn gpio ng vo analog c in tr ko xung*/ /*Reset ADC bng cch set bit ADC_SWRST*/
iowrite32(AT91_ADC_SWRST, (at91adc_base + AT91_ADC_CR));

/*Cho php knh 0 ca b chuyn i ADC hot ng*/


iowrite32(AT91_ADC_CH(0), (at91adc_base + AT91_ADC_CHER));

/*Ci dt cc ch hot ng cho ADC*/ /*Tn s cc i = 5MHz = MCK / ((PRESCAL+1) * 2) /*PRESCAL = ((MCK / 5MHz) / 2) -1 = ((100MHz / 5MHz)/2)-1) = 9 /*Thi gian start up cc i = 15uS = (STARTUP+1)*8/ADC_CLOCK /*STARTUP = ((15uS*ADC_CLOK)/8)-1 = ((15uS*5MHz)/8)-1 = 9 /*Minimum hold time = 1.2uS = (SHTIM+1)/ADC_CLOCK /*SHTIM = (1.2uS*ADC_CLOCK)-1 = (1.2uS*5MHz)-1 = 5, Use 9 to /*ensure 2uS hold time. /*Enable sleep mode and hardware trigger from TIOA output from TC0.*/
iowrite32((AT91_ADC_SHTIM_(9)|AT91_ADC_STARTUP_(9)| AT91_ADC_PRESCAL_(9)|AT91_ADC_SLEEP|AT91_ADC_TRGEN), (at91adc_base + AT91_ADC_MR));

/*Khi to chn gpio theo ch ng ra*/


gpio_request(GPIO_MOTOR, NULL); at91_set_GPIO_periph (GPIO_MOTOR, 1); gpio_direction_output(GPIO_MOTOR, 0); printk(KERN_INFO "at91adc: Loaded module\n"); printk(KERN_ALERT "Welcome to our at91adc world\n"); return misc_register(&at91adc_dev); exit_3: ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

180

N TT NGHIP
clk_disable(at91adc_clk); return ret; }

/*Khai bo v nh ngha hm exit thc hin khi tho driver ra khi h thng*/
static void __exit at91adc_mod_exit(void) {

/*V hiu ha hot ng ca xung clock*/


clk_disable(at91adc_clk);

/*Gii phng con tr thanh ghi nn iu khin ADC*/


iounmap(at91adc_base);

/*In ra thng bo cho ngi dng*/


printk(KERN_ALERT "Goodbye for all best\n"); printk(KERN_INFO "at91adc: Unloaded module\n"); misc_deregister(&at91adc_dev); } module_init (at91adc_mod_init); module_exit (at91adc_mod_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Coolwarmboy / OpenWrt"); MODULE_DESCRIPTION("Character device for driver");

for

generic

at91adc

Driver LED 7 on: C tn l led_seg_dev.ko /*Driver iu khin led 7 on dc chng ti gii thch k trong bi thc hnh iu khin LED 7 on, y ch thay i cc chn gpio v cu trc chng trnh cho ph hp vi d n*/
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include <linux/module.h> <linux/errno.h> <linux/init.h> <mach/at91_tc.h> <asm/gpio.h> <asm/atomic.h> <linux/genhd.h> <linux/miscdevice.h> <asm/uaccess.h> <linux/interrupt.h> <linux/clk.h> <linux/irq.h> <linux/time.h> <linux/jiffies.h> <linux/sched.h> <linux/delay.h> "led_seg_dev" "led_seg"

#define DRVNAME #define DEVNAME

/*-------------Port Control-----------*/ ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

181

N TT NGHIP
#define #define #define #define #define #define #define #define #define #define #define #define #define #define #define P00 P01 P02 P03 P04 P05 P06 P07 A B C D E F G AT91_PIN_PB0 AT91_PIN_PB2 AT91_PIN_PC5 AT91_PIN_PC6 AT91_PIN_PC7 AT91_PIN_PC4 AT91_PIN_PB3 AT91_PIN_PB1 AT91_PIN_PB7 AT91_PIN_PB9 AT91_PIN_PB11 AT91_PIN_PA24 AT91_PIN_PB16 AT91_PIN_PA23 AT91_PIN_PB10

/*Basic commands*/
#define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define #define SET_P00() SET_P01() SET_P02() SET_P03() SET_P04() SET_P05() SET_P06() SET_P07() CLEAR_P00() CLEAR_P01() CLEAR_P02() CLEAR_P03() CLEAR_P04() CLEAR_P05() CLEAR_P06() CLEAR_P07() SET_A() SET_B() SET_C() SET_D() SET_E() SET_F() SET_G() CLEAR_A() CLEAR_B() CLEAR_C() CLEAR_D() gpio_set_value(P00,1) gpio_set_value(P01,1) gpio_set_value(P02,1) gpio_set_value(P03,1) gpio_set_value(P04,1) gpio_set_value(P05,1) gpio_set_value(P06,1) gpio_set_value(P07,1) gpio_set_value(P00,0) gpio_set_value(P01,0) gpio_set_value(P02,0) gpio_set_value(P03,0) gpio_set_value(P04,0) gpio_set_value(P05,0) gpio_set_value(P06,0) gpio_set_value(P07,0) gpio_set_value(A,1) gpio_set_value(B,1) gpio_set_value(C,1) gpio_set_value(D,1) gpio_set_value(E,1) gpio_set_value(F,1) gpio_set_value(G,1) gpio_set_value(A,0) gpio_set_value(B,0) gpio_set_value(C,0) gpio_set_value(D,0)

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

182

N TT NGHIP
#define CLEAR_E() #define CLEAR_F() #define CLEAR_G() #define CYCLE 1 'B' _IO(LED_SEG_DEV_MAGIC, 12) gpio_set_value(E,0) gpio_set_value(F,0) gpio_set_value(G,0)

#define LED_SEG_DEV_MAGIC #define LED_SEG_UPDATE

/*Counter is 1, if the device is not opened and zero (or less) if opened.*/
static atomic_t led_seg_open_cnt = ATOMIC_INIT(1); unsigned char DataDisplay[8]={0,1,2,3,4,5,6,7}; unsigned char SevSegCode[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82,0xF8,0x80,0x90,0x3F,0x77,0xFF}; int i;

/*Khai bo cu trc timer mm*/


struct timer_list my_timer; void led_seg_write_data_active_led(char data) { (data&(1<<0))? SET_P00():CLEAR_P00(); (data&(1<<1))? SET_P01():CLEAR_P01(); (data&(1<<2))? SET_P02():CLEAR_P02(); (data&(1<<3))? SET_P03():CLEAR_P03(); (data&(1<<4))? SET_P04():CLEAR_P04(); (data&(1<<5))? SET_P05():CLEAR_P05(); (data&(1<<6))? SET_P06():CLEAR_P06(); (data&(1<<7))? SET_P07():CLEAR_P07(); } void led_seg_write_data_led(char data) { (data&(1<<0))? SET_A():CLEAR_A(); (data&(1<<1))? SET_B():CLEAR_B(); (data&(1<<2))? SET_C():CLEAR_C(); (data&(1<<3))? SET_D():CLEAR_D(); (data&(1<<4))? SET_E():CLEAR_E(); (data&(1<<5))? SET_F():CLEAR_F(); (data&(1<<6))? SET_G():CLEAR_G(); } void active_led_choice(char number) { led_seg_write_data_active_led(~(1<<(number))); } void data_led_stransmitt (char data) { led_seg_write_data_led (SevSegCode[data]); } void sweep_led_time_display(int hh, int mm, int ss) { DataDisplay[0] = ss%10; ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

183

N TT NGHIP
DataDisplay[1] DataDisplay[2] DataDisplay[3] DataDisplay[4] DataDisplay[5] DataDisplay[6] DataDisplay[7] } = = = = = = = ss/10; 10; mm%10; mm/10; 10; hh%10; hh/10;

/*Hm thc thi qut LED khi c ngt xy ra*/


void my_timer_function (unsigned long data) {

/*Xut m 7 on th ca d liu th i ra LED 7 on th i*/


data_led_stransmitt(DataDisplay[i]);

/*Cho php LED 7 on th i tch cc*/


active_led_choice(i);

/*Tng bin i ln 1 n v*/


i++;

/*Gii hn s LED hin th l 8*/


if (i==8) i = 0;

/*Ci t li thi gian ngt cho timer l CYCLE=1(ms)*/


mod_timer (&my_timer, jiffies + CYCLE); }

/*buf[0] nhit gii hn trn; buf[1] nhit gii hn di*/


static ssize_t led_seg_write (struct file *filp, unsigned char __iomem buf[], size_t bufsize, loff_t *f_pos) { unsigned char write_buf[2]; int write_size = 0; int i; if (copy_from_user (write_buf, buf, bufsize) != 0) { return -EFAULT; } else { write_size = bufsize; }

/*Cp nht hin th LED*/


DataDisplay[0] = write_buf[0] % 10; DataDisplay[1] = write_buf[0] / 10; DataDisplay[2] = 12; /*K t khong trng trong LED 7 on*/ DataDisplay[5] = 12; /*K t khong trng trong LED 7 on*/ DataDisplay[6] = write_buf[1] % 10; DataDisplay[7] = write_buf[1] / 10; return write_size; }

/*Khai bo v nh ngha giao din hm ioctl() phc v cho hm cp nht d liu hin ti hin th trn led*/
static int ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

184

N TT NGHIP
led_seg_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned int arg) { int retval; switch (cmd) {

/*Trong trng hp lnh update d liu hin th trn led 7 on*/


case LED_SEG_UPDATE:

/*Gii m s nguyn t 00 n 99 sang 2 s BCD chc v n v, cp nht thng tin cho mng d liu hin th*/
DataDisplay[3] = arg % 10; DataDisplay[4] = arg / 10; break; default: retval = -EINVAL; break; } return retval; } static int led_seg_open(struct inode *inode, struct file *file) { int result = 0; unsigned int dev_minor = MINOR(inode->i_rdev); if (!atomic_dec_and_test(&led_seg_open_cnt)) { atomic_inc(&led_seg_open_cnt); printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor); result = -EBUSY; goto out; } out: return result; } static int led_seg_close(struct inode * inode, struct file * file) { smp_mb__before_atomic_inc(); atomic_inc(&led_seg_open_cnt); return 0; } struct file_operations led_seg_fops = { .write = led_seg_write, .ioctl = led_seg_ioctl, ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

185

N TT NGHIP
.open = led_seg_open, .release = led_seg_close, }; static struct miscdevice led_seg_dev = { .minor = MISC_DYNAMIC_MINOR, .name = "led_seg_dev", .fops = &led_seg_fops, }; static int __init led_seg_mod_init(void) { int ret=0; gpio_request (P00, gpio_request (P01, gpio_request (P02, gpio_request (P03, gpio_request (P04, gpio_request (P05, gpio_request (P06, gpio_request (P07,

NULL); NULL); NULL); NULL); NULL); NULL); NULL); NULL); (P00, (P01, (P02, (P03, (P04, (P05, (P06, (P07, 1); 1); 1); 1); 1); 1); 1); 1); 0); 0); 0); 0); 0); 0); 0); 0);

at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph

gpio_direction_output(P00, gpio_direction_output(P01, gpio_direction_output(P02, gpio_direction_output(P03, gpio_direction_output(P04, gpio_direction_output(P05, gpio_direction_output(P06, gpio_direction_output(P07, gpio_request gpio_request gpio_request gpio_request gpio_request gpio_request gpio_request (A, (B, (C, (D, (E, (F, (G, NULL); NULL); NULL); NULL); NULL); NULL); NULL);

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

186

N TT NGHIP
at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph at91_set_GPIO_periph (A, (B, (C, (D, (E, (F, (G, 1); 1); 1); 1); 1); 1); 1); 0); 0); 0); 0); 0); 0); 0);

gpio_direction_output(A, gpio_direction_output(B, gpio_direction_output(C, gpio_direction_output(D, gpio_direction_output(E, gpio_direction_output(F, gpio_direction_output(G,

/*Khi to timer mm ngt vi chu k thi gian l 1ms*/ /*Khi to timer t cu trc timer nh ngha*/
init_timer (&my_timer);

/*Ci dt thi gian sinh ra ngt l CYCLE=1 (ms)*/


my_timer.expires = jiffies my_timer.data = 0; + CYCLE;

/*Cung cp d liu cho hm phc v ngt*/ /*Gn con tr hm phc v ngt cho timer khi c ngt xy ra*/
my_timer.function = my_timer_function;

/*Thc hin ci t timer vo h thng*/


add_timer (&my_timer); misc_register(&led_seg_dev); printk(KERN_INFO "led_seg: Loaded module\n"); return ret; } static void __exit led_seg_mod_exit(void) {

/*Xa ng b timer ra khi h thng khng lm nh hng n cc ln khi to timer tip theo*/
del_timer_sync(&my_timer); misc_deregister(&led_seg_dev); printk(KERN_INFO "led_seg: Unloaded module\n"); } module_init (led_seg_mod_init); module_exit (led_seg_mod_exit); MODULE_LICENSE("GPL"); ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

187

N TT NGHIP
MODULE_AUTHOR("coolwarmboy"); MODULE_DESCRIPTION("Character device for for generic gpio api");

3. Chng trnh application: /*Khai bo th vin dng cho cc hm trong chng trnh*/
#include #include #include #include #include #include #include <stdint.h> <unistd.h> <stdio.h> <stdlib.h> <getopt.h> <fcntl.h> <linux/ioctl.h>

#include <sys/types.h> #include <sys/stat.h>

/*Khai bo cc s nh danh lnh cn dng cho driver ADC v LED 7 on*/ /*S nh danh lnh dng cho giao din hm ioctl() ca driver at91adc_dev*/
#define AT91ADC_DEV_MAGIC 'B' #define AT91ADC_SET_MOTOR #define AT91ADC_CLEAR_MOTOR #define LED_SEG_DEV_MAGIC #define LED_SEG_UPDATE 12) 'B' _IO(LED_SEG_DEV_MAGIC, _IO(AT91ADC_DEV_MAGIC, 10) _IO(AT91ADC_DEV_MAGIC, 11)

/*S nh danh lnh dng cho giao din hm ioctl() ca driver led_seg_dev*/

/*Khai bo cc bin lu cc nhit gii hn nhp t ngi dng*/


unsigned int HighestTemp, LowestTemp;

/*Cc bin lu s m t tp tin thit b khi c m*/


int fd_at91adc_dev, fd_led_seg_dev;

/*Chng trnh con cp nht nhit hin ti t driver adc v truyn sang driver LED 7 on*/
void check_update_cur_temp (void) {

/*B nh m lu gi tr tr v t driver adc*/


unsigned char current_value[2];

/*Bin lu nhit hin ti sau khi chuyn i*/


int cur_temp;

/*Bin lu gi tr tr v t driver di dng int*/


int cur_value;

/*Gi giao din hm read c thng tin chuyn i t driver adc*/


read(fd_at91adc_dev, current_value, 2);

/*Chuyn byte thp v byte cao ca b m thnh s int*/


cur_value = current_value[1]*256 + current_value[0];

/*Chuyn i thng tin chuyn i t driver adc sang nhit S 0.31867 c tnh bng cng thc sau: Vref/(2^10-1) trong Vref l gi tr o c t chn VREFP; 10 l phn gii 10 bits ca ADC on chip*/
________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

188

N TT NGHIP
cur_temp = cur_value * 0.31867;

/*Gi giao din hm ioctl() ca driver LED 7 on cp nht hin th nhit hin ti ln LEDs*/
ioctl(fd_led_seg_dev, LED_SEG_UPDATE, cur_temp);

/*So snh nhit hin ti vi cc nhit gii hn tt|m ng c cho thch hp*/
if (cur_temp >= HighestTemp) {

/*Trong trng hp nhit hin ti vt qu nhit gii hn trn*/


/*In ra thng bo cho ngi dng*/ printf("Motor is turned on\n"); /*Gi hm ioctl() ca driver adc set pin iu khin motor*/ ioctl(fd_at91adc_dev, AT91ADC_SET_MOTOR); } else if (cur_temp <= LowestTemp) {

/*Trong trng hp nhit hin ti xung thp di nhit gii hn di*/


printf("Motor is turned off\n");

/*Gi giao din hm ioctl() clear pin iu khin motor*/


ioctl(fd_at91adc_dev, AT91ADC_CLEAR_MOTOR); } }

/*Chng trnh chnh khai bo di dng c tham s nhp vo t ngi dng */


int main(int argc, char **argv) {

/*B m lu gi tr cn truyn sang driver LED 7 on hin th hai nhit


gii hn trn v di */

/*buf[0] highest temp; buf[1] lowest temp*/


unsigned char buf_write[2] = {34, 35};

/*M hai tp tin thit b trc khi thao tc*/


fd_at91adc_dev = open("/dev/at91adc_dev",O_RDWR); fd_led_seg_dev = open("/dev/led_seg_dev",O_RDWR);

/*Cp nht cc thng tin v nhit gii hn*/


HighestTemp = atoi(argv[2]); value*/ LowestTemp = atoi(argv[1]); on*/ buf_write[0] = HighestTemp; buf_write[1] = LowestTemp; /*Highest Temperature /*Lowest Temperature value*/

/*Lu cc gi tr gii hn vo b m ghi sang driver hin th LED 7

/*Gi giao din hm write() ghi d liu trong b m sang driver LED 7 on*/
write(fd_led_seg_dev,buf_write,2);

/*Dng vng lp lin tc cp nht iu khin ng c, hin th nhit


ra LED vi chu k l 1s*/ ________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

189

N TT NGHIP
while (1) { check_update_cur_temp(); sleep(1); } exit (0); }

Kt lun v bi tp: a. Kt lun: Bn cnh dng IC 0809 lm thit b chuyn i tng t-s chng ta cng c th dng module ADC tch hp sn trong CHIP vi iu khin. Nh vy s tic kim chi ph v rt gn c s chn IO iu khin dng vo cng vic khc. Bn cnh dng ADC on chip chng ta c th thc hin c nhiu chc nng tin li hn, chnh xc c th linh ng thay i ty theo yu cu chng trnh ng dng. Trong bi ny chng ta sa li driver hin th LED 7 on ng dng timer mm qut LED ng thi ng dng phng php lp trnh character device driver vo vit driver cho ADC on chip. Kt hp 2 driver iu khin va hin th thng tin trn LED 7 on. Ngi hc c th thay i d n hin th trn nhng thit b khc hay ng dng driver vo vic ly mu tn hiu, ... lc ng dng s phc tp hn. Do thi gian thc hin cun gio trnh ny c hn nn chng ti khng di su vo nghin cu nhng ng dng ny. b. Bi tp: 1. Lm li yu cu ca d n trn, nhng hin th cc thng tin cc nhit ln LCD. (p dng LCD driver vit trong bi thc hnh LCD); 2. Ti u ha d n trn theo yu cu sau: - Thng tin v cc nhit gii hn c lu trong EEPROM 24C08; - Khi chng trnh c m, n s cp nht hai gi tr nhit gii hn t EEPROM; - Thng tin v cc gi tr nhit nu thay i s c cp nht vo EEPROM;

III.

________________________________________________________________________________

CHNG III: LP TRNH GIAO TIP NGOI VI

190

You might also like