You are on page 1of 200

2013

Bi ging H Thng Nhng

u Trng Hin
Trng Ngc Sn
SPKT

Chng 1
GII THIU H THNG NHNG
1 .H thng nhng ( Embedded System):
Hin nay h thng nhng v ang tng bc pht trin Vit nam, n thay cho cc h
thng vi x l trc y. H thng nhng c ng dng rng ri trong ngnh in t, my tnh
v vin thng nh cc h thng in thoi, cc my o, cc h thng iu khin t ng trong
cng nghip, thng mi v ngn hng. Tuy nhin chng ta vn cha c mt nh ngha c th
v h thng nhng. Thng qua qu trnh vn hnh, xy dng v pht trin h thng nhng chng
ta c th hiu h thng nhng nh sau:
H thng nhng l mt ng dng bao gm t nht mt thit b lp trnh c nh vi x l,
vi iu khin hay cc vi mch x l s. N l mt h thng da trn vi x l thc hin mt
chc nng hay mt dy chc nng c th no .
H thng nhng l mt ng dng c tch hp c phn cng v phn mm nhm phc v
cc bi ton chuyn dng trong lnh vc cng nghip, y t, qun s.
Mt my tnh PC l mt thit b c nhiu chc nng v ngi s dng c th thay i cc
chc nng thng qua vic thm, xa phn mm ng dng, trong khi h thng nhng c
thit k phc v mt s chc nng c th, xc nh. Chnh v th h thng nhng c cc nh
pht trin ti u ha n nhm gim thiu kch thc v chi ph sn xut.
Cc thit b cm tay PDA cng c c im ging h thng nhng nhng chng khng
phi l h thng nhng v chng c nhiu chc nng.
thay i chc nng ca h thng nhng thng thng ngi ta da v cc cng c pht
trin v cng vic ny do cc chuyn gia pht trin h thng nhng thc thin. Qu trnh xy
dng li chc nng h thng nhng ging nh qu trnh thay i chc nng h iu hnh, thng
thng ngi ta thay i, sa cha, thm, xa cc trnh iu khin, hot ng ca h thng sau
tin hnh bin dch li cho h thng nhng.
Mt h thng nhng c kt ni vi mt h thng my ch pht trin h thng, qu
trnh pht trin h thng hay lp trnh cho h thng nhng c thc hin trn mt my tnh c
cc cng c h tr. Cc kt qu ca cc qu trnh bin dch nh: cc tp tin nh ca h iu hnh,
cc tp tin thc thi c np xung h thng nhng thng qua cc kt ni nh: serial, usb,
ethernet..

Hnh 1-1 Kt ni trong qu trnh pht trin h thng nhng


Mt h thng nhng thng thng c cc thnh phn sau:
- Vi x l: thng thng l cc vi x l 32 bit, cc vi x l ng vai tr b x l trung tm
trong h thng nhng, ngy nay vi s pht trin ca ngnh cng nghip in t, nhiu hng sn
xut vi x l cho ra i cc chip vi x l 32 bit vi nhiu tnh nng tch hp phc v trong h
thng nhng nh Renesas vi cc chip h SH, AMCC vi PowerPC, Cirrus Logic vi ARM7,
ARM9, Atmel
Trang 1

- B nh: bao gm b nh RAM, EEPROM hay Flash ROM.


- Cc ngoi vi bao gm cc giao tip IO nh USB, Ethernet, PCI Ty vo mc ch, yu
cu ca mi h thng khc nhau m thit k cc ngoi vi khc nhau, trong c mt s ngoi vi
chung nh ethernet, usb, serial. Cc ngoi vi ny va l cc giao tip ca h thng trong cc ng
dng va lm nhim v truyn d liu trong qu trnh np phn mm cho h thng hay g ri h
thng.
Phn mm trong h thng nhng: Phn mm l chng trnh iu khin hot ng ca h
thng nhng, trong mt s h thng nhng phn mm cn c gi l h iu hnh nhng. N
ging nh mt h iu hnh chy trn my tnh nhng chng c cc nh pht trin ti u sao
cho c th vn hnh hiu qu trn h thng c b nh v tc x l gii hn.
Mt s h iu hnh chy trn h thng nhng l Linux, QNX, Windows CE
Trong cc h thng nhng s dng h iu hnh Linux, b phn mm gm cc phn nh
sau:
Bootloader, uboot, redboot: phn mm khi ng h thng
Kernel: Nhn ca h iu hnh
File system: H thng tp tin
Mt s h thng nhng quanh ta nh cc thit b nghe nhn, cc thit b trong khoa hc k
thut, cc thit b phc v trong i sng tinh thn

Hnh 1-2 Mt s h thng nhng


2 .H thng thi gian thc (Real-time operating system_ RTOS):
Trong cc bi ton iu khin chng ta hay bt gp cc thut ng Thi gian thc.
Thi gian thc khng phi l thi gian phn nh mt cch trung thc chnh xc thi gian
hay yu cu thi gian h thng phi trng vi thi gian thc t.
H thng thi gian thc c hiu l cc hot ng ca h thng phi tha mn v tnh tin
nh. Tnh tin nh l hnh vi ca h thng phi c thc hin ng trong mt khung thi gian
cho trc hon ton xc nh, khung thi gian ny c quyt nh bi c im v yu cu ca
h thng.
Thc t cho thy rng hu ht cc h thng nhng l cc h thng thi gian thc v ngc
li hu ht cc h thng thi gian thc l cc h thng nhng.
3 .c im ca h thng nhng:
H thng nhng c mt s c im sau:
- tin cy cao.
Trang 2

- C kh nng bo tr v nng cp.


- Hiu qu v thi gian thc hin.
- Kch thc, khi lng nh.
4 .Cc khi nim s dng trong h thng nhng:
4.1 Qu trnh khi ng h thng:
- Image thc thi chng trnh c bin dch cho h thng nhng c th c truyn t
cng c pht trin h thng nhng (Host) vo h thng nhng (Target) qu trnh ny c gi l
Loading the Image.
- Image c th c load v h thng nhng thng qua cc cch nh sau:
Load Image vo b nh EEPROM hay Flash.
Download Image trc tip ln b nh SRAM ca h thng nhng thng qua cng ni tip
RS232 hay cng mng (ethernet) qu trnh ny i hi mt s trnh ng dng chy trn Host v
Target nh Embedded Monitor, Embedded Loader, Target debug
Download Image thng qua JTAG.

Hnh 1-3 H thng nhng c bn


- Embedded Loader: l mt chng trnh c np vo h thng nhng u tin,
Embedded Loader c hiu ging nh BIOS ca my tnh. Embedded loader c dung lng
nh nn thng thng c np vo ROM, trn cc h thng vi x l nh, Loader c np vo
mt vng ring trn vi x l.
Chng trnh Embedded Loader c nhim v kt ni vi Host trong qu trnh truyn file
nh (Image) xung h thng nhng.
c th truyn d liu gia Host v Target, giao thc truyn c xy dng sao cho cc
tin ch chy trn Host v Embedded Loader trn Target iu hot ng theo cc thng s ca
giao thc ny.
Ty theo mi nh sn xut vi x l s c cc Embedded Loader ring, v d cc vi x l
Atmel th c Bootstrap v uboot, PowerPC th s dng uboot, Cirrus Logic th s dng redboot.
Mt s chip vi x l khc th s dng bootloader.
- Embedded Monitor: l mt phn mm ng dng trn h thng nhng thng thng
c cung cp bi cc nh sn xut. N cho php cc nh pht trin h thng c th g ri h
thng, ging nh mt chng trnh boot, Embedded Monitor thc thi khi h thng c cp
ngun v thc hin mt s thao tc trn h thng nh sau:
Trang 3

o Khi to, thit lp cho cc thit b ngoi vi nh cng ni tip, b nh thi chip, s ln
lm ti RAM
o Khi to b nh h thng chun b cho qu trnh download Image.
o Khi to chng trnh iu khin ngt, ci t cc ngt h thng.
- Embedded Monitor h tr 1 cng c giao tip ngi dng thng qua giao tip ni tip
n cc chng trnh m phng. Thng thng th n h tr cc lnh iu khin nh sau:
o Download Image.
o c v ghi cc thanh ghi h thng.
o c v ghi b nh h thng.
o Thit lp v xa cc break point.
o Cho php thc thi tng lnh g ri h thng.
o Reset v reboot h thng.
- Qu trnh boot ca h thng:

Hnh 1-4 Qu trnh khi ng h thng


5 .H iu hnh thi gian thc (Real-time Operating System)
- H iu hnh thi gian thc l mt chng trnh lp lch cho cc hot ng ca h thng
thi hnh chnh xc theo thi gian nh trc, qun l ti nguyn h thng v cung cp mt s

Trang 4

thit lp thch hp cho qu trnh pht trin m ngun ca h thng. M ngun h thng c th
thay i c.
- Trong mt s ng dng, RTOS bao gm mt kernel (nhn). Kernel l mt li mm gim
st h thng, cung cp cc khi logic, cc gii thut lp lch, cc gii thut qun l ti nguyn.
Mi mt h thng thi gian thc u c mt kernel. Mi h thng thi gian thc l mt s tng
hp ca nhiu module trong bao gm kernel, file system, network protocol stack, v cc
module khc ty thuc vo yu cu chc nng ca h thng.

Hnh 1-5 T chc trong h thng nhng


6 .Scheduler (B lp lch)
- Scheduler c xem nh tri tim ca kernel. Mt scheduler cung cp cc gii thut cn
thit xc nh mt tc v khi no c php thc hin.
- Cc gii thut lp lch (schedule Algorimth)
o Preemtive priority-based scheduling
o Round-Robin scheduling
- Cc nh sn xut RTOS cung cp cc gii thut lp lch trn, tuy nhin trong mt s
trng hp cc nh pht trin h thng c th nh ngha thm cc gii thut lp lch.
6.1 Preemtive Priority-Based scheduling.

Trang 5

- Hu ht cc h thng nhng s dng gii thut ny nh l mt gii thut mc nh. Trong


gii thut ny mt task c thc thi bt k v tr no l task c mc u tin ln nht gia cc
task khc trong h thng.

Hnh 1-6 Gii thut lp lch Preemtive Priority-Based scheduling


- RTOS Kernel cung cp 255 mc u tin trong mc 0 l mc u tin thp nht, 255 l
mc u tin cao nht. Mt s kernel th nh ngha ngc li, 255 l mc u tin thp nht, 0 l
mc u tin cao nht.
- Vi Preemtive Priority-Based scheduling, mi task c mt mc u tin khc nhau, task
c mc u tin cao nht s thi hnh trc. Nu mt task c mc u tin cao hn mt task ang
thi hnh m task ny trng thi ready to run (yu cu c thc thi) th kernel lp tc lu task
hin hnh vo TCB (task control block) v chuyn sang thc hin task c u tin cao hn.
- Mc d mi task khi c to ra s c gn mt gi tr u tin, xong gi tr u tin c
th c thay i thng qua vic s dng cc lnh do kernel h tr.
- Kh nng thay i mc u tin cc task ng cho php cc ng dng trn h thng nhng
d dng hiu chnh cc s kin xy ra, to ra mt h thng thi gian thc.
6.2 Round -Robin scheduling:
- Round-Robin scheduling cung cp mi task mt khong thi than thc hin ca CPU.
- Round-Robin scheduling khng th p ng cc yu cu ca h thng thi gian thc bi
v trong h thng thi gian thc mt task c th thc hin nhiu mc u tin khc nhau,
thay vo preemtive priority scheduling c th tt hn nu kt hp vi Round-Robin, mt gii
thut s dng cc khong thi gian bng nhau thc hin ca CPU.

Hnh 1-7 Round-Robin v Preemtive priority-based scheduling


Trang 6

7 .Task (Tc v):


- Mt phn mm ng dng n gin c thit k t th hot ng tun t, mt lnh c
thi hnh ti mt thi im, cc lnh c thc hin lin tip nhau. M hnh ny tr nn khng
thch hp trong h thng nhng, trong h thng nhng thng thng c nhiu ng vo v nhiu
ng ra, cc phn mm ng dng cho h thng nhng phi c thit k hot ng ng thi.
- Trong cc thit k ng thi i hi cc nh pht trin phi phn tch ng dng ra thnh
nhiu n v chng trnh nh hot ng lin tip nhau. Khi thc hin phn tch xong, cc thit
k ng thi cho php h thng a task v c th hot ng da trn yu cu cht ch v thi
gian cho h thng thi gian thc.
- Hu ht cc kernel cung cp cc task v qun l cc task thch hp cho cc thit k
ng thi.
- Task l mt lung c lp ca qu trnh thc hin, cc task ginh nhau qu trnh thc
hin ca CPU. Nh cp trn cc nh pht trin chia ng dng thnh nhiu task ti u ha
cc qun l xut nhp trong mt trong cc khong thi gian xc nh.
- Mt task c th ginh thi gian thc hin ca CPU theo cc gii thut lp lch do kernel
to ra, task c xc nh da v cc thng s v cu trc d liu ring bit ca n. Mi task khi
c to c mt tn, s hiu (ID) v mc u tin khc nhau.
7.1 Cc trng thi ca task:
- D l task h thng hay task ng dng, ti mi thi im, mi task tn ti mt trong
cc trng thi sau: ready, running hay block. Khi h thng ang hot ng cc task c th chuyn
qua li gia cc trng thi.

- Ready state: Task sn sng thc thi nhng khng th v mt task khc vi mc u tin
cao hn ang thc thi.
- Block state: Task gi yu cu nhng khng c chp nhn, yu cu c thi hnh phi
ch mt s s kin khc din ra hay b tr hon trong mt khong thi gian.
- Running state: Task c mc u tin cao nht v ang c thi hnh.

Trang 7

Chng 2
GII THIU H IU HNH NHNG
1. h iu hnh linux
1.1 Gii thiu h iu hnh Linux:
Linux l h iu hnh m phng Unix, Linux c xy dng da trn phn nhn (kernel)
v cc gi phn mm m ngun m. Linux c cng b di bn quyn ca GPL (General
Public Licence).
Unix ra i gia nhng nm 1960, ban u c pht trin bi AT&T sau c ng
k thng mi v pht trin theo nhiu dng vi cc tn khc nhau. Nm 1990, xu hng pht
trin phn mm m ngun m xut hin v c thc y bi t chc GNU. Mt s Licence v
m ngun m xut hin nh BSD, GPL. Nm 1991, Linus Torvald vit thm phin bn nhn
V0.01(kernel) u tin v a ln cho cng ng ngi dng s dng v pht trin. Nm
1996, nhn V1.0 chnh thc cng b v ngy cng c s quan tm ca ngi dng. Nm 1999,
phin bn nhn V2.0 vi nhiu c tnh h tr nhiu cho cc ng dng server. Nm 2000, phin
bn V2.4 ra i h tr nhiu hn v Linux bt u bc chn vo th trng m ch yu l trong
cc ng dng mng, cc ng dng cho cc thit b cm tay.
Cc phin bn ca Linux l sn phm ng gi kernel v cc gi phn mm min ph khc.
Cc phin bn ny c cng b di licence GPL.
Ging nh Unix, Linux gm c 3 phn chnh: Kernel, Shell v cu trc tp file.
Kernel l chng trnh nhn, mt s ti liu cn gi l nhn h iu hnh Linux. Kernel
chy cc chng trnh h thng v qun l hat ng ca h thng.
Shell l mi trng cung cp cc giao din cho ngi s dng cn c m t nh mt b
bin dch, Shell l cu ni giao tip gia ngi s dng v nhn h iu hnh(kernel). Shell nhn
cc lnh t ngi dng v gi cc lnh n nhn h iu hnh thc thi. Hin nay ch yu tn
ti 3 shell: Bourne, Korn, C Shell. Bourne c pht trin ti phng th nghim Bell. C Shell
c pht trin cho phin bn BSD ca Unix. Korn Shell l phin bn ci tin ca Bourne Shell.
Nhng phin bn hin nay ca Unix bao gm Linux u tch hp c 3 shell trn.
Cu trc File hay h thng file (file system) quy nh cch lu tr cc file trn a. File
c t trong cc th mc. Mi th mc c th cha File v cc th mc con khc. Mt s th
mc l cc th mc chun do h thng s dng. Ngi dng c th to ra cc file hay th mc
ring v c th thay i cc file hay th mc . Trong mi trng Linux/ Unix, ngi dng cn
c th thay i cc quyn truy cp trn cc file hay th mc cho php hn ch quyn truy cp i
vi mt ngi dng hay mt nhm ngi dng. Cc th mc trong Linux c t ch hnh cy,
bt u l th mc gc (root), cc th mc khc uc phn nhnh t th mc ny.
Kernel, Shell v h thng File to nn cu trc h iu hnh. Vi cc thnh phn trn
ngi dng c th chy chng trnh, qun l file v tng tc vi h thng.
1.2 Mt s phin bn ca Linux:
Redhat v Fedora Core bn Linux c l l thnh hnh nht trn th gii, pht hnh bi cng
ty Redhat. T nm 2003, Redhat Inc chuyn hng kinh doanh. H u t pht trin dng sn
phm Redhat Interprise Linux (RHEL) vi mc ch thng mi, nhm vo cc cng ty, x
nghip. i vi ngi dng bnh thng, h m mt d n tn l Fedora. Redhat b tin v mt
s k s ca mnh h tr cho d n ny ng thi ku gi cc chuyn vin thit k trn khp th
gii qui t li pht trin Fedora Core. Bn Linux ca Redhat cui cng dng phin bn 9.0.
Version ca Fedora Core c m t 1. C th ngh i khi l FC1 tng ng Redhat 10,
FC2 tng ng Redhat 11. Thc t th khc nhiu, c bit l t FC2.

Trang 8

WhiteBox Linux Bn clone ca Redhat Enterprise Linux 3.0. Build trn source code ca
RHEL bi mt nhm cc k s LA, Hoa K. Hin nay server Nhatban.NET ang dng bn
ny.
SuSE Linux c sn xut c. Bn Linux cc k thnh hnh chu u v Bc M.
Nm 2003, cng ty SuSE b ng ln Novell mua. Novell ang dc sc u t cho SuSE nhm
vo cc nh doanh nghip hng ginh li th phn t tay Redhat. Bn SuSE mi nht hin nay l
9.1
Mandrake Linux Made in France. Cng l mt bn Linux rt thnh hnh chu u, M, v
Vit Nam. y cng l bn c u i nht trong vn Vit ho. Theo thng tin mi nht ngy
22/7/2004 th qu trnh Vit ho cho Mandrake Linux (MDK) t 85%. Bn MDK mi nht
hin nay l 10.0
Turbo Linux Ni ting Nht, Trung Quc. Cng ty Turbo ang u t mnh nhm thng
tr th trng Linux Trung Quc. Bn Turbo mi nht hin nay l 10F.
Debian Linuxm, mt ng ln na trong lng Linux. Nhiu ngi c kin cho rng:
ngi khng chuyn nn dng Fedora Core c th lm quen c vi nhng k thut mi
nht ca Linux, cn dn chuyn nghip nn dng Debian v s n nh tuyt vi ca n. Bn
mi nht: 3.0R2
Vine Linux Cc k c a chung ti Nht. c pht trin trn nn Redhat 6.2. c
im ca bn ny l rt nh (duy nht 1 a CD) v h tr ting Nht 100%. Vine Linux cng
c tch hp thm mt s tnh nng ca Debian v d nh apt-get. Bn mi nht hin nay l
2.6R4. Bn 3.0 c tung ra trong thng 8/2004.
Knoppix Linux c sn xut c. Bn live Linux c a chung nht hin nay. Khi
ng trc tip t CD m khng cn ci t vo cng. Phin bn mi nht l 3.4.
Vietkey Linux c sn xut ti Vit Nam. Hon ton khng c ting tm g ngoi chuyn
c gii trong cuc thi TTVN 2003. Pht trin bi nhm Vietkey trn nn Redhat 7.2. Cng
nn th cho bit sn phm ot gii nht ca TTVN n ra sao.
vnlinuxCD Bn live CD by Larry Nguyn. Nguyn tc ca vnlinuxCD ging Knoppix
nhng c build trn nn Mandrake 9.2. H tr kh tt cc vn v ting vit.
Cc phin bn khc cn rt nhiu nh phn phi khc. Cc bn t tm hiu thm c th
check: Slackware, Gentoo, College, Yellow Dog, SGI, Momonga...
1.3 H thng tp tin v th mc trn Linux:
Trong mi trng Windows (v d 2000 hay XP), mc d ngi dng c ton quyn t
chc cu trc th mc, nhng mt s quy nh truyn thng vn c tun theo. V d cc tp
tin h thng thng nm trong th mc :\Windows, cc chng trnh thng c ci t vo
C:\Program Files, v.v. . . Trong Linux cng c mt cu trc th mc kiu nh vy v thm ch
cn nghim ngt hn. Hn na c mt tiu chun xc nh cu trc th mc cho cc h iu
hnh dng UNIX. Tiu chun ny c gi l Filesystem Hierarchy Standart (FHS).
/bin: Th mc ny gm ch yu cc chng trnh, phn ln trong s chng cn cho h
thng trong thi gian khi ng (hoc trong ch mt ngi dng khi bo tr h thng). y
c lu rt nhiu nhng cu lnh thng dng ca Linux.
/boot: Gm cc tp tin c nh cn cho khi ng h thng, trong c nhn (kernel). Tp
tin trong th mc ny ch cn trong thi gian khi ng.
/dev: Th mc ny cha cc file thit b. Trong th gii Unix v Linux cc thit b phn
cng c xem nh lm mt file. a cng v phn vng l cc file nh hda1, hda2. a mm l
fd0 Cc tp tin thit b ny t trong th mc /dev.
/etc: Th mc ny cha cc file cu hnh ton cc ca h thng. C th c nhiu th mc
con ca th mc ny nhng nhn chung chng cha cc file script khi ng hay phc v cho
mc ch cu hnh chng trnh trc khi khi ng.
Trang 9

/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 khong cho ngi dng, h cp cho
ngi dng mt th mc con trong /home. Ngi s dng c th sao chp, xa file, to th mc
con trong th mc /home m khng nh hng n cc ngi dng khc.
/lib: th mc ny cha cc file th vin .so hoc .a. Cc th vin C v cc th vin lin lt
ng cn cho chng trnh khi chy v cn cho ton h thng. Th mc ny tng t nh th
mc SYSTEM32 ca Windows.
/lost + found: Th mc ny c t tn hi l nhng ng ngha ca n. 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 cc tp tin, Linux s gp chng li v t trong th mc ny
nu cn ngi dng c th c v gi li d liu mt.
/mnt: Th mc ny cha cc th mc kt gn tm thi n cc a hay thit b khc.
/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: y l th mc tm dng 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 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 ci t trong /usr/local vn gi nguyn v khng s b mt mt. Hu ht cc ng
dng Linux u thch ci t vo /usr/local. Th mc ny tng t nh Program File trn
Windows.
/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 hng i cha d liu cn a ra my in hoc cc hng i cha mail.
1.4 Cc lnh c bn trn Linux:
Hin th thng tin ngi dng:
Lnh who am I, hay whoami

To ti khon ngi:
Lnh useradd
useradd [tn ti khon]
Lnh cho php to mt ti khon ngi dng, ngi dng c th s dng ti khon ny
ng nhp vo h thng ngay trn my Linux hoc t cc my khc thng qua mng.
Bn ch khi ng nhp vo h thng vi ti khon root bn mi c th to ti khon
ngi dng, ng nhp h thng vi ti khon root c th ng nhp trc tip trn my hoc
thng qua mt my khc trn mng.

Trang 10

Sau khi to ti khon thnh cng, th mc c tn ti khon va to s c to ra trong th


mc /home /.
Xa ti khon ngi dung:
Lnh userdel
userdel [tn ti khon]
Thay i mt khu ng nhp:
Lnh passwd

Bn ch trong h thng Linux, khi bn nhp password th cc k t s khng c hin


th ra mn hnh di dng cc k t * nh trong h thng windows.
Thay i ti khon ng nhp:
Lnh su
Gi s bn ng nhp vi ti khon l root. Sau khi ng nhp du nhc h thng s c
dng #.
Gi chng ta to thm mt ti khon user c tn l user01 s dng lnh useradd nh sau:
useradd user01
Chuyn ng nhp sang user01 nh sau:
su user01
Lc ny du nhc h thng c dng $

Thay i ng nhp bng ti khong root:

Xem tr gip v lnh:


Lnh man
C php: man tn lnh
Lnh man cho php h thng hin th thng tin ca lnh c ch ra trong lnh man, y l
mt trnh tr gip hiu qu cho ngi s dng Linux.
Mt s phm chc nng trong lnh man:
:q Kt thc
:b V trang trc
:f V trang sau
Thay i th mc hin hnh:
Lnh cd (change directory)
Trang 11

$ cd <pathname>
pathname = ng dn tng i (tnh t th mc hin hnh) hoc tuyt i (tnh t th
mc gc)
Th mc c bit:
Th mc hin hnh: .
Th mc cha: ..
Th mc home: ~ hoc ~username
$cd /tmp
(chuyn ti th mc /tmp)
$cd ../home/a01
(chuyn ti th mc /home/a01)
$pwd
/home/a01
Lit k ni dung th mc:
Lnh ls (listing directory):
ls [option] path_name
V d:
$ ls
addr.c env.c fork.c lockf.c pipe1.c a.out exec1.c forkex.c lockf.h
-a lit k cc file n
-d ch lit k tn ca th mc, khng lit k ni dung
-F lit k cc file v cho bit kiu ca file qua k hiu cui
Khng c k hiu g: file thng
/
directories
*
executable files
@
linked files
-i cho bit s inode ca file
-l lit k y thng tin v file/th mc
-R lit k cc th mc con quy
-t sp xp theo thi gian cp nht
To th mc:
Dng lnh mkdir
mkdir path_name
V d:
$pwd
/export/home/a01
$mkdir examples
$ls aF
./ .bash_logout .bashrc .emacs ex.tar .screenrc
../ .bash_profile Desktop/ examples/ .kde/ .wl
V d cn to 3 th mc a, b, c nh sau a/b/c
Dng 3 lnh mkdir
$mkdir a
$mkdir a/b
Trang 12

$mkdir a/b/c
Dng mt lnh mkdir
$mkdir p a/b/c
1.5 Lnh xa file v th mc:
Lnh rm
Xo th mc rng (khng cha th mc con hay file)
rmdir path_name(s)
Xo th mc khng rng
rm r path_name(s)
Xo file
rm option file_name(s)
Lnh Copy files:
cp [-option] from(s) to
Copy th mc
cp -r from(s) to
Vd:
$cp /etc/passwd.
$cp p*.pas /tmp
$cp /etc/sysconfig/network-sripts /tmp
1.6 Di chuyn file v th mc
Lnh mv (move):
mv [option] filename dest_file
mv [option] directory dest_dir
mv [option] filename dest_dir
V d:
$mv examples lab1
To file v nhp vo ni dung
cat > name_of_file
Sau khi nhp ni dung, g <Enter> xung dng.
n Ctrl-d ghi ni dung son tho vo file v kt thc thao tc.
V d
$cat > test.txt <Enter>
this is my file <Enter>
Ctrl + D
$
To file rng (0 bytes) bng lnh touch
touch new_file
To file c ni dung di:
Lnh more:
more filename
Du nhc --More--(nn%) xut hin bn di mn hnh.
C th dng cc phm iu khin trong lc ang xem ni dung file
Trang 13

space bar
hin th trang k tip
<RETURN> hin th dng k tip
q
thot khi lnh more
b
v trang trc.
h
xem tr gip
Hin th n dng u tin ca mt text file, dng lnh head
head -n filename
(nu n=10, c th b option n i: head filename)
Hin th ni dung file:
Hin th n dng sau cng ca mt text file, dng lnh last
last -n filename
(nu n=10, c th b option n i: last filename)
1.7 Tm kim mt file trong h thng file (file system): dng lnh find
find pathname -name filename -print
(C th dng wildcard t trong du nhy kp)
V d:
$find / -name *.cpp -print
Cng c th nh v mt file bng cc lnh which, whereis, locate (lu l cc lnh ny ch
tm trong phm vi bin mi trng PATH hoc xxxPATH)
V d:
$ which find
$ locate ls
Tm trong ni dung ca file:
Tm mt chui k t trong mt text file bng lnh
grep pattern filename(s)
pattern: chui k t cn tm kim. Nu chui c k t c bit th phi t trong du nhy
n.
V d:
$ grep UNIX /usr/man/man*/*
$ grep -n '[dD]on\'t' notes
$ grep a01 /etc/passwd
Cc quyn trn file v th mc:
H thng *NIX bo v cc file v th mc thng qua cc quyn thit lp trn .
C 3 quyn:
rread - c
wwrite ghi
xexecute -thc thi
Cc quyn c p dng trn 3 nhm ngi dng, k hiu bng ba k t tng ng u, g, o
u = owner user = ch s hu
g = group = nhng ngi cng nhm vi ch s hu
o = others = tt c nhng ngi khc
Phn quyn:
Trang 14

Cc quyn p dng cho 3 nhm ngi dng kt hp li thnh 9 bit nh sau:


rwx rwx rwx
user group other
C th xem thng tin v quyn truy cp bng lnh ls -l
V d:
$ls -l
-rwxr-xr-x
Vi v d trn:
Ch s hu c quyn r (c), w (ghi), v x (thc thi).
Cc thnh vin cng nhm vi ch s hu c quyn r v x.
Nhng ngi khc c quyn r v x.
Thay i quyn trn file v th mc:
Dng lnh chmod.
chmod access_mode file(s)
Quyn truy cp c th thit lp theo 2 dng
Dng dng k hiu (symbolic): [ugo][+ -=][rwx]
Dng dng s bt phn (octal): [0-7][0-7][0-7]
1.8 Kt gn a v th mc:
Lnh mount
Lnh mount cho php kt gn cc phn vng hay thit b vt l nh A, CD_ROM thnh
mt th mc trong cy th mc thng nht ca h iu hnh bt u t th mc gc /. Lnh
mount n gin c c php nh sau:
mount t vfstype devicefile mdir
devicefile l ng dn n file thit b (thng lu trong thu mc /dev). Linux thng
quy nh a A l file thit b /dev/fd0. a CD-ROM l /dev/cdrom, cc phn vng l
dev/hda1, dev/hda2.Ty chn t s kt gn theo kiu h thng file trn thit b do vfstype quy
nh. mdir l ng dn cn kt gn vo h thng file ca Linux. Hin ti Linux c th c c
rt nhiu h thng file, vfstype c th bao gm nhng kiu h thng file thng dng sau:
Msdos l h thng file v th mc theo bng FAT16, FAT32 ca DOS. Linux c c
mi kiu a v nh dng ca DOS / Windows.
Ntfs
nh dng h thng file NTFS ca Windows NT
Ext2
nh dng h thng file chun ca Unix v Linux.
Nfs
nh dng h thng file truy xut qua mng (Network File System)
Mun tho kt gn c th s dng lnh umount. Lnh umount ch yu cu tham s l
ng dn n th mc ang kt gn. Sau khi tho kt gn bn khng cn truy xut vo thit b
c na.
V d kt gn a A vo th mc trong /tmp
mount t msdos /dev/fd0 /mnt/mydrive
c ghi th mc mydrive tng ng vi c ghi a a ca h thng
Tho kt gn a A
umount /mnt/mydrive
ng gi cc tp tin:
Trang 15

ng gi cc file ca chng trnh, ta thng nn chng li thnh mt file duy nht vi


cc dng nn nh .tar, .gz, .tgz. Thng file TAR (tape archive) trc y l mt file dng lu
tr ca UNIX nn t l nn khng cao. Bn nn cc file li thnh file .tar s dng lnh tar. Sau
ny thut gii nn zip cho php nn nhiu d liu hn nn cc file .tar c th c nn thm mt
ln na bng trnh gzip (trn Windows l winzip).
V d:
Gi s trong th mc hin hnh c cc file nh sau: main.c, a.c, a.h, b.c b.h, Makefile.
Gi ta nn cc file li v lu trong mt file nn c tn myapp.tar
tar cvf mayapp.tar main.c a.c a.h b.c b.h

Kt qu thu c tp tin nn myapp.tar trong cng mt th mc.


Trnh gzip c th cho kch thc file nh hn nh sau:
gzip myapp.tar

Kt qu ta thu c tp tin nn myapp.tar.gz


Khi nhn c tp tin nn myapp.tar.gz. qu trnh gii nn ngc li c th c tin hnh
nh sau:
Gii nn tr li tp tin .tar
gzip d myapp.tar.gz
Gii nn tp tin .tar
tar xvf myapp.tar
C php v ty chn ca lnh tar thng dng:
Tar [option] [list of file]
Trong option s mang cc gi tr kt hp sau:
c
To file tar mi
f
tn tp tin cn a d liu vo
t
Lit k ni dung hay danh sch file cha trong file tar
v
yu cu lnh tar hin th thng bo khi thc thi lnh
x
Bung cc file trong tp tin tar tr li a cng.
Thng thng khi nn cc tp tin to thnh file tar ta dng ty chn cvf. Ngc li khi gii
nn tp tin .tar ta dng ty chn xvf.

Trang 16

Chng 3
LP TRNH H V SHELL
1. S dng bin

2.Cc k t c bit

Trang 17

3. ng dn

4. Lnh r nhnh
Trang 18

Trang 19

4.1 Lnh if

Trang 20

#!/bin/sh
echo nhap a=
read a
echo nhap b=
read b
if [ $a -gt $b ] ; then echo 'a>b
elif [ $a -eq $b ] ; then
echo 'a=b
else echo 'a<b
fi

5. Vng lp

#!/bin/sh
dem=0
echo "ban nhap vao mot chuoi"
read word
echo "tach tu:"
for i in $word
do
dem="$(($dem+1))"
Trang 21

echo "$i"
done
echo "tong so tu la:$dem"
exit 0

6. Lnh CASE

Trang 22

#!/bin/sh
echo "Is it morning? Please answer yes or no"
read timeofday
case "$timeofday" in
"yes") echo "Good Morning";;
"no" ) echo "Good Afternoon";;
"y" ) echo "Good Morning";;
"n" ) echo "Good Afternoon";;
* ) echo "Sorry, answer not recognised";;
esac
exit 0

Trang 23

7. Lnh s hc

Trang 24

8. Express

9. Ly kt qu
Trang 25

Trang 26

Chng 4
LP TRNH TRN LINUX
Rt nhiu bn ngh rng lp trnh trn Unix , Linux lun lun phi dng ngn ng C. iu
ny hon ton ng bi v nguyn thy Unix c vit t C v phn ln cc ng dng cho Unix
cng dng C vit. Mc d vy C khng phi l mt la chn duy nht v bt buc. Ngoi
ngn ng C cn c th s dng nhiu ngn ng khc lp trnh nh Pascal, Assembler hay
Perl, Fortran, Prolog
Tuy nhin C/C++ v Pascal l hai ngn ng c kh nng bin dch mnh v gn gi vi
chng ta nht. Trnh bin dch C v Pascal trn Linux hon ton c kh nng bin dch c m
ngun vit bng ngn ng Assembler.
Chng trnh ng dng trn Unix, Linux tn ti 2 dng: dng thc thi (tp tin nh phn)
v dng thng dch script. Tp tin chng trnh thc thi dng nh phn tng t nh tp tin
.exe ca DOS. Script l nhng ch th lnh bng vn bn din dch v thc thi bi shell hay trnh
thng dch no . Cc file script tng t nh cc file.bat ca DOS.
Hu nh script hay chng trnh m my u c kh nng v sc mnh ngang nhau. Bn
kh phn bit u l lnh gi chng trnh nh phn u chng trnh gi lnh script trong Unix
v Linux tr khi xem ni dung ca chng. Chng trnh nh phn v chng trnh gi lnh script
c th hon i cho nhau. Mt chng trnh script nu thch bn c th chuyn thnh chng
trnh nh phn bng ngn ng bin dch C hay Pascal.
Khi ln u tin ng nhp vo h thng Linux v gi mt chng trnh t dng lnh, h
iu hnh Linux s tm ng dn n ni cha tp tin chng trnh trong bin mi trng
PATH. Thng th bin mi trng ny s cha cc ng dn c bn nh: /bin, /user/bin,
/usr/local/bin
Cc thnh phn cng c h tr h iu hnh thng c ci t vo th mc /opt. Linux
khng tm ng dn chng trnh trong th mc hin hnh tr khi bn thm k t (.) vo bin
mi trng PATH.
Lu l Unix, Linux s dng k t: phn cch cc ng dn trong bin mi trng
PATH trong khi DOS s dng k t ; V d:
PATH= /bin:/user/bin:/usr/local/bin
4.1 Chng trnh helloworld.c
Hello World l chng trnh kinh in i vi hu ht cc lp trnh vin khi tm hiu mt
ngn ng lp trnh mi. Trong phn ny s gip cc bn hiu v cc bc tin hnh lp trnh mt
ng dng bng ngn ng C, bin dch v thc thi ng dng trn mi trng linux.
Trc ht, m ca s Terminal. Terminal l giao din dng lnh cho php ngi dng
tng tc vi h thng thng qua cc lnh iu khin, n tng t nh bn nhp cc lnh trong
ca s cmd ca windows.
C nhiu cch khi ng ca s Terminal. Trong cc phin bn RedHat, chng ta ch cn
Click phi ln Destop, chn menu lnh Terminal. Trong cc phin bn khc nh Fedora Core,
m ca s Terminal Chn menu Applications / System Tools / Terminal

Du nhc trong ca s Terminal


To mt file c tn helloworld.c. C nhiu cch to mt tp tin m ngun. Bn c th
to trc tip trn ca s lnh ca Linux, hoc c th to bng cc chng trnh h tr trn
Trang 27

Windows v sao chp sang my Linux (phn ny s hng dn c th sau). Trong phn ny
s hng dn to mt tp tin m ngun trc tip trn Linux.
S dng trnh son tho vi nh sau:
vi helloworld.c
Trong trng hp tp tin ch nh trong lnh khng tn ti, trnh son tho vi t hiu phi
to mt tp tin mi c tn ch ra trong lnh, ngc li nu n s m tp tin cho php ngi dng
thay i.
Ln u tin vi m tp tin, c th chn ni dung vo tp tin, bn nhn phm I chuyn
sang ch insert, Nhp ni dung nh sau:
#include<stdio.h>
int main ()
{
printf (Hello World) ;
exit(0) ;
}
Thot khi ch INSERT v chuyn sang ch lnh bng cch nhn ESC .
lu li ni dung tp tin nhn t hp phm :w
thot khi trnh vi nhn t hp phm :q
Lc ny trong th mc hin hnh s to ra tp tin c tn helloworld.c
bin dch tp tin m ngun .c trn Linux s dng trnh bin dch gcc. Trc ht bn cn
kim tra s tn ti v phin bn ca trnh gcc trn my Linux ca bn. Thng thng khi ci t
h iu hnh Linux th gcc c ci t sn. xem thng tin v trnh bin dch b, ti dng lnh
bn nhp lnh gcc v.
Mt lot cc thng tin trong ng ch l phin bn ca gcc:

Bin dch tp tin m ngun:


gcc helloworld.c o helloworld

Sau khi qu trnh bin dch thnh cng, tp tin thc thi helloworld s c to ta. gi
tp tin ny chy trn mi trng Linux, c th gi trc tip nh sau:
./helloworld

Trang 28

Kt qu khi chy lnh printf (Hello World ) s hin th thng tin ra ca s.


Trnh bin dch gcc yu cu file cha m ngun C trn tham s dng lnh bin dch.
y ta ch nh helloworld.c i s dng lnh th nht. Ty chn o yu cu trnh bin dch to
ra file kt xut (file chng trnh thc thi) mang tn helloworld (bn c th ch nh mt tn file
kt xut khc vi file m ngun). Nu bn khng ch nh ty chn o th trnh bin dch s to
ra file thc thi vi tn a.out. Khi thay v gi helloworld trn dng lnh bn phi gi a.out
4.2 Chng trnh trn Linux:
Vi t cch l nh pht trin chng trnh bn cn nm r mt s v tr t ti nguyn
xy dng chng trnh nh trnh bin dch, file th vin, cc file header khai bo hm cu trc
d liu, cc file chng trnh sau khi bin dch s c t u..
Trnh bin dch gcc thng c t trong th mc /usr/bin hoc /usr/local/bin. Tuy
nhin khi bin dch gcc cn n nhiu file h tr nm trong cc th mc khc nh cc file C
header thng c t trong th mc /usr/include hay /usr/local/include. Cc file th vin lin
kt thng c gcc tm trong th mc /lib hoc /usr/local/lib. Cc th vin chun ca gcc
thng t trong th mc /usr/lib/gcc-lib
Chng trnh ca bn sau khi bin dch ra c th t bt k ni u trong h thng,
min l h iu hnh c th tm thy trong bin mi trng PATH hoc trn ng dn tuyt i
khi bn gi chng trnh t dng lnh.
Cc file header trong C thng nh ngha hm v khai bo cc hng cng vi cu trc
d liu cn thit cho qu trnh bin dch. Hu ht cc chng trnh trn Linux khi bin dch s
dng cc file header trong th mc /usr/include hoc cc th mc con bn di th mc ny.
V d nh /usr/include/asm, /usr/include/sys. Trong cc chng trnh C sau ny c th bn s
gp cc khai bo nh:
#include<sys/types.h>
Trnh bin dch lc ny s tm file header mang tn types.h trong th mc con sys ca
/usr/include. Mt s th mc cha file header c cc trnh bin dch d tm mc nh nh
/usr/include/x11 i vi cc khai bo hm lp trnh ha X-Window. Hoc th mc
/usr/include/g++ -2 i vi trnh bin dch GNU g++.
V d vit mt chng trnh gii phng trnh bc 2 bng ngn ng C, bin dch v chy
trn Linux.
#include<stdio.h>
#include<math.h>
int main()
{
float a,b,c,x1,x2,delta;
do{
printf("\nNhap vao he so a \n") ;
scanf("%f",&a) ;
}
while(a==0) ;
printf("\nNhap vao he so b \n") ;
scanf("%f",&b) ;
printf("\nNhap vao he so c \n") ;
Trang 29

scanf("%f",&c) ;
delta = b*b - 4*a*c ;
if (delta<0)
printf("\nphuong trinhh vo nghiem") ;
else if (delta==0)
printf("\nphuong trinh co nghiem kep x= %f ",-b/(2*a));
else
printf("\nPhuong trinh co nghiem \n x1=%f \nx2=%f");
exit(0);
}
Bin dch chng trnh
gcc main.c main
./main
4.3 Tin trnh (process)
Mt th hin ang chy ca mt chng trnh c gi l mt tin trnh (process). V d
chng ta c 2 ng dng ca s terminal trn mn hnh chng ta xem nh c 2 tin trnh ang
chy. Mi ca s terminal ang thc thi mt shell. Mi shell l mt tin trnh khc nhau. Khi
nhp mt lnh vo t mi shell, chng trnh s thc thi mt tin trnh mi, khi tin trnh mi
ny kt thc th tin trnh shell li c tip tc.
Lp trnh trn Linux thng s dng nhiu tin trnh trong mt ng dng cho php ng
dng c th thc thi nhiu cng vic hn nhm lm gia tng tnh hiu qu ca ng dng.
Hu ht cc hm x l cc tin trnh m t trong phn ny tng t nh trong cc h thng
Unix khc. Hu ht c khai bo trong tp tin unistd.h
4.4 S hiu ca tin trnh (process IDs):
Mi tin trnh trong h thng Linux c xc nh bi mt s hiu duy nht. Thng s ny
cn c gi l pid. S hiu tin trnh l mt s nguyn 16 bit c cp lin tc bi h thng
Linux khi mt tin trnh mi c to.
Mi tin trnh c mt tin trnh m (parent process) ngoi tr cc tin trnh c bit nh
init process. V th cc tin trnh trong h thng Linux c xp theo hnh cy vi tin trnh init
l gc. parent Process ID hay ppid n thun l cc s hiu ca cc tin trnh m.
Khi thao tc vi cc process ID trong cc chng trnh vit bng C/C++ chng ta thng
s dng cc kiu d liu nh ngha sn pid_t trong th vin <sys/types.h>. Mt chng trnh
c th c mt s hiu ca mt tin trnh ang chy bng cch gi hm h thng getpid(). Tng
t cng c th ly s hiu ca tin trnh m bng cch gi hm h thng getppid().
V d:
#include <stdio.h>
#include <unistd.h>
int main ()
{
printf (The process ID is %d\n, (int) getpid ());
Trang 30

printf (The parent process ID is %d\n, (int) getppid ());


return 0;
}
4.5 To tin trnh:
C 2 k thut chung c dng to mi mt tin trnh. K thut th nht hu nh n
gin nhng tnh hiu qu khng cao do khng an ton. K thut th 2 th phc tp hn nhng c
kh nng mm do hn, nhanh hn v an ton hn.
4.5.1 S dng system:
Hm system trong th vin chun ca C cung cp l cch thc n gin thc thi mt
lnh t bn trong mt chng trnh, tng t nh mt lnh c nhp vo t ca s shell. Thc
t hm system to mt tin trnh ph chy trong shell chun Bourne (/bin/sh). V d on
chng trnh sau s gi thc thi lnh ls hin th ni dung ca cy th mc gc tng t nh khi
bn g ls l trong mi trng shell.
#include <stdlib.h>
int main ()
{
int return_value;
return_value = system (ls -l /);
return return_value;
}
Hm system tr v trng thi kt thc ca lnh thc thi shell. Nu shell khng thc hin
lnh n s tr v gi tr 127, nu mt li khc xy ra, hm system s tr v gi tr -1.
Bi v hm system s dng shell gi lnh ca bn nn n l thuc vo c im, gii
hn v lut bo mt ca shell h thng. Bn khng th da vo bt k kh nng no ca cc
phin bn ring bit ca Bourne shell. Trong nhiu h thng Unix /bin/sh l mt lin kt n
mt shell khc. V d trong hu ht cc h thng GNU/UNIX /sbin/sh tr n bash shell. Nhng
phin bn phn phi khc ca GNU/UNIX th s dng nhng phin bn khc nhau ca bash
shell. C th l mt chng trnh vi mt quyn root, vi hm system d nhin l c nhiu
kt qu khc nhau trn cc h thng GNU/UNIX khc nhau. Chnh v iu m s dng
fork v exec to mi mt tin trnh.
4.5.2 S dng fork v exec:
DOS v API trn Winddows bao gm h cc hm SPAWN. Thng s ca cc hm ny l
tn ca mt chng trnh chy v to mt tin trnh mi th hin ca chng trnh . Linux
th khng bao gm mt hm n x l tt c trong mt bc. Thay vo Linux cung cp
mt hm fork, n c th to mt tin trnh con nh mt sao chp chnh xc tin trnh m. to
mt tin trnh trc tin s dng lnh fork to mt bn sao ca tin trnh hin ti. Sau s
dng hm exec chuyn i mt trong nhng tin trnh ny thnh th hin ca chng trnh m
bn mun to tin trnh.
Khi chng trnh gi lnh fork, mt bn sao ca tin trnh cn c gi l tin trnh con
(child process) c to ra. Tin trnh m tip tc thc hin chng trnh t v tr fork c gi.
Gia 2 tin trnh khc nhau nh th no? Trc ht tin trnh con l mt tin trnh mi v
th n c mt s hiu (ID) mi khc bit vi s hiu ca tin trnh cha. Mt cch khc chng
trnh c th nhn ra u l tin trnh cha v u l tin trnh con l gi hm getpid. Tuy nhin
hm fork cung cp gi tr tr v khc nhau cho tin trnh cha v tin trnh con khi c to. Gi
tr tr v ca tin trnh cha l s hiu ca tin trnh con, gi tr tr v ca tin trnh con l zero
bi v khng c tin trnh no c s hiu bng zero.

Trang 31

V d s dng lnh fork to mt tin trnh con. Ch rng trong khi u tin ca pht
biu if ch c thc thi trong tin trnh cha, trong khi pht biu trong mnh else li c thc
thi trong tin trnh con.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main ()
{
pid_t child_pid;
printf (the main program process ID is %d\n, (int) getpid ());
child_pid = fork ();
if (child_pid != 0)
{
printf (this is the parent process, with id %d\n, (int) getpid ());
printf (the childs process ID is %d\n, (int) child_pid);
}
else
printf (this is the child process, with id %d\n, (int) getpid ());
return 0;
}
Hm exec t mt chng trnh ang chy trong mt tin trnh vi mt chng trnh khc.
Khi mt chng trnh gi hm exec, tin trnh ngay lp tc dng chng trnh ang thc thi
v bt u thc thi mt chng trnh mi t gi s rng gi hm exec khng pht sinh ra li.
Mt s cc hm exec thng dng nh sau:
Cc hm bao gm k t p sau tn ca exec (execvp, execlp) nhn vo tn chng trnh v
tm chng trnh thng qua tn ca n trong ng dn ca chng trnh thc thi hin hnh.
Hm khng bao gm k t p phi c cung cp ng dn y ca chng trnh thc thi.
Cc hm bao gm k t v sau tn exec (execv, execvp, execve) nhn vo danh sch cc i
s cho chng trnh mi nh l mt mng khc NULL ca con tr chui. Cc hm bao gm k
t l (execl, execlp v execle) nhn vo danh sch cc i s s dng c ch ca ngn ng C.
Cc hm bao gm k t e (execve, execle) nhn vo cc i s truyn thng, mt mng cc
bin mi trng. Cc i s phi l mt mng khc NULL con tr ti chui k t, mi chui k
t c dng VARIABLE=value
Mt cch chung nht chy mt chng trnh con bn trong mt chng trnh kt hp
gi lnh fork v exec nh v d sau:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
/* Spawn a child process running a new program. PROGRAM is the name
of the program to run; the path will be searched for this program.
ARG_LIST is a NULL-terminated list of character strings to be
passed as the programs argument list. Returns the process ID of
the spawned process. */
Trang 32

int spawn (char* program, char** arg_list)


{
pid_t child_pid;
/* Duplicate this process. */
child_pid = fork ();
if (child_pid != 0)
/* This is the parent process. */
return child_pid;
else {
/* Now execute PROGRAM, searching for it in the path. */
execvp (program, arg_list);
/* The execvp function returns only if an error occurs. */
fprintf (stderr, an error occurred in execvp\n);
abort ();
}
}
int main ()
{
/* The argument list to pass to the ls command. */
char* arg_list[] = {
ls, /* argv[0], the name of the program. */
-l,
/,
NULL
/* The argument list must end with a NULL. */
};
/* Spawn a child process running the ls command. Ignore the
returned child process ID. */
spawn (ls, arg_list);
printf (done with main program\n);
return 0;
}
4.6 Tuyn (thread):
Tuyn (thread) l mt phn ca tuyn trnh s hu ring ngn xp v thc thi c lp ngay
trong m lnh ca tin trnh. Nu nh mt h iu hnh c nhiu tin trnh th bn trong mi tin
trnh, bn c th to ra nhiu tuyn hot ng song song vi nhau tng t nh cc tin trnh
hot ng song song bn trong h iu hnh. u im ca tuyn l chng hot ng trong cng
mt khng gian a ch ca tin trnh. Tp hp mt nhm cc tuyn c th chia s chung vng
nh ca mt tin trnh v do c th s dng chung bin ton cc, vng nh heap ca tin
trnh. C ch lin lc gia cc tuyn n gin v hiu qu hn c ch lin lc gia cc tin trnh.
4.6.1 To tuyn:
Mi tuyn trong mt tin trnh c nh ngha bi mt s hiu (thread ID). Khi tng tc
vi cc s hiu ca tuyn trong lp trnh C, C++ ta c th s dng kiu cu trc nh ngha
trc pthread_t.
Trang 33

Mi tuyn thc thi mt hm ca tuyn. Hm ny cng ging nh cc hm thng thng


khc, n bao gm cc on m chng trnh m tuyn phi thc thi. Khi hm ny tr v gi tr,
tuyn s c kt thc. Trong cc h thng Unix, hm tuyn ch bao gm thng s con tr void*,
kiu gi tr tr v void*. Chng trnh s dng thng s truyn vo mt tuyn khi to mt
tuyn mi. Tng t chng trnh cng c th s dng gi tr tr v ca tuyn truyn d liu
t mt tuyn kt thc v chng trnh to n.
Hm pthread_create to mt tuyn mi, chng ta c th s dng vi cc thng s nh
sau:
Con tr n kiu d liu pthread_t ma trong s hiu ca tuyn mi to c lu tr.
Con tr n i tng thuc tnh ca tuyn. i tng ny iu khin vic tuyn tng tc
nh th no vi cc thnh phn khc ca chng trnh. Nu truyn vo con tr NULL cho thuc
tnh ca tuyn, tuyn s c to vi thuc tnh mc nh.
Con tr n hm ca tuyn, y l con tr hm thng thng c dng sau:
void* (*) (void* )
Gi tr i s ca tuyn c kiu void*. Tc c nhng g truyn vo cho tuyn thc cht l
truyn tham s cho hm ca tuyn khi tuyn c to.
V d chng trnh sau to mt tuyn v gi tuyn thc thi:
#include <pthread.h>
#include <stdio.h>
void * display(void* unused)
{
while(1)
fputc('x',stderr);
return NULL ;
}
int main ()
{
pthread_t thread_id ;
pthread_create(&thread_id,NULL,&display,NULL) ;
while(1)
fputc('o',stderr) ;
return 0 ;
}
t tn tp tin chng trnh test.c. Bin dch chng trnh trn dng lnh nh sau:
gcc test.c o test lpthread
Thc thi chng trnh trn dng lnh:
./test.
Kt qu bn s thy cc k t x v o xut hin trn mn hnh, lnh putc truyn mt k t ra
vng m xut stderr.
4.6.2 Hy tuyn:
Hm pthread_exit() c dng chm dt mt tuyn hin hnh. Thng hm ny ch
c dng khi mun thot ra khi tuyn bt ng gia qu trnh thc hin lnh. Lnh ny khng
cn t cui mi hm thc thi tuyn. pthread_exit() cng c th dng tr d liu v ni
gi tuyn.
Trang 34

Chng 5
PHN CNG H THNG NHNG
H thng nhng cng l mt h thng vi x l m nhim mt chc nng ring bit no
. Tuy nhin khi thit k h thng nhng th i hi phi quan tm nhiu yu t hn mt h
thng vi x l thng thng. Mt h thng nhng thng thng l mt h thng da trn vi x l
m ch yu l cc vi x l 32 bit kt hp vi b nh, cc ngoi vi cn thit phc v cho chc
nng ca h thng. Vi iu khin ARM thng l la chn ti u cho h thng nhng bi chng
h tr nhiu. Cc h thng nhng s dng ARM c th lm gim cc ngoi vi, lm cho h thng
n gin nhng vn p ng c yu cu. Hin nay ARM c nhiu hng nghin cu v sn
xut vi tnh nng ngy cng vt tri.
Mt h thng nhng c bn c th xem bao gm cc phn cng nh vi x l, vi iu
khin, b nh, cc ngoi vi.
Trong ti liu ny s gii thiu phn cng h thng nhng da trn nn vi iu khin
ARM9 AT91Sam9260 ca Atmel.

Hnh 5. 1 S khi mt h thng nhng ca Atmel


5.1 Vi x l, vi iu khin:
Trang 35

Vi x l, vi iu khin l thnh phn quan trng trong h thng nhng, cc vi iu khin,


vi x l phi m bo v tc x l, kh nng giao tip v m rng cc ngoi vi p ng
yu cu h thng.
(Phn ny ln mng gii thiu chung cc h vi x l ca cc hng ni ting nh Renesas,
Samsung, Cirus Logic, Atmel).
Kin trc ca mt vi iu khin ARM AT91SAM9260 ca Atmel c bn nh sau:

Hnh 5.2 cu trc AT91SAM9260 ca Atmel


AT91SAM9260 l mt mch tch hp b x l ARM926EJ-S, b nh, mt s IO v h
thng bus.
B x l ARM926EJ-S l mt trong s cc ARM9, thuc h cc vi x l a mc ch ca
Atmel. B x l ARM926EJ-S bao gm mt kin trc ARM phin bn 5TEJ c thit k cho
cc ng dng a tc v vi b qun l b nh (MMU), tc x l cao, kch tht b v tiu tn
nng lng thp.
AT91SAM9260 c mt s c im nh sau:
- B x l ARM926EJ-S, 8Kbyte b nh m lnh, 8 Kbyte b nh m d liu.
- Bus giao tip b nh ngoi 32 bit h tr 4 bank SDRAM/LPSDR, static Memory,
CompactFlash, Nand Flash vi EEC.
- 4 kbyte b nh SRAM ni, 32 Kbyte b nh ROM ni cha bootstrap.
- Ma trn bux AHB 6 lp 32 bit vi tc 90Mhz
- 22 knh DMA
- Boot t Nand Flash, Sdcard, DataFlash, SiralDataFlash,
- On-chip Power-on Reset
Trang 36

- 4 b ADC 10 bit
- USB device v USB host
- 4 b USART, 2 UART
- 10/100Mbps ethernet.
- Giao tip SPI, SSC, 2 wire
5.2 Chng trnh khi ng vi iu khin AT91SAM9260 (boot program):
Chng trnh khi ng tch hp mt chng trnh c kh nng dowload hay upload mt
chng trnh khc ln mt vng nh khc ca vi iu khin.
Trc ht n khi ng n v g ri qua cng ni tip v thit b USB. Tip theo
chng trnh khi ng trn DataFlash c thc thi, n tm mt cch lin tc trong 8 vector ca
cc dataFlash c kt ni n vi iu khin thng qua chun SPI.
Nu mt vector hp l c tm thy, m chng trnh s c dowload vo bn trong
SRAM ni, chng trnh s nh x b nh v nhy n a ch u tin ca SRAM
Nu khng c mt vector hp l no c tm thy, chng trnh khi ng trn DataFlash
s c thc thi trn chn chn chip th 2(NPCS1).
Nu khng c mt Vector hp l no c tm thy trn c 2 chn chn Serial DataFlash,
chng trnh khi ng trn NAND Flash s c thc thi. Tng t chng trnh s tm 8
vector hp l, nu mt vector hp l c tm thy, m chng trnh s c download ln
SRAM, chng trnh s nh x b nh v nhy n a ch u tin ca SRAM.
Nu khng c vector hp l no c tm thy trn NAND Flash, chng trnh SAM-BA
Monitor s c thc thi v ch qu trnh truyn d liu chng trnh trn cc cng USB v
JTAG.

Trang 37

Lu chng trnh khi ng h thng c biu din nh sau:

Hnh 5.3 Qu trnh khi ng


5.3 Bus giao tip b nh ngoi:
Bus giao tip b nh ngoi (External Bus Interface) c thit k h tr qu trnh
truyn d liu gia mt s thit b ngoi vi bn ngoi vi b nh bn trong kin trc ARM. B
nh tnh (static memory), SDRAM, EEC cng c a ra trnh qun l b nh trn bus giao

Trang 38

tip b nh ngoi. Cc trnh qun l b nh ngoi ny c kh nng giao tip mt s loi b nh


nh SRAM, PROM, EPROM, EEPROM, Flash v SDRAM.
EBI cng h tr giao tip vi nand Flash v CompactFlash. EBI qun l truyn d liu vi
hn 6 thit b ngoi vi v c thit k 6 vng nh do trnh qun l b nh nhng bn trong nh
ngha. D liu truyn c th c thc hin 16 bit hay 32 bit, bus a ch ln n 26 bit, 8 ng
chn chip NCS[7..0].

Hnh 5.4 Bus giao tip b nh ngoi


V d thit k vi b nh SRAM ngai nh sau:
Trang 39

Hnh 5.5 kt ni b nh SRAM ngoi


5.4 Static memory Controller:
Static memory Controller (SMC) to ra cc tn hiu iu khin truy xut n vng nh cc
thit b ngoi hay cc ngoi vi kt ni bn ngoi chip. N bao gm 8 chn tn hiu chn chip vi
bus a ch 26 bit. Bus d liu 32 bit c th c cu hnh vi rng 8 bit, 16 bit, 32 bit. Cc
tn hiu iu khin c v ghi c lp cho php truy xut vng nh trc tip n cc thit b.
SMC kt ni n b nh tnh nh sau:

Trang 40

Hnh 5.6 Kt ni b nh tnh


SMC cung cp n 26 ng a ch, cho php mi chn chn chip c th ln n 64Mbyte
b nh.
A[25..0] c s dng khi giao tip b nh 8 bit, A[25..1] c s dng khi giao tip b
nh 16 bit, A[25..2] c s dng khi giao tip b nh 32 bit. iu ny gip chng ta hiu hn
cc thit k ca h thng nhng sau ny.
SMC kt ni vi 8 thit b m rng nh sau:

Hnh 5.7 Kt ni vi cc thit b m rng


Kt ni b nh 512K x 8bit s dng tn hiu chn chip NCS2:

Trang 41

Hnh 5.8 Kt ni b nh 512K X 8


Kt ni b nh 512K x 16 bit s dng tn hiu chn chip NCS2:

Hnh 5.9 Kt ni b nh 512 X16


Kt ni 2 b nh 512 x 16 bit nh b nh 32 bit s dng tn hiu chn chip NCS2

Trang 42

Hnh 5.10 Kt ni 2 b 512 X16


5.5 B nh:
B nh trong h thng nhng thng bao gm 2 b nh chnh: b nh chng trnh v b
nh d liu. Khc vi cc h thng vi x l thng thng, h thng nhng thng c mt h
thng phn mm iu khin phc tp hn nn b nh cng phc tp hn. Trong cc h thng
nhng th b nh chng trnh c nhim v lu tr cc phn mm khi ng (Boot program) nh
h iu hnh (OS image) v h thng tp tin (File System). Trong ti liu ny s trnh by mt s
thit k b nh ca h thng nhng da trn vi iu khin ARM9 ca Atmel.
5.6
B nh Serial DataFlash.
Serial DataFlash l cc IC nh dng Flash s dng giao tip ni tip SPI. Chun giao tip
SPI l chun giao tip thng dng nht hin nay n cho php truyn thng vi tc cao, Serial
data Flash c s dng lu tr chng trnh khi ng cho h thng. Khi hot ng chng
trnh khi ng ny s c b x l c v ghi ln SRAM sau mi thc thi. Trnh khi ng
c nhiu tn gi khc nhau cho cc h thng nhng khc nhau, xong bn c th hnh dung chng
ging nh chng trnh CMOS trn h thng my tnh m bn ang s dng. Trong cc h thng
nhng s dng cc vi iu khin ca Atmel, AMCC vi Power PC th l u-boot, hay Ciruss
Logic th s dng tn gi Red boot, mt s khc li gi tn l boot loader..
H thng pht trin AT91SAM9260 s dng Serial Data Flash ca Atmel, AT45DB041D,
dung lng 4 Mbit,
Mt b nh ni tip cng c s dng trong h thng l th nh SDCard, th nh c
dung lng ln c s dng lu tr h thng tp tin (File System) cho h thng nhng.

Trang 43

Hnh 5.11 kt ni giao tip b nh ni tip


AT45DB041D c b nh Flash c chia thnh nhiu trang, mi trang c th cu hnh 256
byte hay 264 byte, tn s xung clock truy xut ln n 66Mhz s dng chun giao tip SPI mode
0 v 3. c bit khc vi cc chip nh khc AT45DB041D c 2 vng nh m SRAM 256 /264
byte, iu ny gip cho qu trnh giao tip truyn d liu nhanh hn.

Trang 44

Hnh 5.12 Cu trc bn trong b nh ni tip


5.7 B nh NAND Flash
Nand Flash l mt dng ca b nh Eeprom c s dng lu tr nh ca h iu hnh,
tuy nhin khc vi cc b nh EEPROM thng thng, NAND Flash a hp cc tn hiu a ch
hng v ct ca ma trn cc nh lm hn ch cc ng a ch giao tip. Cng ngh ch to
cc NAND Flash s dng cc MOSFET kt hp tng t cc cng Logic NAND cho php tc
truy xut cao. Hnh di trnh by mt s khi ca mt NAND Flash.

Hnh 5.13 Cu trc bn trong NAND Flash


Giao tip NAND Flash trn h thng nhng:

Trang 45

Hnh 5.14 Giao tip NAND Flash


5.8 B nh SRAM:
B nh SRAM l b nh d liu chnh trong h thng nhng, Cc SRAM c dung lng
t vi chc Mbyte ty theo cc h thng khc nhau, tuy nhin b nh SRAM quyt nh n
nhiu vn v phn mm trong h thng nhng v bt k mt ng dng no trc khi thc thi
u c load xung SRAM. H thng pht trin h thng nhng da trn vi iu khin ARM9
AT91SAM9260 s dng SDRAM ca Micron c dng lng 256Mb.

Hnh 5.15 Giao tip SDRAM

Trang 46

S khi ca mt SDRAM c m t nh sau:

Hnh 5.16 Cu trc bn trong mt SDRAM


MT48LC16M16A2P l SDRAM 256Mb cng ngh CMOS, bn trong c thit k 4
bank DRAM, vi giao tip ng b.
5.9 Giao tip ngoi vi:
H thng nhng thng thng c thit k vi cc ngoi vi phc v cho chc nng h
thng nhng nh ADC, Graphic LCD, USB, PWM.. Tuy nhin mt s ngoi vi c thit k
chung cho c ng dng ng thi h tr cho qu trnh pht trin h thng.
Ethernet PHY DM9161A cho php hot ng 100BASE-TX , 10BASE-TX, giao tip
mng trc tip s dng cp xon i UTP5 cho 100BASE TX Fast Ethernet, UPT5/UTP3 cho
10BASE-TX ethernet. DM9161A ng vai tr lp vt l trong qu trnh giao tip mng.

Trang 47

Hnh 5.17 Giao tip PHY Ethernet


Giao tip ethernet c s dng load h iu hnh, file System xung h thng trong
qu trnh pht trin h thng, ng thi cn s dng trong cc ng dng mng cho h thng
nhng.
USB host v device: USB host cho php xy dng cc ng dng giao tip USB nh
Camera...
USB device cn c nhim v giao tip my ch load phn mm xung cho h thng
nh u-boot, bootstrap
Serial Port h tr giao tip my ch hin th thng tin trong qu trnh h thng hat ng.

Trang 48

Hnh 5.18 Giao tip USB v RS232

Trang 49

SPEC kit KM9260

Trang 50

Chng 6
PHN MM H THNG NHNG
6.1 Cu trc phn mm trong h thng nhng:
Tng t nh mt h thng my tnh n gin, mt h thng nhng l mt s kt hp cht
ch gia phn cng v phn mm, khc vi cc h thng vi x l thng thng khc, h thng
nhng c mt h thng phn mm iu khin phc tp hn. Chng ta hy hnh dung h thng
phn mm trong mt my tnh. Khi bn mua mt my tnh mt phn mm c ci t sn
trong h thng l CMOS. Chng trnh ny lm nhim v giao tip gia ngi s dng vi
phn cng v thc hin cc thao tc tip theo. Sau bn ty thch ci h iu hnh m bn
mun, sau khi c h iu hnh cc ng dng li c la chn phc v nhu cu ca bn. Phn
mm trong h thng nhng cng tng t nh mt h thng my tnh. H iu hnh trong cc h
thng nhng cng tng i phong ph. Hin nay c nhiu h iu hnh cho h thng nhng nh
Window CE, LinuxTuy nhin Linux l c la chn nhiu do m ngun m v nhiu tnh
nng nh a nhim, a ngi dng Ngai ra Linux cn cho php ti bin dch nhn h iu
hnh trn ngay chnh h iu hnh. Vic pht trin h thng nhng s dng h iu hnh Linux
c thc hin trn mt my tnh s dng h iu hnh Linux, y cng l l do m cc chng
trc ti liu hng dn co thao tc v cch lp trnh trn h thng Linux. Mt h thng
nhng s dng h iu hnh Linux thng thng c 3 lp phn mm nh sau:
Boot Loader l tn gi chung mt phn mm c ci t trc vo h thng, phn mm
ny c nhim v khi to h thng v thc hin giao tip gia h thng vi ngi s dng. C
nhiu phin bn cng nh nhiu loi bootloader khc nhau. Cc b x l ca Ciruss Logic nh
EP9315th s dng red boot, AMCC vi Power PC v cc ARM9 ca Atmel th s dng uboot, mt s b s l khc th dng lun tn Boot Loader. Trong ti liu ny s trnh by mt t
chc phn mm trong mt h thng nhng s dng b x l ARM9 ca Atmel. Trong cc h
thng nhng s dng b x l ca Atmel th phn boot loader bao gm 2 phn Bootstrap v Uboot, phn h iu hnh Linux l kernel linux c cu hnh cho ph hp, phn file system c
s dng mt s file system ca linux nh Amstrong, Debian...

BootStrap
U-boot

Kernel

File System

6.1.1 BootStrap v U- boot:


BootStrap l mt chng trnh khi ng c np xung trc tin cho cc vi iu khin
dng ARM 9 ca Atmel.

Trang 51

BootStrap l mt module ng dng, n c s dng thc hin cc chc nng sau:


o Khi to phn cng nh tn s xung clock, thit lp cc PIO (programmable Input
Output).
o Thit lp cc ngoi vi nh PIO, PCM, SDRAMC...
o Thc hin cc thut ton truy xut vt l cc ngoi vi nh DataFlash, NANDFlash,
Paralell Flash..
o iu khin cc tp tin h thng nh JFFS2, FAT..
o Thc thi cc ng dng nh ELF, Linux.
- BootStrap c th c t trong vng bootLoader, c th l c t trong vng DataFlash.
BootStrap c chp ln RAM ni bi trnh SAM-BA Boot. BootLoader thc hin khi to vi
x l (PLL, PIO, SDRAMC, SPI).
- BootStrap thc hin load U-boot t DataFlash ln SRAM v tr n thc hin chng
trnh U-Boot.
- U-boot (universal bootLoader) l mt tp m ngun m, h tr bootLoader cho nhiu
kin trc nn khc nhau. U-boot h tr cc lnh tng tc, cc bin mi trng, cc lnh thc thi
v boot h thng t cc thit b media bn ngoi. U-boot h tr nhiu loi CPU v cc h CPU
thng dng hin nay. U-boot h tr cc board pht trin trn nn cc vi x l thng dng hin
nay.
- U-boot thc hin cu hnh cc khi phn cng trong mt board v t chng vo trng thi
hot ng. N c th load v thc thi h iu hnh mt cch t ng (auto-boot) hoc ngc li
n cho php ngi dng khi ng h iu hnh thng qua cc lnh giao tip m u-boot h tr.
Tp lnh chun ca u-boot cung cp kh nng cho php ngi s dng thao tc trn b nh,
mng v nhiu thao tc khc khi h thng khi ng.
- Thng thng u-boot c t trong phn vng u tin ca Flash, bt u t sector hay
block no c nh ngha bi vi x l. U-boot khi to CPU v mt vi phn cng trn board,
to mt vi cu trc d liu cho kernel s dng v load n ln phn vng u tin ca b nh.
- Khi quyn iu khin c chuyn n cho u-boot, n s khi to cc ngt v cc thit b
ngoi vi. Sau u-boot ch nhp cc lnh t ngi dng. Nu u-boot nhn c lnh boot nh
ca kernel hoc nu n c s dng boot kernel trc tip th u-boot s gii nn kernel
image, load kernel ln b nh v chuyn iu khin n kernel. Kernel s thc thi m khng c
s tng tc vi u-boot.
- U-boot cung cp cc hm chun hiu chnh qu trnh khi ng v khi to kernel.
Thng th n cung cp cc thao tc di dng cc lnh (command-line).
- U-boot c nhiu phin bn, tuy nhin t phin bn 1.3.4 tr i th mi h tr b x l
AT91SAM9260 ca Atmel.
- Cu trc th mc ca U-boot.

Trang 52

Nm r kin trc cc thnh phn trong u-boot gip ngi pht trin h thng bin dch v
cu hnh u-boot cho tng thch vi cc phn cng khc nhau.
Th mc board xc nh nhiu kin trc nn khc nhau ca cc hng khc nhau nh Philip,
AMCC, Atmel, davici, Cirus Logic... th mc board cng bao gm cc hm khi to cc board.
Cc hm ny c th gi t th vin lib_<arch>/board.c
Th mc board / <boardname> xc nh thng tin chi tit cho h thng, th mc ny
cha cc tp tin khi to cn thit cho mi h thng bao gm cc tp tin nh asm_init.S,
congif.mk, flash.c
Th mc common cha tp tin nh ngha cc lnh ca uboot, cc bin mi trng nh
cmd_boot.c, cmd_date.c, environment, env.c, main.c...
Th mc CPU bao gm cc tp tin xc nh cc thng s, khi to cc ngt, b nh m...
cho CPU nh cpu.c, cpu_init.c, interrupts.c, cache.s, start.s...
Th mc disk cha cc tp tin phn vng v thng tin thit b cho a.
Th mc driver cha cc tp tin thit b nh ethernet, usb, sirial...
Th mc include bao gm nhiu tp tin header nh console.h, version.h, usb.h, pci.h.
Trong tp tin version.h nh ngha phin bn ca u-boot #define u-boot_VERSION xxx.
Include/congifs cha cc cu hnh cho nhiu board.
Th mc lib_generic cc th vin chung nh bzlib.c vsprintf, string.c...
Th mc net cha cc tp tinh Ethernet nh eth.c, net.[ch], nfs.[ch], bootp.c [ch].
Th mc fs cha cc file h thng nh fat, fdos, jffs2
Th mc bao gm cc tp tin h tr ch ng h thi gian thc rtc date.c, mpc8xx.c, etc.
Th mc tools cc th mc v cc tp tin h tr bin dch, g ri nh env, gdb, logos,
scripts, mkimage.c
Th mc post bao gm cc tp tin v th mc nh post.c codec.c, cache.c, memory.c,
uart.c, etc.
6.1.2 Bin dch li u-boot:
Sau khi thit k mt h thng nhng mi, qu trnh bin dch li u-boot thc thi trn h
thng mi l ht sc cn thit. Qu trnh ny hay con gi bng mt thut ng porting. Porting
u-boot l qu trnh to ra mt u-boot vi cc thng s ph hp cho b x l v cc thit b ngoi
vi. Mt cch chung nht thc hin vn ny l to ra t cc u-boot c sn t cc board c
cu hnh gn ging vi h thng m bn ang thit k.
Trc ht to mt s tp tin v th mc phc v cho vic cu hnh h thng:
u-boot/board/<boardname>
u-boot/include/configs/<boardname>.h
u-boot/Makefile
Chp cc tp tin v thay i makefile v kin trc nn cho board nh include, cpu,
lib_arch, v board.
Trong th mc include, tp tin config/<boardname>.h s bao gm cc tp tin cu hnh
phn cng cho h thng nh nh x b nh v cc ngoi vi. Cu hnh b x l, cu hnh b nh
khi ng, cu hnh Nor hay Nand flash, cu hnh b nh SDRAM, cc giao tip ni tip,
ethernet v network...tp tin <core>.h nh arm926ejs.h bao gm cc nh ngha cn thit cho
b x l nh a ch cc thanh ghi...
Trong th mc cpu bao gm cc tp tin nh cpu.c cha cc khai bo cho b x l, cc
hot ng c v ghi IO, Reset CPU, cho php hay khng cho php hot ng ca b nh m
lnh v b nh m d liu, khi to ngn xp cho cc ngt. Th mc interrupt.c bao gm cc
hm phc v cho ngt v timer, nh cho php ngt hay khng cho php ngt, cc hm lin quan
Trang 53

n b nh thi. Tp tin start.S l chng trnh khi ng cho li ca b x l. Tp tin <


boardname >/flash.c cha cc hm lin quan n b nh flash nh khi to flash, cc hm
reset, xa, c v ghi b nh flash.
Sau khi to ra mt tp m ngun ca u-boot, bc cui cng l bin dch u-boot to ra tp
tin thc thi u-boot.bin.
Ti liu s trnh by cc bc bin dch u-boot phin bn 1.3.4 cho h thng nhng s
dng vi iu khin ARM91SAM9260 ca Atmel.
Trc ht download m ngun u-boot di dng tp tin nn v t mt s trang web nh
http://www.denx.de/wiki/U-Boot/SourceCode. bn c file u-boot-1.3.4.tar.bz2
Chp vo th mc trn my Linux. V d /sontruong. Chng ta c th download m ngun
trc tip trn mt my Linux kt ni vi mng internet, thc hin cc thao tc trn mt my tnh
chy h iu hnh Linux. Tuy nhin trong thc t th nhiu nh pht trin phn mm li dng
my tnh vi h iu hnh Windows XP. Vista. iu ny hon ton thch hp v s thng tho
cng nh quen thao tc trn h iu hnh Windows. Linux ch c nhim v bin dch m ngun
m thi. Chnh v th m ngi ta thng kt ni mt my Linux vi nhiu my Windows
cng lc nhiu ngi c th pht trin h thng nhng, nhiu ngi c th truy cp v my Linux
ti mt thi im do Linux l mt h iu hnh a nhim, a ngi dng. Cc my tnh trn
Windows c th giao tip v truy xut vo my Linux thng qua mt s phn mm h tr nh
SSH client..

Trn my tnh s dng h iu hnh windows, vic chp mt tp tin t gia 2 my tnh
c thc hin mt cch n gin thng qua vic ko th cc tp tin, th mc.
Sau khi ci t SSH secure File Transfer, thc hin kt ni n my Linux thng qua tn
user, a ch IP, Port

Trang 54

Ca s bn tri l cc th mc v tp tin trn my Windows, bn phi l cc tp tin v th


mc trn my Linux

Gii nn gi m ngun u-boot bng dng lnh: Tar xjvf u-boot-1.3.4.tar.bz2


Ta thu c th mc u-boot-1.3.4 nh hnh di.

Trang 55

Bin dch uboot cho ARM khng s dng trnh bin dch gcc c sn trn my tnh ci
linux. Trc ht bn cn ci gi phn mm bin dch arm-linux-gcc. ci t gi phn mm
bin dch, download gi phn mm arm-linux-gcc-3.4.3.tar.bz2 v v gii nn vo th mc gc
ca my Linux.
Gi phn mm bin dch bn c th ti v t trn mng.
Trc khi bin dch, cn thit lp bin mi trng v ng dn cho trnh bin dch, v d
nh sau:
PATH=/usr/local/arm/3.4/bin:$PATH
Trong th mc PATH=/usr/local/arm/3.4/bin cha cc trnh bin dch nh arm-linuxgcc
Bin dch uboot cho h thng:
Make clean: xa ht cc cu hnh bin dch trc .
Make at91sam9260ek_config: khai bo bin dch uboot cho h thng board
at91sam9260ek.

Make all
Nu qu trnh bin dch thnh cng trong th mc u-boot-1.3.4 s tn ti file u-boot.bin

6.1.3 Cc thao tc trn u-boot:

Trang 56

Sau khi U-boot c load vo h thng. Bootstrap thc thi, khi to cc thng s cho
b, load uboot v thc thi uboot. Khi uboot thc thi, u-boot command cho php ngi s dng
c th giao tip vi h thng thng qua cc lnh u-boot h tr.
Trc ht cn thit lp cc thng s mi trng cho h thng.
thit lp cc thng s mi trng chng ta s dng command setenv nh sau:
o Thit lp a ch IP cho board: setenv ipaddr <a ch IP cho board>
o Thit lp a ch IP cho host: setenv serverip <a ch host>
o Thit lp a ch ethernet(MAC): setenv ethaddr <MAC address>
o Thit lp mt n: setenv netmask <submask net>
o Lu li cc bin mi trng vo dataflash: save
xem li cc bin mi trng ti dng lnh bn nhp lnh prinenv

Chun b kernel cho h thng.


Ti command line uboot ca:
Xa vng nh NAND FLASH chun b cho kernel:

nand erase offset length

nand erase 0x0 0x200000

Lnh trn cho php xa 2 Mbyte b nh Nand Flash a ch offset l 0. (vng nh u


tin ca NandFlash)
Chp uImage t my tnh vo SRAM a ch 0x20000000

Tftp 0x20000000 uImage

c th chp thng qua giao thc tftp th trn my tnh host phi ci t v chy dch v
tftp, file uImage c lu trong thc mc ca tftp server.

U-boot s d trong bin mi trng xem a ch ca server l bao nhiu v n s ln sever


ny tm file c tn uImage v chp vo b nh SRAM t a ch 0x20000000.
Thc thi kernel

Bootm 0x20000000

H thng s chuyn n a ch SRAM 0x20000000 boot Umage:


Trong trng hp ny ln sau khi m in ni dung trn SRAM s mt i. c th
s dng uImage cho cc ln khi ng sau chng ta cn chep uImage ln NandFlask.
Nand write 0x20000000 0x0 0x200000
Trang 57

Chp 2 Mbyte t a ch SRAM 0x20000000 ln nandflash c a ch offset l 0


(vng u tin ca NandFlash)
Cc ln khi ng sau s chp uImage t Nanflash xung SRAM v thc thi n trn
SRAM
Nand read 0x20000000 0x0 0x200000
Bn ch cc thao tc chp uImage t Nandflash xung SRAM v thc thi n c
thit lp trong bin mi trng uboot thc hin mt cch t ng.

Bng tng hp cc lnh ca u-boot:


autoscr
base
bdinfo
bootm
bootp
bootd
cmp
cp
crc32
echo
erase
flinfo
go
help
iminfo
loadb
loadc
loadg
loads
loop
md
mm
mtest
mw
nm
printenv
protect
rarpboot
reset
run
saveenv
setenv
sleep
Trang 58

run script from memory


print or set address offset
print Board Info structure
boot application image from memory
boot image via network using BootP/TFTP protocol
boot default, i.e., run 'bootcmd'
memory compare
memory copy
checksum calculation
echo args to console
erase FLASH memory
print FLASH memory information
start application at address 'addr'
print online help
print header information for application image
load binary file over serial line (kermit mode)
load binary file over serial line (ymodem-c mode)
load binary file over serial line (ymodem-g mode)
load S-Record file over serial line
infinite loop on address range
memory display
memory modify (auto-incrementing)
simple RAM test
memory write (fill)
memory modify (constant address)
print environment variables
enable or disable FLASH write protection
boot image via network using RARP/TFTP protocol
perform RESET of the CPU
run commands in an environment variable
save environment variables to persistent storage
set environment variables
delay execution for some time

tftpboot
version
? alias for 'help'

boot image via network using TFTP protocol and env


variables ipaddr and serverip
print monitor version

6.2 Bin dch nhn h iu hnh Linux cho h thng:


H thng nhng s dng b x l ARM9 ca Atmel s dng h iu hnh Linux c phin
bn t 2.6.27. Bin dch nhn h iu hnh cho h thng l qu trnh thay i cu hnh ca nhn
h iu hnh Linux sao cho tng thch vi h thng, qu trnh ny thng thng mt phn c
thc hin bi cc nh sn xut, mt phn c thc hin bi cc nh pht trin h thng.
Download phin bn Linux 2.6.27 v my tnh di dng gi tp m ngun linux2.6.27.tar.bz2. Copy gi m ngun Linux vo my Linux thc hin bin dch. Trc khi bin
dch, download trnh bin dch cross Compiler v v ci vo my Linux.
arm-2009q3-67-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 cha cc trnh bin
dch cn thit ph v cho qu trnh bin dch nhn h iu hnh Linux. i tn gi li thnh
arm-kernel_compiler.tar.bz2.
Gii nn gi va mi i tn tar xjvf arm-kernel-compiler.tar.bz2
Trc khi tin hnh bin dch ta phi khai bo ng dn n trnh bin dch, nu qu trnh
ny b b qua, trnh make s khng tm thy trnh bin dch gi, chng trnh bn s b li.
Gi s th mc arm-kernel-compiler c bn chp vo th mc /sontruong. Sau khi bin dch
th mc arm2009q3 c to ra. Nh vy cc trnh bin dch nm trong th mc:
/sontruong/arm2009q3/bin
Tin hnh thm ng dn n trnh bin dch nh sau:
Export PATH=$PATH:/sontruong/arm2009q3/bin
uboot-mkimage.tar.bz2 l chng trnh to ra nh ca nhn h iu hnh c chp vo
trong th mc my Linux, qu trnh ci t c th c tin hnh nh sau:
# tar jxvf uboot-mkimage.tar.bz2
# cd uboot-mkimage
# make clean
# make
# chmod 777 mkimage
# cp mkimage /bin
Gii nn linux-2.6.26.tar.bz2
# tar jxvf kernel-2.6.27.tar.bz2
#cd linux-2.6.27

Trang 59

Thay i cc cu hnh ca h thng, s dng: #make menuconfig

Mt menu hin ra cho php thit lp cc ty chn thch hp nh b x l, b nh SDRAM,


Flash, ethernet, giao tip cc ngoi vi. Sau khi thc hin cu hnh thch hp chn save lu li.
Vic chn cc cu hnh trong ca s menuconfig ty thuc vo phn cng h thng m
chng ta ang thit k, n i hi nhiu kin thc v thit k phn cng. Ti liu khng i trnh
by chi tit cc ty chn. Ngi bin dch phn mm i hi phi nm cc thit k phn cng h
thng cu hnh cho ng.
V d cu hnh cho b x l.

Trang 60

Trong menu h thng cha c loi vi x l tng thch vi h thng bn, iu ny cng d
hiu, Linux c thit k h tr nhiu phn cng khc nhau, bn mun cu hnh Linux cho mt
h thng ring ca bn i hi bn phi c kin thc tht tt v h thng v h iu hnh lm
c iu . Bn phi to ra cc tp tin Linux hiu h thng ca bn khi bin dch. i vi
h thng nhng s dng ARM9 ca Atmel, nh sn xut lm sn cho bn cc thay i bng
cch to ra cc bng v nhn h iu hnh linux.
Download cc bn v
2.6.xx-at91.patch.gz , 2.6.xx-at91-exp.patch.gz
Chy cc bn v
zcat 2.6.xx-at91.patch.gz | patch -p1
zcat at91-exp. patch.gz | patch -p1
Download tp tin cu hnh at91sam926yek_defconfig
Chp tp tinh cu hnh vo th mc config trong th mc Linux. Sau thc thi config
cp at91sam926yek_defconfig .config
make ARCH=arm oldconfig
Trong qu trnh thc hin oldconfig, trnh bin dch s yu cu bn xc nhn mt s thng
s cho h thng.
Thc thi menuconfig
make ARCH=arm menuconfig
Lc ny menuconfig xut hin cho php bn tin hnh cc ci t cho h thng.

Trang 61

Trong mc chn System type:

Trang 62

Da vo thit k h thng, chng ta c th thay i mt s thng s da vo vic chn cc


menu trong menuconfig.
Bin dch Linux image
make ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi- uImage
Sau khi bin dch thnh cng, tp tin nh ca nhn h iu hnh c to ra trong th mc
arch/ arm/ boot.
Trong phn ny ti liu trnh by mt s khi nim v phn mm h thng nhng, cc bc
bin dch u-boot cho h thng nhng, mt s thao tc trn mi trng uboot. Cc bc thao tc
bin dch nhn h iu hnh. Phn File System chng ta c th ty chn ty thuc vo mt s
c im ca h thng nh b nh, tc x l. Vic pht trin trn h thng nhng rt a dng,
ngi pht trin ty thuc vo mc ch v yu cu ca h thng c th thay i trong u-boot,
cng c th thay i cc tp tin iu khin thit b trong kernel, hoc c th xy dng cc
chng trnh ging nh cc ng dng chy trn h iu hnh. Tuy nhin cho d bn pht trin h
thng nhng mc no th qu trnh bin dch, cc kin thc v u-boot, kernel lun l cn
thit.

Trang 63

V d thit k bi tp giao din dng lnh trn kit KM9260


Phn 1: vit code chng trnh hello v bin dch trn linux
1. Ci t trnh bin dch cho trn linux
2. Khai bo ng dn cho trnh bin dch
PATH=$PATH:/root/km9260/arm-2009q3/bin/
3. Bin dch chng trnh
arm-none-linux-gnueabi-gcc -o hello hello.c
Phn 2: chp code qua kit
Bc 1:
t a ch trn PC(window): 192.168.1.2 netmask 255.255.255.0
default gw 192.168.1.1
t a ch trn kit:
ifconfig eth0 192.168.1.60 netmask 255.255.255.0
route add default gw 192.168.1.1 eth0
Trong trng hp my cha thit lp MAC ta vo U-Boot thit lp
U-Boot> setenv ipaddr 192.168.1.35
(ip ca board)
U-Boot> setenv serverip 192.168.1.34
(trng ip ca my tnh)
U-Boot> setenv ethaddr 00:11:22:33:44:55
U-Boot> setenv netmask 255.255.255.0
U-Boot> save
Bc 2: Np hello xung Kit bng lnh TFTP
Trn my tnh serser m tftpd32 v browse ti th mc cha tp tin hello
Trn mn hnh putty ang mn hnh root ca Linux ca KIT
SAM9260-EK ta nh lnh sau:
# tftp -g -l / -l hello 192.168.1.2 y IP ca my server
S3: Gn thuc tnh thc thi (lnh trn putty)
# chmod 777 hello
S4: Chy chng trnh trn board (lnh trn putty)
# ./hello

Trang 64

Cch 2:
1. Ci t trnh bin dch cho trn linux
2. Khai bo ng dn cho trnh bin dch
PATH=$PATH:/root/km9260/arm-2009q3/bin/
3. Bin dch chng trnh
arm-none-linux-gnueabi-gcc -o hello hello.c
3. Chp file sang kit
scp hello root@192.168.1.60:/home/root/baitap/
4. truy cp kit:
=> ssh 192.168.1.60
User: root; pass: 1234567
Ch :
nu ssh yu cu add key:
=>to file config trong thu muc:~/.ssh/
ni dung file config:
Host 192.168.1.*
StrictHostKeyChecking no
UserKnownHostsFile=/dev/null

Trang 65

Chng 7
LP TRNH GUI S DNG QT
Exercises Lecture An introduction to Qt
Install the Qt SDK
Visit http://qt-project.org/downloads , and download the LGPL version of Qt SDK
suitable for your system. Then proceed to install the SDK. This gives you a Qt Creator
icon on your desktop and in your program menu. Please refer to the platform specific
tips and tricks below if you are experiencing any issues with this.
Windows
If altering the installation path of the Qt SDK, make sure to use a path without spaces.
Spaces can in some situations confuse the build tool-chain.
Mac OS X
Installation should be straight forward.
Before you can develop Qt applications, you must make sure you have installed the
developer tools from the DVD that came with your Mac.
Unix/Linux X11
Before you can develop Qt software, you must ensure that you have a C++ toolchain
installer. This usually means GCC with support for C++. This comes as a part of your
distribution and you must install it to be able to use the SDK.
If your Linux distribution has a prepackaged version of Qt Creator and the Qt
development libraries, it is often better to use those libraries. This course has been
developed with Qt 4.6+ and Qt Creator 1.2+ in mind.
If you choose to use the installer downloaded from the web, you must make the installer
executable before you can run it. You can either do this by setting the executable bit
(sometimes just X-bit) of the file through your file manager, or by running chmod from a
command prompt.
chmod u+x qt-sdk-linux-*.bin

When running the installer, make sure that you have write access to the directory where
you chose to install the SDK.

Trang 66

Testing the tool-chain


To ensure that the SDK has been properly installed, please try to build and debug some
of the examples shipped with Qt. On the welcome screen of Qt Creator, make sure that
you are on the Getting Started page shown below. From the list of Qt examples, pick
the Animated Tiles example from the Animation Framework group.

Having opened the project, ensure that you are in edit mode (Ctrl+2), then look for
main.cpp in the Sources folder. Understanding the source code is not the purpose of this
exercise, so leave that for later. Instead, try pressing the run button (Ctrl+R) to start the
example. This will trigger Qt Creator to first build the example, then run it. When the
example has been built, you should see a window with the demo running.

Trang 67

Having run the project, you have verified that the compiler and linker work. The next
step is to test the debugging features.
To find a point in the code to insert a break point at, we will use the locator. The locator
lets you search within your project. It can be used to look for classes, methods and files
within or outside your project. In this case, you are looking for the mousePressEvent in the
main.cpp file. To locate a method, start your search with a dot followed by a space . .
Then start typing mousePressEvent until you find the method in the list, then press
enter to go there.

Having located the Button::mousePressEvent in the source code, you will see something like
the image below. Try setting a break point as shown below (by clicking just left of the
line number or right clicking on the line number and picking Set Breakpoint from the
pop-up menu).

To start debugging click the debugging button (F5) just below the run button. This will
start a debugging session. The example program will start as expected, but as soon as
you click one of the buttons, the program execution will break and the editor will show
the current callstack, breakpoint and so on.

Trang 68

To resume execution, press the resume button on the debugging bar. Exiting the
example program will end the debug session.
When you have run and debugged this example, you have verified that your
development setup is in order and you are ready to continue.

Create a Hello World project


To create a project of your own, go the the welcome screen using the top-left button
(Ctrl+1), pick the page Develop and click Create New Project....

From the dialog that pops up, create an Empty Qt4 Project, then specify a location for
your project. Notice that Qt Creator will create a sub-directory with your project's name,
so if you choose to name the project helloworld and create it in /home/user/code, your source
files will end up in /home/user/code/helloworld.
If you have other projects open (from earlier exercises), make sure to either close them
(right click on the project node and choose Close Project ... from the menu) or ensure
that you are working with your project by right clicking on your project in the projects
tree view and pick your project as the current run configuration. Your project should be
marked as bold as shown below.

Trang 69

Now, right click on your project and choose Add New... from the menu. In the following
dialogs, create a C++ Source File and name it main.cpp. In the file, enter the following
code and save it.
#include <QApplication>
#include <QLabel>
int main(int argc, char **argv)
{
QApplication a(argc, argv);
QLabel l("Hello World");
l.show();
return a.exec();
}

Now, run the application (Ctrl+R) and try stretching and moving the resulting window
about.

Trang 70

Lecture 2 The Qt Object Model and Signal Slot Mechanism


Exploring Inheritance
Start by creating a new, empty Qt 4 project in Qt Creator. Add the following to your
project:

A C++ class, ValueObject, inheriting from QObject

A C++ source file, main.cpp

In main.cpp, create a main function and include the ValueObject header file. In your main
function, implement the following function body.
{
ValueObject o;
// Insert code here
}

return 0;

Using the function QObject::inherits(const char *className), write qDebug statements testing if o
inherits QObject and ValueObject.
Note! If using Qt Creator on Windows, you might have to run your code in
the debugger to see the qDebug printouts!
Try commenting out the Q_OBJECT macro from the valueobject.h header file. Discuss and
explain the results. Remember to re-enable the Q_OBJECT macro after having tested this.
Now, try testing a QFile object. Does it inhert QIODevice, QDataStream, QObject or QTemporaryFile?
Can you find this information in the documentation as well as through testing?

Properties
For this step, we keep the class that we created in the previous step.
Start by adding two member functions to the ValueObject class:

setValue,

value,

setting an integer value of the object

returning the set integer value of the object

These methods set and get an int value. You will have to add a private int member
variable to keep that value. Do not forget to initialize the private value in the constructor.

Trang 71

Now, modify your main function to look like this.


int main(int argc, char **argv)
{
ValueObject o;
qDebug("Value: %d = %d", o.value(), o.property("value").toInt());
o.setValue(42);
qDebug("Value: %d = %d", o.value(), o.property("value").toInt());
o.setProperty("value", 11);
qDebug("Value: %d = %d", o.value(), o.property("value").toInt());
}

return 0;

You will have to include the QVariant header file as well for the property calls to work.
Run the code, discuss and explain the results.
Now, add a Q_PROPERTY macro defining the value property with a READ and a WRITE
function. Add the macro just after the Q_OBJECT macro in the class declaration.
Re-run the code, discuss and explain the different result.

Memory Management
Continuing from the previous step, we now add a qDebug statement in the constructor
along with a destructor with a qDebug statement. Make sure that the destructor is virtual.
The qDebug statements should inform you when an object is constructed and when it is
destructed. In the destructor, add a reference to the QObject::objectName property as well.
Replace the property setting and debugging from the last step with the following line.
o.setObjectName("root");

Running the code should now yield an output looking something like this.
ValueObject constructed.
ValueObject root destructed.

Now, add the following code just after the setting of the object name of of o.
ValueObject *c1 = new ValueObject();
c1->setObjectName("child 1");
ValueObject *c2 = new ValueObject();
c2->setObjectName("child 2");
ValueObject *c1c1 = new ValueObject();
c1c1->setObjectName("child 1 of child 1");
ValueObject *c2c1 = new ValueObject();
c2c1->setObjectName("child 2 of child 1");
ValueObject *c = new ValueObject();
c->setObjectName("child");

Run the code and evaluate the result. The code is leaking memory.

Trang 72

Now, provide a parent pointer to the constructors of c1, c2, c1c1 and c2c1 so that the
ownership tree looks like the illustration below.
root

child 1

child 1
of child 1

child 2

child 2
of child 1

Finally, assign c2 as the parent of c using the QObject::setParent method.


Run the code and verify that all objects are properly destructed. Discuss and explain the
order of destruction, as well as why having the root object on the stack instead of the
heap simplifies the situation.

Signals and Slots


Again, building on the results from the last step, we will now add signals and slots to our
ValueObject class.
Set functions are natural slots, and are also natural points for adding signals tracking
the value of the property being set. Update the ValueObject class declaration with these
changes.
Move setValue to the public slots section
Add a signal called valueChanged carrying an integer argument
Alter setValue so that it prints the new value and emits the valueChanged signal upon the
value changing.
Now, replace the contents of your main function with the following code.
int main(int argc, char **argv)
{
ValueObject o1;
ValueObject o2;
o1.setValue(1);
o2.setValue(2);
// Connect here
qDebug("o1: %d, o2: %d", o1.value(), o2.value());
o1.setValue(42);
qDebug("o1: %d, o2: %d", o1.value(), o2.value());
o2.setValue(11);
qDebug("o1: %d, o2: %d", o1.value(), o2.value());
}

return 0;

Running the code shows that o1 and o2 are completely independent.


Trang 73

Now, establish a connection from o1 to o2, making the value of o2 follow o1.
Run the code, discuss and explain the behavior.
Now establish another connection from o2 to o1, making the two ValueObject instances
follow each other.
Run the code, discuss and explain the behavior.
If the program hangs here, setting the same value over and over again,
you have forgotten to add a check in your setValue. If the value isn't
changed, the setValue slot should simply return.
Try to come up with situations in a user interface where the two connection relationships
are useful, i.e. one object following another, versus two objects following each other.

The Signal Mapper


This step uses the calculator project as the base. Please open the project in Qt Creator
and familiarize yourself with the components of the project.

The project is divided into three parts.

main.cpp,

containing a boilerplate main function

The class CalculatorInterface, providing a user interface for a basic calculator


The class Calculator, providing a trivial calculator engine implementation
In the file calculatorinterface.cpp, you will find the constructor shown below.
CalculatorInterface::CalculatorInterface(QWidget *parent) :
QWidget(parent),
ui(new Ui::CalculatorInterface),
m_calculator(new Calculator(this))
{
ui->setupUi(this);
// Add code here
m_calculator->allClear();
}

The user interface, made available through the ui variable, holds the following set of
widgets:

buttonZero

Trang 74

buttonOne

buttonTwo

buttonThree

buttonFour

buttonFive

buttonSix

buttonSeven

buttonEight

buttonNine

buttonClear

buttonAllClear

buttonAdd

buttonSubtract

buttonCalculate

entryLabel

Trang 75

The Calculator class, object m_calculator, holds the following slots:


the number provided has been entered (0-9)

numEntered(int)

clear()

clearAll()

additionMode()

subtractionMode()

calculate()

- clear the current entry


- clear the calculator state completely
- switch to addition mode, calculates before switching mode
- switch to subtraction mode, calculates before switching mode

- calculate the next result, clears the current entry

The class also provides a signal, displayChanged(QString), used to update any display
showing the status of the calculator.
In the CalculatorInterface constructor, make all the connections you can see fit. Run the
code and discuss the result.

Extending the Calculator


The Calculator class is far from perfect. The interested student can extend the
calculator in various ways:
Add more operations (e.g. multiplication and division)
Add support for entering negative numbers
Add memory operation (M+, M-, MC, MR)

Add support for larger numbers (the current limit is the size of int)

Trang 76

Solution Tips
Step 1 - Inheritance
Test if the object o inherits from QObject using the following line.
qDebug("ValueObject inherits QObject: %s",
o.inherits("QObject")?"yes":"no");

Step 2 Properties
The class declaration looks like this when the member functions and private variable
have been added.
class ValueObject : public QObject
{
Q_OBJECT
public:
explicit ValueObject(QObject *parent = 0);
void setValue(int value);
int value() const;
private:
int m_value;
};

The property declaration to be added at the end of the exercise reads like this.
Q_PROPERTY(int value READ value WRITE setValue)

Step 3 Memory Management


The constructors need to be called with the following parent pointers.
ValueObject *c1 = new ValueObject(&o);
ValueObject *c2 = new ValueObject(&o);
ValueObject *c1c1 = new ValueObject(c1);
ValueObject *c2c1 = new ValueObject(c1);

The parent of c is assigned using the following line.


c->setParent(c2);

Trang 77

Step 4 Signals and Slots


The class declaration looks like this when the slot and signal have been added.
class ValueObject : public QObject
{
Q_OBJECT
Q_PROPERTY(int value READ value WRITE setValue)
public:
explicit ValueObject(QObject *parent = 0);
virtual ~ValueObject();
int value() const;
public slots:
void setValue(int value);
signals:
void valueChanged(int);
private:
int m_value;
};

The connections for interconnecting o1 and o2 look like this.


QObject::connect(&o1, SIGNAL(valueChanged(int)),
&o2, SLOT(setValue(int)));
QObject::connect(&o2, SIGNAL(valueChanged(int)),
&o1, SLOT(setValue(int)));

The implemented slot looks like this.


void ValueObject::setValue(int value)
{
if(m_value == value)
return;
m_value = value;
qDebug("Value set to %d", m_value);
emit valueChanged(m_value);
}

Trang 78

Hng dn ci t QT Everywhere trn KIT FriendlyArm


1. Mc ch:
- Ci t Qt SDK trn my tnh Linux, cho php pht trin ng dng chy trn Desktop.
- Ci t th vin Qt Everywhere (hay Qt Embedded), cho php pht trin ng dng chy
trn KIT FriendlyArm (Embedd Linux).
- Hng dn ny thc hin i vi phin bn Qt 4.7.2
Gii thiu
- Qt l mt framework pht trin ng dng a nn tng, bao gm:

+ a cross-platform class library (Th vin cc lp hng i tng)


+ integrated development tools (Cc cng c pht trin tch hp)
+ a cross-platform IDE. (Mi trng pht trin ng dng)
- Qt cho php vit ng dng mt ln v bin dch cho trn nhiu nn tng h iu hnh khc
nhau m khng phi vit li m. Tuy nhin, m ngun cn c
bin dch trn nn tng m mun ng dng c thc thi. Qt c pht trin bi cng ty
Trolltech t nm 1994, n 2008 c st nhp vo hng Nokia v
c gi l Qt Software.
- Lp trnh Qt theo chun C++.
- Hnh di ch ra cc thnh phn ca b cng c lp trnh Qt SDK

Trang 79

2. Ci t Qt:
- B ci QT SDK cho Desktop
- B ci QT Everywhere
C th pht trin ng dng Qt trn 3 nn tng my tnh khc nhau: Linux, Windows, hoc Mac.
Trong hng dn ny ch tp trung vo ci t Qt trn my tnh
Linux X86.
2.1. Ci t Qt SDK trn my tnh X86 Linux (Ubuntu)
Bc 1.Chun b file ci t qt-sdk-linux-x86-opensource-2010.05.1.bin
Download t trang ch http://qt.nokia.com/downloads (chn phin bn thch hp cho X86 Linux
32 bit), hoc copy vo my.
Bc 2.Di chuyn n th mc cha file ci t, cp quyn thc thi cho file nu cn. Dng lnh:
$ chmod u+x qt-sdk-linux-x86-opensource-2010.05.1.bin

Bc 3.Thc thi file ci t t dng lnh:


$ ./qt-sdk-linux-x86-opensource-2010.05.1.bin

i qu trnh ci t din ra thnh cng, mc nh th mc ci t cha ti $HOME/qtsdk2010.01/qt/bin


Sau khi ci t xong Qt SDK, cng c Qt Creator cho php pht trin ng dng vi la chn mc
nh bin dch trn my tnh Linux. bin dch cho ng dng

Trang 80

thc thi trn KIT FriendlyArm (Embedded Linux) cn ci t Qt Everywhere


2.2. Ci t Qt Everywhere trn host Linux
ng dng vit bng Qt chy trn KIT FriendlyArm c th s dng mn hnh touchscreen ca
KIT, cn ci mt th vin h tr touchscreen gi l tslib, trc khi
cu hnh ci t Qt Everywhere.
2.2.1. Ci t v build tslib
Trc tin cn ci t mt s cng c h tr bin dch tslib nu my tnh cha c sn.
sudo apt-get install autoconf
sudo apt-get install libtool

Download tslib:
$ cd ~
$ mkdir tslib-arm
$ cd tslib-arm
$ apt-get source tslib

Configure tslib:
$ cd tslib-1.0
$ ./autogen.sh
$ ./configure --prefix=$HOME/tslib_arm/ --host=arm-none-linux-gnueabi

Trong file config.h, sa dng sau (approx. line 185)


#define malloc rpl_malloc --> /* #define malloc rpl_malloc */

Sau , bin dch (cross-compile) tslib:


$ make
$ sudo make install

i cho qu trnh bin dch v ci t kt thc thnh cng. (Nu c li cn kim tra li v thc

Trang 81

hin li). Th vin tslib sn sng s dng (s c cu hnh s


dng khi ci t Qt Everywhere).
2.2.2. Ci t Qt Everywhere trn host
Bc 1. Chun b file nn gi ci t qt-everywhere-opensource-src-4.7.2.tar.gz
C th download t trang ch http://qt.nokia.com/downloads (chn phin bn thch hp), hoc
copy trn my tnh. ( ti th mc ngi dng $HOME)
Bc 2. Gii nn file ci t
M ca s lnh, di chuyn n th mc cha file ci t trn v tin hnh gii nn.
Dng lnh:
gunzip qt-everywhere-opensource-src-4.7.2.tar.gz
tar xf qt-everywhere-opensource-src-4.7.2.tar

Kt qu gii nn ra mt th mc cng tn file tar.


Bc 3. Cu hnh v bin dch gi ci t
Di chuyn vo th mc gii nn ca gi ci t:
cd qt-everywhere-opensource-src-4.7.2

Thm bin mi trng n ng dn trnh bin dch Qt (M file ~/.bashrc, thm bin mi
trng $HOME/qt-everywhere-opensource-src-4.7.2)
Sa file cu hnh bin dch qmake.conf cha ti $HOME/qt-everywhere-opensource-src4.7.2/mkspecs/qws/linux-arm-g++/qmake.conf nh sau.
#
# qmake configuration for building with arm-linux-g++
#
include(../../common/g++.conf)
include(../../common/linux.conf)
include(../../common/qws.conf)

Trang 82

# modifications to g++.conf
QMAKE_CC

= arm-none-linux-gnueabi-gcc

QMAKE_CXX

= arm-none-linux-gnueabi-g++

QMAKE_LINK

= arm-none-linux-gnueabi-g++

QMAKE_LINK_SHLIB

= arm-none-linux-gnueabi-g++

# modifications to linux.conf
QMAKE_AR

= arm-none-linux-gnueabi-ar cqs

QMAKE_OBJCOPY

= arm-none-linux-gnueabi-objcopy

QMAKE_STRIP

= arm-none-linux-gnueabi-strip

QMAKE_INCDIR

+= /opt/tslib/include

QMAKE_LIBDIR

+= /opt/tslib/lib

Load(qt_config)

(Ch : Bin mi trng c th c thm khng chnh xc hoc khng thnh cng, trong
trng hp trong file qmake.conf trn nn t ng dn tuyt i n cc trnh bin dch)
Sau , tin hnh cu hnh th vin Qt Everywhere 4.7.2 trc khi ci t
$ cd
$ cd qt-everywhere-opensource-src-4.7.2
./configure --prefix=/opt/qte -embedded arm -xplatform qws/linux-arm-g++ -qtmouse-tslib -little-endian -no-qt3support -fast -no-largefile -qt-sql-sqlite
-nomake tools -nomake demos -nomake examples -no-webkit -no-multimedia -nojavascript-jit

(Qu trnh cu hnh din ra mt thi gian), ch n khi thng bo thnh cng. Tin hnh dch th
vin:
$ make

(Qu trnh make din ra ~hour ph thuc vo cc option la chn khi configure trn). Trong

Trang 83

trng hp tht bi (xut hin thng bo li), cn thc hin li:


make confclean, cu hnh li vi option thch hp v make li.
i qu trnh make thnh cng, g lnh ci t:
$ sudo make install

i qu trnh ci t thnh cng, kim tra kt qu ci t ti /opt/qte nh cu hnh trn.


2.2.3. Ci t Qt Everywhere trn target (KIT)
Th vin Qt Everywhere ci trn host Linux cho php bin dch ng dng Qt chy trn KIT
FriendlyArm. Tuy nhin, cn copy mt s file th vin c bn, v font xung KIT ng dng
c th thc thi.
Th vin Qt Everywhere (Libraries): Copy ti thiu 3 file th vin sau (Copy qu nhiu s tn
b nh)
-

libQtCore.so.4

libQtGui.so.4

libQtNetwork.so.4

Trn KIT t vo th mc /opt/qte/lib (nu cha c cn to th mc ny, ging nh th mc


trn host)
Fonts:Copy th mc fonts xung KIT cha /opt/qte/lib/fonts
Th vin tslib: Copy ton b th mc /opt/tslib trn host xung KIT ti th mc /opt/tslib
2.2.4. Thit lp chy ng dng Qt trn KIT.
Tt Qtopia
- Mc nh khi khi ng KIT vi h iu hnh Linux nhng ci t, th vin Qtopia 2.0

Trang 84

c khi ng. (Cc ng dng vit chy trn th vin ny cn c build li cng Qtopia
2.0). chy ng dng Qt trc tip, cn tt Qtopia trnh xung t. Thc hin nh sau:
- Trn KIT, dng vi m file cu hnh /etc/init.d/rcS, disable dng Qtopia.
Chnh sa cu hnh s dng touchscreen trn KIT
- Dng vi m file cu hnh /opt/tslib/etc/ts.conf, b ch thch dng lnh module_raw input
- Thm bin mi trng s dng th vin tslib, dng vi sa file /etc/profile, thm ni dung
nh sau (dng lib copy ln KIT):
export TSLIB_TSEVENTTYPE=INPUT
export TSLIB_ROOT=/opt/tslib
export TSLIB_TSDEVICE=/dev/input/event0
export LD_LIBRARY_PATH=$TSLIB_ROOT/lib:$LD_LIBRARY_PATH
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_PLUGINDIR=$TSLIB_ROOT/lib/ts
export TSLIB_CONSOLEDEVICE=none
export TSLIB_CONFFILE=$TSLIB_ROOT/etc/ts.conf
export POINTERCAL_FILE=/etc/pointercal
export TSLIB_CALIBFILE=/etc/pointercal
export QWS_MOUSE_PROTO=TSLIB:/dev/input/event0

Qu trnh ci t n y thnh cng, ng dng vit bng Qt c th c bin dch v


np ln KIT thc thi.
3. Cu hnh Qt Creator bin dch vi nn tng Qt Embedded (Qt Everywhere)
Bc 1. Chn tab Project, m giao din Build Settings tng ng Project ang cu hnh.

Trang 85

Trn ca s ny, m mc Manage

Bc 2.Click nt Add (+) thm mi mt nn tng bin dch cho.


To 1 cu hnh bin dch mi, t tn Mini2440, tr ti Qmake ci t phn trc (nm
trong /opt/qte/bin/qmake)

Trang 86

Bc 3. Bin dch ng dng vi cu hnh bin dch thit lp trn.

Trang 87

Bc 1. Khi ng IDE Qt Creator, to mt Project


Giao din Start Page (nh hnh di) cho php:

M Project mu (Choose an example)

Xem ti liu hng dn lp trnh (Tutorials)

M project c (Open Project)

To Project mi (Create Project).

Chn Create Project to mt d n mi:

Trang 88

Chn Qt C++ Project/Qt GUI Application, thc hin tip cc bc theo hng dn Wizard ca
Qt Creator.
Lu chn cu hnh nn tng bin dch thit lp bin dch ng dng chy trn KIT
FriendlyArm (hoc bin dch chy trn desktop).
Bc 2. Ti Form chnh thit k mt giao din c bn nh sau:

Trang 89

- Ko mt TextEdit v 2 Pushbutton, mt nt tn l Display v mt nt tn l Clear.


- Chut phi vo nt display, chn Go to slot ->> chn Clicked() ->> OK
Thm dng lnh sau cho s kin click ca pushbutton display:
ui->textEdit->setText(QString("Hello World!"));

- Chut phi vo nt Clear, chn Go to slot ->> chn Clicked() ->> OK.
Thm dng lnh sau cho s kin click ca pushbutton Clear:
ui->textEdit->setText(QString(" "));

Bc 3. Build Project
Ch trong ca s Build Settings, chn cu hnh bin dch qmake cho nn tng Qt FriendlyArm
(phin bn tng ng vi Qt Everywhere ci t)
Chn Build/Build All. ng dng c build thnh cng, kt qu c file thc thi (trong th
mc Project) s chuyn ln KIT chy. V d ny l file HelloQt).

Trang 90

Bi tp: LP TRNH CHNG TRNH CALCULATOR S


DNG QT
1. Giao din ca h thng

2. Hot ng
Khi ta thc hin cc php tnh cng tr nhn chia cc s thc th ta check
vo option Real
Khi ta thc hin cc php tnh cng tr nhn chia c s thc ln s phc th
ta check vo option Clex
Sau khi thc hin xong 1 php tnh th kt qu ti khung nhp v th hin
php tnh khung trn, ta c th chnh sa cc php tnh khung php
trn v bm du bng cng cho ra kt qu.
Chng trnh c vit trn Qt creator
3. Code chng trnh calculator
+ calculatorwin.cpp
#include"calculatorwin.h"
#include<QDebug>

Trang 91

CalculatorWin::CalculatorWin()
:mathString( "" ), item( "0" ), isRealMode( true )
{
//initialize mian window
setupUi( this );
engine = new Engine();
timer = new QTimer();
mainLineEdit->setText( "0" );
mainLineEdit->setMaxLength( 9 );
mainLineEdit->setReadOnly( true );
expandLineEdit->setReadOnly( true );
realRadioButton->setChecked( true );
complexButton->setEnabled( false );
timer->start( 100 );
//connect signals with slots
connect( zeroButton, SIGNAL( clicked() ), this, SLOT( zeroButtonClicked() ) );
connect( oneButton, SIGNAL( clicked() ), this, SLOT( oneButtonClicked() ) );
connect( twoButton, SIGNAL( clicked() ), this, SLOT( twoButtonClicked() ) );
connect( threeButton, SIGNAL( clicked() ), this, SLOT( threeButtonClicked() ) );
connect( fourButton, SIGNAL( clicked() ), this, SLOT( fourButtonClicked() ) );
connect( fiveButton, SIGNAL( clicked() ), this, SLOT( fiveButtonClicked() ) );
connect( sixButton, SIGNAL( clicked() ), this, SLOT( sixButtonClicked() ) );
connect( sevenButton, SIGNAL( clicked() ), this, SLOT( sevenButtonClicked() ) );
connect( eightButton, SIGNAL( clicked() ), this, SLOT( eightButtonClicked() ) );
connect( nineButton, SIGNAL( clicked() ), this, SLOT( nineButtonClicked() ) );
connect( dotButton, SIGNAL( clicked() ), this, SLOT( dotButtonClicked() ) );
connect( clearButton, SIGNAL( clicked() ), this, SLOT( clearButtonClicked() ) );
connect( realRadioButton, SIGNAL( clicked() ), this, SLOT( setRealMode() ) );
connect( complexRadioButton, SIGNAL( clicked() ), this, SLOT( setRealMode() ) );
connect( complexButton, SIGNAL( clicked() ), this, SLOT( complexButtonClicked() ) );
connect( backButton, SIGNAL( clicked() ), this, SLOT( backButtonClicked() ) );
connect( addButton, SIGNAL( clicked() ), this, SLOT( addButtonClicked() ) );
connect( subButton, SIGNAL( clicked() ), this, SLOT( subButtonClicked() ) );
connect( signButton, SIGNAL( clicked() ), this, SLOT( signButtonClicked() ) );
connect( mulButton, SIGNAL( clicked() ), this, SLOT( mulButtonClicked() ) );
connect( divButton, SIGNAL( clicked() ), this, SLOT( divButtonClicked() ) );
connect(
frontBracketButton,
SIGNAL(
clicked()
),
this,
SLOT(
frontBracketButtonClicked() ) );
connect(
backBracketButton,
SIGNAL(
clicked()
),
this,
SLOT(
backBracketButtonClicked() ) );
connect( equalButton, SIGNAL( clicked() ), this, SLOT( equalButtonClicked() ) );
connect( upButton, SIGNAL( clicked() ), this, SLOT( upButtonClicked() ) );
connect( downButton, SIGNAL( clicked() ), this, SLOT( downButtonClicked() ) );
connect( clsHistoryButton, SIGNAL( clicked() ), this, SLOT( clsHistoryButtonClicked() ) );

Trang 92

connect( timer, SIGNAL( timeout() ), this, SLOT( setUpOrDownButtonEnbled() ) ); //set a


timer to check the stack of history
}
//slots to response button clicked event
void CalculatorWin::zeroButtonClicked()
{
if( item == "0" )
mainLineEdit->setText( item );
else if( ( item != "0" ) && ( item.at( item.length() - 1 ) != 'i' ) )
{
item = item + "0";
mainLineEdit->setText( item );
}
}
void CalculatorWin::oneButtonClicked()
{
dealWithNonZero( "1" );
}
void CalculatorWin::twoButtonClicked()
{
dealWithNonZero( "2" );
}
void CalculatorWin::threeButtonClicked()
{
dealWithNonZero( "3" );
}
void CalculatorWin::fourButtonClicked()
{
dealWithNonZero( "4" );
}
void CalculatorWin::fiveButtonClicked()
{
dealWithNonZero( "5" );
}
void CalculatorWin::sixButtonClicked()
{
dealWithNonZero( "6" );
}
void CalculatorWin::sevenButtonClicked()
{
dealWithNonZero( "7" );
}
void CalculatorWin::eightButtonClicked()

Trang 93

{
dealWithNonZero( "8" );
}
void CalculatorWin::nineButtonClicked()
{
dealWithNonZero( "9" );
}
void CalculatorWin::dotButtonClicked()
{
if( isRealMode )
{
if( ( !item.contains(".") ) && ( item.at( item.length() - 1 ) != 'i' ) && ( item.at(
item.length() - 1 ) != '+' ) && ( item.at( item.length() - 1 ) != '-' ) )
{
item = item + ".";
mainLineEdit->setText( item );
}
}
else
{
if( ( item.count(".") < 2 ) && ( item.at( item.length() - 1 ) != 'i' ) && ( item.at(
item.length() - 1 ) != '+' ) && ( item.at( item.length() - 1 ) != '-' ) && ( item.at( item.length()
- 1 ) != '.' ) )
{
item = item + ".";
mainLineEdit->setText( item );
}
}
}
void CalculatorWin::complexButtonClicked()
{
if( !item.contains("i") )
{
item = item + "i";
mainLineEdit->setText( item );
}
}
void CalculatorWin::dealWithNonZero( QString number ) //function to deal with non-zero
number input
{
if( item == "0" )
{

Trang 94

item = number;
mainLineEdit->setText( item );
}
else if( ( item != "0" ) && ( item.at( item.length() - 1 ) != 'i' ) )
{
item = item + number;
mainLineEdit->setText( item );
}
}
void CalculatorWin::clearButtonClicked()
{
mainLineEdit->setText( "0" );
expandLineEdit->setText( "" );
item = "0";
mathString = "";
}

//slot to clean current expression

void CalculatorWin::setRealMode() //slot to switch real mode with imag mode


{
if( realRadioButton->isChecked() )
{
complexButton->setEnabled( false );
isRealMode = true;
item = "0";
mainLineEdit->setText( "0" );
}
else
{
complexButton->setEnabled( true );
isRealMode = false;
item = "0";
mainLineEdit->setText( "0" );
}
}
void CalculatorWin::backButtonClicked()
{
mainLineEdit->backspace();
item = mainLineEdit->text();
if( item.isEmpty() )
{
item = "0";
mainLineEdit->setText( item );
}
}

Trang 95

void CalculatorWin::addButtonClicked()
{
item = mainLineEdit->text();
if( ( !mathString.isEmpty() ) && ( mathString.at( mathString.length() - 1 ) == ')' ) )
{
mathString = mathString + "+";
item = "0";
expandLineEdit->setText( mathString );
}
else
{
if( isRealMode )
{
mathString = mathString + item + "+";
item = "0";
expandLineEdit->setText( mathString );
}
else
{
if( !item.contains( "+" ) )
{
if( !item.contains( "-" ) )
{
item = item + "+";
mainLineEdit->setText( item );
}
else if( ( ( item.count( "-" ) ) == 1 ) && ( item.at(0) == '-' ) )
{
item = item + "+";
mainLineEdit->setText( item );
}
else
{
mathString = mathString + "(" + item + ")" + "+";
item = "0";
expandLineEdit->setText( mathString );
}
}
else
{
mathString = mathString + "(" + item + ")" + "+";
item = "0";
expandLineEdit->setText( mathString );
}
}

Trang 96

}
}
void CalculatorWin::subButtonClicked()
{
item = mainLineEdit->text();
if( ( !mathString.isEmpty() ) && ( mathString.at( mathString.length() - 1 ) == ')' ) )
{
mathString = mathString + "-";
item = "0";
expandLineEdit->setText( mathString );
}
else
{
if( isRealMode )
{
mathString = mathString + item + "-";
item = "0";
expandLineEdit->setText( mathString );
}
else
{
if( ( ( !item.contains( "-" ) ) || ( ( item.at(0) == '-' ) && ( item.count( "-" ) ) == 1 ) )
&& ( !item.contains( "+" ) ) )
{
item = item + "-";
mainLineEdit->setText( item );
}
else
{
mathString = mathString + "(" + item + ")" + "-";
item = "0";
expandLineEdit->setText( mathString );
}
}
}
}
void CalculatorWin::signButtonClicked()
{
item = mainLineEdit->text();
if( item != "0" )
{
if( item.at(0) != '-' ) //insert a '+' before the begin of string
item.insert( 0, "+" );
//exchange '+' with '-'

Trang 97

item.replace( "+", "a" );


item.replace( "-", "s" );
item.replace( "a", "-" );
item.replace( "s", "+" );
if( item.at(0) == '+' ) //delete '+' before the begin of string
item.remove( 0, 1 );
mainLineEdit->setText( item );
}
}
void CalculatorWin::mulButtonClicked()
{
item = mainLineEdit->text();
if( ( !mathString.isEmpty() ) && ( mathString.at( mathString.length() - 1 ) == ')' ) )
{
mathString = mathString + "*";
item = "0";
expandLineEdit->setText( mathString );
}
else
{
if( !isRealMode )
{
if( item.at( item.length() - 1 ) == '+' || item.at( item.length() - 1 ) == '-' )
item.remove( item.length() - 1, 1 );
mathString = mathString + "(" + item + ")" + "*";
item = "0";
expandLineEdit->setText( mathString );
}
else
{
mathString = mathString + item + "*";
item = "0";
expandLineEdit->setText( mathString );
}
}
}
void CalculatorWin::divButtonClicked()
{
item = mainLineEdit->text();
if( ( !mathString.isEmpty() ) && ( mathString.at( mathString.length() - 1 ) == ')' ) )
{
mathString = mathString + "/";
item = "0";
expandLineEdit->setText( mathString );

Trang 98

}
else
{
if( !isRealMode )
{
if( item.at( item.length() - 1 ) == '+' || item.at( item.length() - 1 ) == '-' )
item.remove( item.length() - 1, 1 );
mathString = mathString + "(" + item + ")" + "/";
item = "0";
expandLineEdit->setText( mathString );
}
else
{
mathString = mathString + item + "/";
item = "0";
expandLineEdit->setText( mathString );
}
}
}
void CalculatorWin::frontBracketButtonClicked()
{
if( !mathString.isEmpty() )
{
if( mathString.at( mathString.length() - 1 ) == '+' || mathString.at( mathString.length() 1 ) == '-' || mathString.at( mathString.length() - 1 ) == '*' || mathString.at(
mathString.length() - 1 ) == '/' )
{
mathString = mathString + "(";
expandLineEdit->setText( mathString );
}
}
else
{
mathString = mathString + "(";
expandLineEdit->setText( mathString );
}
}
void CalculatorWin::backBracketButtonClicked()
{
item = mainLineEdit->text();
if( mathString.count( "(" ) - mathString.count( ")" ) ) //check the number of bracket
{
if( mathString.at( mathString.length() - 1 ) != ')' )
{

Trang 99

if( !isRealMode )
{
mathString = mathString + "(" + item + ")" + ")";
item = "0";
expandLineEdit->setText( mathString );
}
else
{
mathString = mathString + item + ")";
item = "0";
expandLineEdit->setText( mathString );
}
}
else
{
mathString = mathString + ")";
expandLineEdit->setText( mathString );
}
}
}
void CalculatorWin::equalButtonClicked()
{
item = mainLineEdit->text();
if( mathString == "" )
{
mathString = item;
expandLineEdit->setText( mathString );
*engine = mathString; //transfer the expression to engine
result = engine->calculate(); //calculate the expression and return the result
}
else if( ( mathString.at( mathString.length() - 1 ) == ')' ) || ( ( mathString.at(
mathString.length() - 1 ) >= '0' ) && ( mathString.at( mathString.length() - 1 ) <= '9' ) ) )
{
correctError(); //correct the errors in expression
*engine = mathString; //transfer the expression to engine
result = engine->calculate(); //calculate the expression and return the result
}
else
{
if( !isRealMode )
{
mathString = mathString + "(" + item + ")";
item = "0";
expandLineEdit->setText( mathString );
correctError(); //correct the errors in expression

Trang 100

*engine = mathString; //transfer the expression to engine


result = engine->calculate(); //calculate the expression and return the result
}
else
{
mathString = mathString + item;
item = "0";
expandLineEdit->setText( mathString );
correctError(); //correct the errors in expression
*engine = mathString; //transfer the expression to engine
result = engine->calculate(); //calculate the expression and return the result
}
}
if( !engine->isError() ) //if no errors in result, display result
{
displayResult();
mathStack1.push( mathString ); //save current expression in stack
mathString = ""; //clear current expression
}
else
{
mainLineEdit->setText( engine->getMassage() ); //display error massage
mathString = ""; //clear current expression
}
}
void CalculatorWin::displayResult() //function to display the result
{
QString real;
QString imag;
QString resultStr;
if( result.isZero() )
{
resultStr = "0";
}
if( result.getReal() != 0.0 )
{
real = real.number( result.getReal(), 'g', 3 );
resultStr = resultStr + real;
}
if( result.getImag() != 0.0 )
{
imag = imag.number( result.getImag(), 'g', 3 );
if( imag.at( 0 ) == '-' )
resultStr = resultStr + imag + "i";

Trang 101

else
resultStr = resultStr + "+" + imag + "i";
}
mainLineEdit->setText( resultStr );
}
void CalculatorWin::correctError() //function to correct the errors in input string
{
mathString.replace( "+-", "-" );
mathString.replace( "+i", "+1i" );
mathString.replace( "-i", "-1i" );
mathString.replace( "(i", "(1i" );
}
void CalculatorWin::upButtonClicked() //slot to load the last expression
{
if( !mathStack1.isEmpty() )
{
mainLineEdit->setText( "0" );
item = "0";
mathString = mathStack1.top();
mathStack1.pop();
mathStack2.push( mathString );
expandLineEdit->setText( mathString );
}
}
void CalculatorWin::downButtonClicked() //slot to load the next expression
{
if( !mathStack2.isEmpty() )
{
mainLineEdit->setText( "0" );
item = "0";
mathString = mathStack2.top();
mathStack2.pop();
mathStack1.push( mathString );
expandLineEdit->setText( mathString );
}
}
void CalculatorWin::clsHistoryButtonClicked()
history of expression
{
mainLineEdit->setText( "0" );
expandLineEdit->setText( "" );
item = "0";

Trang 102

//slot to clear current expression and the

mathString = "";
while( !mathStack1.isEmpty() )
mathStack1.pop();
while( !mathStack2.isEmpty() )
mathStack2.pop();
}
void CalculatorWin::setUpOrDownButtonEnbled() //slot to set up or down button enbled
{
if( mathStack1.isEmpty() )
{
upButton->setEnabled( false );
}
else
{
upButton->setEnabled( true );
}
if( mathStack2.isEmpty() )
{
downButton->setEnabled( false );
}
else
{
downButton->setEnabled( true );
}
}
void CalculatorWin::keyPressEvent( QKeyEvent *event )
event
{
switch( event->key() )
{
case Qt::Key_0:
zeroButton->click();
break;
case Qt::Key_1:
oneButton->click();
break;
case Qt::Key_2:
twoButton->click();
break;
case Qt::Key_3:
threeButton->click();
break;
case Qt::Key_4:
fourButton->click();

Trang 103

//function to response keyboard

break;
case Qt::Key_5:
fiveButton->click();
break;
case Qt::Key_6:
sixButton->click();
break;
case Qt::Key_7:
sevenButton->click();
break;
case Qt::Key_8:
eightButton->click();
break;
case Qt::Key_9:
nineButton->click();
break;
case Qt::Key_Period:
dotButton->click();
break;
case Qt::Key_Plus:
addButton->click();
break;
case Qt::Key_Minus:
subButton->click();
break;
case Qt::Key_Asterisk:
mulButton->click();
break;
case Qt::Key_Slash:
divButton->click();
break;
case Qt::Key_I:
complexButton->click();
break;
case Qt::Key_Equal:
equalButton->click();
break;
case Qt::Key_Enter:
case Qt::Key_Return:
equalButton->click();
break;
case Qt::Key_Control:
if( isRealMode )
complexRadioButton->click();
else
realRadioButton->click();

Trang 104

break;
case Qt::Key_C:
clsHistoryButton->click();
break;
case Qt::Key_Delete:
clearButton->click();
break;
case Qt::Key_Backspace:
backButton->click();
break;
case Qt::Key_ParenLeft:
frontBracketButton->click();
break;
case Qt::Key_ParenRight:
backBracketButton->click();
break;
case Qt::Key_PageUp:
upButton->click();
break;
case Qt::Key_PageDown:
downButton->click();
break;
default:
break;
}
}
+ Comlex.cpp
#include"complex.h"
Complex::Complex( double realNum, double imagNum )
:real ( realNum ), imag ( imagNum )
{
//the body of funtion is empty
}
const Complex Complex::operator + ( const Complex &right ) //overloading operator '+'
{
Complex result;
result.real = this->real + right.real;
result.imag = this->imag + right.imag;
return ( result );
}
const Complex Complex::operator - ( const Complex &right ) //overloading operator '-'
{
Complex result;

Trang 105

result.real = this->real - right.real;


result.imag = this->imag - right.imag;
return ( result );
}
const Complex Complex::operator * ( const Complex &right ) //overloading operator '*'
{
Complex result;
result.real = this->real * right.real - this->imag * right.imag;
result.imag = this->real * right.imag + this->imag * right.real;
return ( result );
}
const Complex Complex::operator / ( const Complex &right ) //overloading operator '/'
{
Complex result;
result.real = ( this->real * right.real + this->imag * right.imag ) / ( right.real * right.real
+ right.imag * right.imag );
result.imag = ( this->imag * right.real - this->real * right.imag ) / ( right.real * right.real
+ right.imag * right.imag );
return ( result );
}
const Complex &Complex::operator = ( const Complex &right ) //overloading operator '=',
achieve a complex assignment to a complex
{
this->real = right.real;
this->imag = right.imag;
return ( *this );
}
const Complex &Complex::operator = ( const QString &right ) //overloading operator '=',
achieve a string assignment to a complex
{
QChar ch;
QString partOfRight;
QString rightStr;
int size = right.size();
int indexOfi = 0;
bool isReal = true;
rightStr = right;
for( int i = 0; i < size; i++ )
{
ch = rightStr.at(i);

Trang 106

if( ch == 'i' )
{
isReal = false;
indexOfi = i;
}
}
if( isReal )
{
this->real = rightStr.toDouble();
this->imag = 0.0;
}
else
{
for( int i = indexOfi - 1; i >= 0; i-- )
{
ch = rightStr.at(i);
if( ( ch == '+' ) || ( ch == '-' ) )
{
partOfRight = rightStr.mid( i, indexOfi - i );
rightStr.remove( i, indexOfi - i + 1 );
break;
}
}
if( partOfRight.isEmpty() )
{
partOfRight = rightStr.mid( 0, indexOfi );
rightStr.remove( 0, indexOfi + 1 );
}
this->imag = partOfRight.toDouble();
if( !rightStr.isEmpty() )
this->real = rightStr.toDouble();
else
this->real = 0.0;
}
return( *this );
}
bool Complex::isZero() //determine whether the number is zero
{
if( ( this->real == 0.0 ) && ( this->imag == 0.0 ) )
return true;
else
return false;

Trang 107

}
double Complex::getReal() //get the real part of complex
{
return ( real );
}
double Complex::getImag() //get the imag part of complex
{
return ( imag );
}

Trang 108

Chng 8
LP TRNH DRIVER
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 3-2.
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:

Trang 109

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
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 thc 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.

Hnh 3-2- S cu trc h thng nhng


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

Trang 110

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.
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 thng thng

Trang 111

khng nm trn chnh h thng . Ngc li thng 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
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 t 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

Trang 112

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.
Mt chng trnh Application ang thc thi nu pht sinh mt li th khng cn hot
ng 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

Trang 113

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.

Trang 114

BI 2

PHN LOI V NHN DNG DRIVER


TRONG LINUX
I.

Tng quan v Device Driver:

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 u 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 u 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.

Trang 115

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;
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-rw-

1 root

root

1,

3 Apr 11

2002 null

crw-------

1 root

root

10,

1 Apr 11

2002 psaux

crw-------

1 root

root

4,

crw-rw-rw-

1 root

tty

4,

64 Apr 11

2002 ttys0

crw-rw----

1 root

uucp

4,

65 Apr 11

2002 ttyS1

crw--w----

1 vcsa

tty

7,

1 Apr 11

crw--w----

1 vcsa

tty

7, 129 Apr 11

2002 vcsa1

crw-rw-rw-

1 root

root

1,

2002 zero

1 Oct 28 03:04 tty1

5 Apr 11

2002 vcs1

Ct th nht cho chng ta thng tin v loi device driver. Theo thng tin trn th tt c
u 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 u
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.

Trang 116

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 2 12*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);
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.

Trang 117

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 u 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 u 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,

Trang 118

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 u 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

Trang 119

bi trc. Chng ta cng bit nhng hm rt quan trng thao tc vi s nh danh


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.
1. 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 ch 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 t 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

Trang 120

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.
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);
}

2. 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;

Trang 121

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;
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) {

Trang 122

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

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


result

register_chrdev_region

(dev,

lcd_nr_devs,

"lcd_dev");
} else {

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


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

/*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

Trang 123

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 u 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
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 l 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.

Trang 124

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 ch d liu trong thit b cn ghi thng tin,
nu 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

Trang 125

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*/


.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

Trang 126

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 th
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 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.

Trang 127

struct dentry *f_dentry;

Cha thng tin v tp tin ngun c m, mi tp tin c m trong h thng linux


u 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.
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:

Trang 128

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.
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;

Trang 129

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.

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.
VII.

Trang 130

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();

Trang 131

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 u 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 u c nhng tham s tng t nhau. V
th chng ta s nghin cu hai hm ny cng lc.
1. Cu trc lnh:

Trang 132

ssize_t

read(struct

file

*filp,

char

__user

*buff,

size_t

__user

*buff,

count, loff_t *offp);


ssize_t

write(struct

file

*filp,

const

char

size_t count, loff_t *offp);

2. 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(...)
u l nhng con tr 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 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 tr n vng nh trong kernel space

Trang 133

lu d liu chp t user space; const void __user *from l con tr tr cha d liu
trong user space mun chp qua kernel space; unsigned long count l s bytes d
liu mun chp.
Hai hm u 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
, 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 3-3:

dev_write

write()
copy_from_user()

Hnh 3-3- Nguyn tc hot ng ca giao din hm read() v write()


read()

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

Trang 134

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.
1. 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);

2. 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 a vo s dng ty theo yu cu trong thc t. Sau y chng ta s tm hiu
cc tham s trong hm ioctl.
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
u cha trong s m t tp tin (file descriptor) gi tt l fd, c tr v khi thc hin m

Trang 135

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:
/*nh ngha s magic cho s nh danh lnh l B trong bng m ascii l 66 thp
phn*/

Trang 136

/*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

_IO(IOC_GPIODEV_MAGIC, 10)

#define GPIO_SET

_IO(IOC_GPIODEV_MAGIC, 11)

#define GPIO_CLEAR

_IO(IOC_GPIODEV_MAGIC, 12)

#define GPIO_DIR_IN

_IO(IOC_GPIODEV_MAGIC, 13)

#define GPIO_DIR_OUT

_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.

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

ngha.
-

<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;

Trang 137

static int
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;
}

Trang 138

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
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.

Trang 139

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;

Trang 140

Lp trnh driver theo nhng yu cu c lp;


Lp trnh application s dng driver hon tt chng trnh iu khin;
Chy kim tra tin cy h thng;
Giao cho khch hng s dng, bo tr sa 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 u 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, character driver 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.

Trang 141

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.
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;
1. 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> //Th vin th nht trong th mc linux
#include <linux/fs.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
......

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


#define ...
...

Trang 142

/*Bc 3: Khai bo s nh danh thit b (Device number); Cu trc (file structure);


Cu trc (file operations); */
int

device_devno; //Khai bo bin lu s nh danh thit b

struct cdev

device_cdev; //Khai bo bin lu cu trc tp tin

struct file_operations

device_fops; //Khai bo bin lu cu trc

lnh
/*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

trong
unsigned long variable_1;//m lnh C, v C++
struct clk *device_clock_0;//
....

/*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;

Trang 143

/*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 ch 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 n a ch bin lu s nh danh u tin tm c;
ret = alloc_chrdev_region ( &device_devno
0,

//S Minor u tin yu cu;

1,

//S thit b yu cu;

device_name );//Tn thit b mun ng 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

Device_name: Device number

allocate fail);
ret = -ENODEV; //Tr v m li cho bin ret;
return ret; //Tr v m li cho hm init;
}

/*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;*/

Trang 144

cdev_init ( &device_cdev,

//Tr n cu trc tp tin c nh

ngha;
device_devno,

//S nh danh thit b c xc nh;

1 );

//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*/


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;
}

Trang 145

/*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");
}

/*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*/

Trang 146

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*/
...
}

/*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*/

Trang 147

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

= device_read,

.write

= device_write,

.ioctl

= device_ioctl,

.open
.release

= device_open,
= device_release,

};

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


module_init (device_init); /*Hm device_init() thc hin khi driver c

ci t*/
module_exit (device_exit); /*Hm device_exit() thc hin khi driver

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

Trang 148

MODULE_AUTHOR("Tn ngi vit driver");


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

2. 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
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;

Trang 149

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 u 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

":

already in use\n", dev_minor);

/*Tr v m li bn*/

Trang 150

Device

with

minor

ID

%d

return -EBUSY;
}

/*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) {

/*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*/

Trang 151

file

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*/


.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);

Trang 152

/*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:

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:

Trang 153

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-...*/


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.

Trang 154

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 u 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;

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 dng 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 ch cp 2 cch cn bn lm nn tng cho
cc bn nghin cu thm nhng cch khc hiu qu hn ngoi thc t.

Trang 155

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.

Trang 156

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 user application. 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 u 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

Trang 157

th hiu nguyn l hot ng ca tng hm s dng p dng vo trng hp khc.


Driver v Application u c nhim v ring, ty vo tng giao din s dng m yu cu
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.
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.
2. Application:

Trang 158

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:
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;

Trang 159

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 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:

1. Chng trnh driver: Chng trnh driver mang tn helloworld_dev.c


(M lnh v gii thch chng trnh driver cha trong CD nh km)
2. Chng

trnh

application:

Chng

trnh

application

mang

tn

helloworld_app.c
(M lnh v gii thch chng trnh application cha trong CD nh km)
3. Thc thi chng trnh:
Cc bc bin dch v kt qu thc thi d n cha trong CD nh km
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

Trang 160

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
qua cc cng vo ra, trong bi sau chng ta s nghin cu cc hm giao tip gpio do linux
h tr sn.

Trang 161

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 u 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 u 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.

Trang 162

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

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

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

Trang 163

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);

/*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*/

Trang 164

...

/*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);

/*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 y 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);

Trang 165

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);

/*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

Trang 166

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():
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);

Trang 167

...
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*/


...

Trang 168

8. Hm gpio_to_irq():
C php ca hm ny nh sau:
#include <linux/gpio.h>
int gpio_to_irq (unsigned gpio);

i khi chng ta mun ci t ch 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

Trang 169

(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);

/*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.

Trang 170

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.

Trang 171

BI 8

THAO TC THI GIAN TRONG KERNEL


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 u


rt quan trng. Trong h iu hnh, nhng hot ng u 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

Trang 172

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
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.

Trang 173

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?
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 tc vi jiffies, kernel h tr cho chng ta cc hm so snh thi gian sau, tt
c cc hm ny u c nh ngha trong th vin linux/jiffies.h:

Trang 174

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)

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

Trang 175

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.
1. Cc kiu, cu trc thi gian:
a. Cu trc timespec: cu trc ny c nh ngha nh sau:
struct timespec {
__kernel_time_t
long

tv_sec;

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

tv_sec;

__kernel_suseconds_t

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 {

Trang 176

int

tz_minuteswest;

int

tz_dsttime;

/* minutes west of Greenwich */

/* 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;
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:

Trang 177

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;
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

time_t sec, long nsec);

Trang 178

timespec

*ts,

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 dng 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)


{
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

Trang 179

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);

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,

Trang 180

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);

Trang 181

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.
V.

Timer v ngt dng 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

linux

kernel

<linux/timer.h> nh sau:
struct timer_list {
struct list_head entry;
unsigned long expires;
void (*function) (unsigned long);
unsigned long data;

Trang 182

nh

ngha

trong

th

vin

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;

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:

Trang 183

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.
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 chu
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*/

Trang 184

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++);

/*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

Trang 185

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:
/*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.

Trang 186

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;
**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.

Trang 187

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 thc t hn v lp trnh h thng nhng.

Trang 188

GIAO TIP IU KHIN


LED N
Bi 1: iu khin LED n trn kit KM9260
a. Kt ni phn cng:
Thc hin kt ni phn cng theo s sau trn board SAM9260-EK iu khin led
ni vi chn PB20, PB21, PB22, PB23
b. Chng trnh driver: C tn 1_1_single_led_dev.c
(M ngun v gii thch chng trnh driver c cha trong CD nh km)
c. Chng trnh application: C tn 1_1_single_led_app.c
(M ngun v gii thch chng trnh application cha trong CD nh km)
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 += 1_1_single_led_dev.o
all:

/*Lu phi ng ng 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

to

thnh

vi

tn

1_1_single_led_dev.ko

Bin dich application: Bng lnh shell sau:


./arm-none-linux-gnueabi-gcc
1_1_single_led_app

Trang 189

1_1_single_led_app.c

**Chng trnh c bin dch c tn l 1_1_single_led_app


Thc thi chng trnh:
Chp driver v application vo kit;
Ci t driver bng lnh: insmod 1_1_single_led_dev.ko
Thay i quyn thc thi cho chng trnh application bng lnh:
chmod 777 1_1_single_led_app

Chy chng trnh v quan st kt qu:


Khai bo chn PC0 l ng ra:
./1_1_single_led_app dirout 96
Using gpio pin 96

(Lc ny led kt ni vi PC0 tt)


Xut d liu mc cao cho PC0:
./1_1_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:
./1_1_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:
./1_1_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
./1_1_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
./1_1_single_led_app get 55

Trang 190

Using gpio pin 55


Pin 55 is HIGH

Bi 2:
IU 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 u 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.

Trang 191

Tip theo, nu l ch 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 1_1_single_led_dev.c
S dng k thut giao din ioctl nhn lnh v tham s t user application thc thi
iu 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 1_1_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 1_1_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;

Trang 192

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:

e. Kt ni phn cng:
Thc hin kt ni phn cng theo s sau:
VCC

U1
PC0

9
8
7
6
5
4
3
2

VCC

1
19

A8
A7
A6
A5
A4
A3
A2
A1

R1
B8
B7
B6
B5
B4
B3
B2
B1

11
12
13
14
15
16
17
18

DIR
G
74HC245

R1
330

D1

R1
330

D3
LED
D4
LED
D5
LED
D6
LED
D7
LED
D8
LED

330

LED

R1
330
R1
330
R1
330
R1
330
R1
330

R2
4k7

D2

LED

R2
4k7

PA23
PB10

SW1

Hnh 4-1- S kt ni LED n v cng tc iu khin


f. Chng trnh driver: C tn 1_1_single_led_dev.c
(M ngun v gii thch chng trnh driver c cha trong CD nh km)
g. Chng trnh application: C tn 1_1_single_led_app.c
(M ngun v gii thch chng trnh application cha trong CD nh km)
h. 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 += 1_1_single_led_dev.o
all:

Trang 193

/*Lu phi ng ng 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

to

thnh

vi

tn

1_1_single_led_dev.ko

Bin dich application: Bng lnh shell sau:


./arm-none-linux-gnueabi-gcc

1_1_single_led_app.c

1_1_single_led_app

**Chng trnh c bin dch c tn l 1_1_single_led_app


Thc thi chng trnh:
Chp driver v application vo kit;
Ci t driver bng lnh: insmod 1_1_single_led_dev.ko
Thay i quyn thc thi cho chng trnh application bng lnh:
chmod 777 1_1_single_led_app

Chy chng trnh v quan st kt qu:


Khai bo chn PC0 l ng ra:
./1_1_single_led_app dirout 96
Using gpio pin 96

(Lc ny led kt ni vi PC0 tt)


Xut d liu mc cao cho PC0:
./1_1_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:
./1_1_single_led_app set 96 0
Using gpio pin 96

Trang 194

(Lc ny ta thy led ni vi chn PC0 tt xung)


Khai bo chn PA23 l ng vo:
./1_1_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
./1_1_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
./1_1_single_led_app get 55
Using gpio pin 55
Pin 55 is HIGH

**Tng t cho cc chn gpio khc;

Trang 195

Bi 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 iu 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 u 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;

Trang 196

Lu iu khin nh sau:

Hnh 4-2- Lu iu khin LED sng tt theo s chu k c quy nh


b. Phn cng nhim v:
Driver: C tn l 1_2_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 1_2_port_led_app.c

Trang 197

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:


D1

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

B8
B7
B6
B5
B4
B3
B2
B1

11
12
13
14
15
16
17
18

DIR
G
74HC245

R1
R2
330

D2

R8
330

D3
LED
D4
LED
D5
LED
D6
LED
D7
LED
D8
LED

330

LED

R3
330
R4
330
R5
330
R6
330
R7
330

LED

Hnh 4-3- S kt ni 8 LEDs n.


**Lu phi ng s chn quy c.
b. Chng trnh driver: Chng trnh c tn l 1_2_port_led_dev.c
(M ngun v gii thch chng trnh c cha trong CD nh km)
c. Chng trnh application: C tn l 1_2_port_led_app.c
(M ngun v gii thch chng trnh c cha trong CD nh km)
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 += 1_2_port_led_dev.o

Trang 198

all:

/*Lu phi ng ng 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 application:


Tr vo th mc cha tp tin chng trnh, bin dch chng trnh ng dng vi lnh
sau:
arm-none-linux-gnueabi-gcc

1_2_port_led_app.c

1_2_port_led_app

**Chng trnh bin dch thnh cng c tn l: 1_2_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 1_2_port_led_dev.ko

Thay i quyn thc thi cho chng trnh ng dng:


chmod 777 1_2_port_led_app

Thc thi v kim tra kt qu:


./1_2_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.

Trang 199

You might also like