Upload
nntuon
View
131
Download
10
Embed Size (px)
DESCRIPTION
Tim hieu board mini2440 va qua trinh phat trien 1 du an linux nhung qua project bai giu xe thong minh
Citation preview
CHƯƠNG 1: GIỚI THIỆU CHUNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 1
CHƢƠNG 1
GIỚI THIỆU CHUNG
1.1. Giới Thiệu Về Hệ Thống Nhúng (Embedded Systems) Thế giới được đánh giá đang ở giai đoạn hậu PC – internet, giai đoạn
của môi trường thông minh mà hệ thống nhúng (Embedded Systems) là cốt
lõi, đóng góp vào rất nhiều lĩnh vực và đang làm nên làn sóng đổi mới thứ ba
trong sự phát triển của công nghệ thông tin. Vì lý do này nên việc phát triển
các hệ nhúng và phần mềm nhúng là chiến lược trọng tâm về phát triển công
nghiệp của nhiều quốc gia trên thế giới.
Hệ thống nhúng (Embedded Systems) là hệ thống tích hợp cả phần cứng
và phần mềm nhằm phục vụ các bài toán chuyên dụng trong nhiều lĩnh vực
của đời sống. Đặc điểm quan trọng của các hệ thống nhúng là hoạt động ổn
định và tính năng tự động hóa cao. Xu hướng phát triển của các hệ thống
nhúng trên thế giới hiện nay là phần mềm ngày càng chiếm tỷ trọng cao,
ngày càng có nhiều chức năng tiện dụng và thông minh hơn. Các chức năng
này phần lớn do các chương trình nhúng tạo nên. Phần mềm nhúng hiện đang
là một lĩnh vực công nghệ then chốt cho sự phát triển kinh tế của nhiều quốc
gia trên thế giới như Mỹ, Nhật Bản, Hàn Quốc, Phần Lan, Trung Quốc…
Những quốc gia này đều đã thành lập nhiều viện nghiên cứu và trung tâm
phát triển các hệ thống nhúng.
Ngày nay, khi mà những phần mềm nhúng đang trở nên phức tạp hơn
thì việc phát triển các sản phẩm phần mềm nhúng đơn lẻ đã không còn phù
hợp. Để hiện thực được những ứng dụng nhúng phức tạp như vậy phải cần
đến các hệ điều hành nhúng nhỏ gọn có khả năng hỗ trợ tốt cho việc phát
triển các phần mềm nhúng. Các hệ điều hành dùng trong các hệ nhúng nổi
trội hiện nay bao gồm Embedded Linux, VxWorks, Windows CE, Lynyos,
BSD, Green Hills, QNX và DOS. Với nhiều lợi thế, Embedded Linux hiện
nay đang phát triển rất mạnh trên thế giới và chiếm vị trí số 1 trong số các hệ
điều hành nhúng.
Một số sản phẩm nhúng tiêu biểu
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 1: GIỚI THIỆU CHUNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 2
Hình 1.1 Iphone4 (chạy iOS 4) Hình 1.2 HTC Evo 4G (chạy Android)
1.2. Mục Tiêu Luận Văn Và Phƣơng Pháp Thực Hiện 1.2.1. Mục Tiêu
Mục tiêu của luận văn được chia làm 2 phần cơ bản:
Nhiệm vụ chính: Cài đặt và sử dụng hệ điều hành Embedded
Linux trên board mini2440, xây dựng cách viết các driver modules và ứng
dụng chạy trên hệ điều hành.
Nhiệm vụ còn lại: Thiết kế mô hình của quản lí bãi giữ xe trong
đó việc kết hợp giao diện người dùng và phần điều khiển trên cùng một board
làm cho hệ thống đơn giản và thuận tiện hơn. Điều này là minh chứng cho sự
thành công trong việc sử dụng board mini 2440 và xây dựng ứng dụng trên
hệ điều hành nhúng.
1.2.2. Phƣơng Pháp Thực Hiện
Vì tính chất mới của đề tài nên luận văn được thực hiện theo phương
pháp chia từng giai đoạn nhỏ. Mỗi giai đoạn đều được lên kế hoạch với các
mục tiêu, thời gian và người thực hiện cụ thể.
Ví Dụ: - cách chia giai đoạn Giai đoạn Thời gian Khối lượng
1 9 tuần ( 06/09/2010 – 08/11/2010) 40%
2 9 tuần (09/11/2010 - 01/01/2011) 60 %
- Bảng phân công công việc
Công việc Dự kiến Thực tế Người thực hiện
… …. …. …..
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 1: GIỚI THIỆU CHUNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 3
1.3. Sơ Lƣợc Về Nội Dung Luận Văn Luận văn bao gồm 9 chương và 1 phần phụ lục
Chương 1: Giới thiệu về đặc điểm, tầm quan trọng cũng như xu
hướng phát triển của hệ thống nhúng trong tương lai. Đồng thời nêu lên mục
tiêu và phương pháp thực hiện luận văn.
PHẦN A: Board Mini 2440 Và Hệ Điều Hành Embeded Linux
Chương 2: Tổng quan chung về phần cứng board Mini2440 từ
processor, memory đến các module khác nhau: USB, ethernet, wifi, camera,
audio, ADC, SD card, GPIO, PWM,…Ngoài ra, tìm hiểu chức năng các
thanh ghi của vi điều khiển S3C2440A phục vụ cho mục đích viết driver bao
gồm: module GPIO, Interrupt controller, timer & PWM.
Chương 3: Tổng quan về định nghĩa và tầm phát triển của hệ
điều hành nhúng. Trong đó đi sâu vào đặc điểm nổi bật của hệ điều hành
BUSY BOX và cách nhúng nó xuống board cũng như việc giao tiếp giữa
board và PC. Cuối cùng, trình bày các công cụ cần thiết nhất cho lập trình hệ
thống nhúng: Operating System, Tool Chain, IDE ( Integrated Development
Environment), …
Chương 4: Giới thiệu Qt như một công cụ lập trình giao diện và
ứng dụng, cách xây dựng một chương trình trong Qt và cách build chương
trình cho tương thích với board mini2440. Các ví dụ được đi kèm nhằm làm
rõ hơn cách viết ứng dụng với Qt.
Chương 5: Device Drivers. Nội dung của chương đề cập tới vai
trò, đặc tính, phân loại driver khác nhau trong nhân Linux kernel. Các thành
phần, tác vụ của một module driver và cách viết một module character driver
hoàn chỉnh cũng như các ví dụ minh họa. Thêm vào đó, cách build và chạy
một loadable driver trong nhân kernel.
PHẦN B: Mô Hình Quản Lí Bãi Giữ Xe Sử Dụng Mini 2440
Chương 6: Trình bày chi tiết phần cứng và nguyên lí hoạt động
của bãi giữ xe.
Chương 7: Đề cập tới cấu trúc chương trình bao gồm 2 phần:
module driver (camera, motor) & giao diện điều khiển người dùng (GUI).
Chương 8: Giới thiệu về những nghiên cứu trong việc nhận dạng
biển số xe và hướng áp dụng vào hệ thống bãi giữ xe hiện tại. Ngoài ra,
chương này cũng trình bày cách build thư viện xử lí ảnh openCV và những lí
do không tương thích.
PHẦN C: Kết luận
Chương 9: Tóm tắt và rút ra kết luận chung về đề tài đồng thời
nêu lên những hướng phát triển tiếp theo trong tương lai.
Tài liệu tham khảo
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 4
CHƢƠNG 2
BOARD FRIENDLY ARM MINI2440
2.1. Giới Thiệu Board Mini2440 2.1.1. Giới Thiệu Chung
Friendly ARM Mini2440 là board phát triển dựa trên dòng vi điều
khiển Samsung S3C2440A. Với kích thước 100x100 (mm), board bao gồm
lõi CPU nguồn source chip và reset chip để đảm bảo sự ổn định hoạt động
của hệ thống.
PCB board được thiết kế với 4 lớp theo công nghệ ENIG và được
sản xuất theo điều kiện nghiêm ngặt.
Ngoài ra, board được trang bị với nhiều loại kết nối (connectors),
giao tiếp (interfaces) và các cổng (ports).Tất cả nhằm cung cấp cho người sử
dụng một công cụ hoàn thiện để nghiên cứu và ứng dụng vào điều khiển.
Hình ảnh thực tế của Friendly ARM Mini2440:
Hình 2.1: Board Friendly ARM Mini2440 thưc tế
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 5
2.1.2. Đặc Tính Chung
Items Chi tiết
Kích thước 100 x 100mm
Processor Samsung S3C2440 (ARM920T), tần số hoạt động
400MHz và tối đa 533MHz
Memory SDRAM:
* 64MB SDRAM onboard
* 32 bit data bus
* Clock frequency: up to 100MHz
Flash Memory:
* 64M Nand Flash on board
* 2M Nor Flash on board with preinstalled BIOS
LCD Model number: NL2432HC22 – 23B
Company: NEC
Panel Type: TFT
LCD Size: 8.90cm 3.5’’
Resolution: 320x 240 RGB
Contrast: 10:1
Touch Panel 4-wires Resistive touch panel
Ethernet 10/100 Mbps ( DM9000 network chip)
Touch ADC Touch ADC: 1 biến trở điều chỉnh (adjustable resistance)
USB Port 1 host và 1 slave
SD card 1 slot giao tiếp SD card chuẩn
Audio 1 stereo audio output
1 MIC interface
RTC Battery on board
JTAG 1 2.0mm 10 pin JTAG interface
LEDs 4 user leds
Keypad 6 user buttons
Buzzer 1 PWM control buzzer
Camera 1 20pin Camera Interface (2.0 mm)
Expansion
Interfaces One 34pin 2.0 mm GPIO
One 40pin 2.0 mm system bus
System Clock
Source
Tần số thạch anh: 12MHz
Nguồn cấp 5V với switch tắt bật nguồn
OS Support Linux 2.6
Window CE 5.0
Hình 2.2. Bảng đặc tính chung của board
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 6
2.1.3. Phần Cứng * Jumpers
Switch (S1): Power On/ Off
Switch (RST): Reset Board
Switch (S2) : Select boot mode ( Nor Flash hoặc Nand Flash)
Jumper (J2): chọn mức volt cho LCD driver board (3.3V hoặc 5V)
Hình ảnh các module trên board:
Hình 2.3: Các module trên board
* Memory Map
S3C2440 cho phép 2 chế độ boot:
Boot từ Nand Flash
Boot từ Nor Flash
Việc cấp phát bộ nhớ tùy thuộc vào chế độ boot.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 7
Hình 2.4: Memory address allocation
(Left: Nor Flash & Right: Nand Flash)
Tùy thuộc vào chế độ Boot khác nhau mà vùng lựa chọn chip nGCS0 sẽ được
ánh xạ không giống nhau khi vào chế độ start-up mode.
Nor Flash Boot: Nor Flash mapped to nGCS0 Space
Nand Flash Boot: 4KB Boot SRAM mapped to nGCS0 Space
SDRAM address space: 0x30000 000 – 0x34000 000 * Nguồn Cung Cấp(Power Supply)
Nguồn hệ thống board khá đơn giản và được cung cấp trực tiếp bởi
nguồn 5V bên ngoài thông qua adaptor 5V/2A.
Ngoài ra, các nguồn điện áp khác như: 3.3V, 1.8V và 1.25V được tạo ra
trên board thông qua các mạch ổn áp từ nguồn cấp 5V.
Vì board Mini2440 không được thiết kế đặc biệt cho các thiết bị cầm tay
nên nó không chứa mạch để quản lí nguồn năng lượng cung cấp. Do đó,
mạch cung cấp được điều khiển thông qua switch S1.
Các mạch tạo các mức áp khác trên board:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 8
Hình 2.5: Mạch tạo nguồn 1.8V và 3.3V trên board
Hình 2.6: Mạch tạo nguồn 1.25V trên board
Để thuận tiện hơn cho việc kết nối tới các nguồn cung cấp, socket
CON8 được thiết kế trên board.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 9
Hình 2.7. Các pin trên CON4
* Mạch Reset
Chip Reset MAX 811 được sử dụng để phát hiện tín hiệu reset mức
thấp.
Hình 2.8. Mạch Reset * User LEDs
Thông thường, LED được sử dụng như thiết bị hiển thị thông dụng trên
các board phát triển. Tương tự như vậy, mini 2440 có tất cả 4 leds được nối
tới chân GPIO của CPU và các leds này đều ở tích cực mức thấp.
Bảng sơ đồ chân của Leds:
LED 1 LED 2 LED 3 LED 4
GPIO GPB5 GPB6 GPB7 GPB8
Name in schematic nLED_1 nLED_2 nLED_3 nLED_4
Hình 2.9. Bảng các pin nối tới user leds * User Keys
Mini 2440 có tất cả 6 user keys, được nối ra trực tiếp từ các chân ngắt
của CPU và giữ ở mức thấp. Các chân pin này có thể được sử dụng như
GPIO hoặc các chức năng đặc biệt khác. Để tiện cho người dùng, 6 user keys
được nối tới CON12.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 10
Bảng sơ đồ chân user keys
K1 K2 K3 K4 K5 K6
Related
interrupt
EINT8 EINT11 EINT13 EINT14 EINT15 EINT19
GPIO GPG0 GPG3 GPG5 GPG6 GPG7 GPG11
Hình 2.10. Bảng các pin nối tới buttons
Hình 2.11. Sơ đồ vị trí buttons trên board
* ADC
Trên board có tất cả 4 kênh chuyển đổi ADC và chúng được nối tới
GPIO tại vị trí header CON4. Để thuận tiện hơn cho việc kiểm tra, kênh
AIN0 được nối tới biến trở xoay 10k (W1).
Hình 2.12. Sơ đồ nối chân ADC channel 0
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 11
* PWM Buzzer
Buzzer trên board được sử dụng để kiểm tra tín hiệu PWM tại chân
GPB0.
Hình 2.13. Sơ đồ nối chân PWM Buzzer
* Cổng nối tiếp (Serial Ports)
Vi điều khiển S3C2440 có 3 cổng nối tiếp: UART0, UART1 và UART2
và được nối tới các header CON1, CON 2 và CON3. Ngoài ra, để thuận tiện
cho người dùng, UART0 còn đươc chuyển đổi thành RS232 và nối tới
COM0 (DB9 connector).
Hình 2.14. Sơ đồ chân cổng nối tiếp
* USB Interfaces
Có 2 cổng giao tiếp USB interfaces trên board: USB Host và USB
Device interface.
USB Host được sử dụng giống như giao tiếp USB trên PC. Do đó, nó có
thể được sử dụng để kết nối USB Camera, USB Keyboard, USB mouse,…
Trong khi đó, USB Device được sử dụng cho download chương trình xuống
board.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 12
* LCD Interface
LCD Interface là socket trắng 41pin 0.5mm trên board, chứa tất cả các
tín hiệu điều khiển LCD (clock, enable, line-field scan,…) và tín hiệu dữ liệu
RGB data.
Ngoài ra các pin 37, 38, 39 và 40 được sử dụng là 4 dây giao tiếp màn
hình cảm ứng (touch screen interface).
Jumper J2 sử dụng làm tín hiệu lựa chọn nguồn cung cấp cho LCD bao
gồm cả nguồn 5V và 3.3V
Hình 2.15. Sơ đồ các chân giao tiếp LCD
* CMOS Camera Interface
CMOS camera interface cho phép người dùng sử dụng trực tiếp module
Cmos camera 1.3 Mpixels và được truy xuất thoog qua header CON20 trên
board. * Audio Interface
Audio chip UDA1341 được sử dụng thông qua giao tiếp bus I2S. Hệ
thông audio trên board bao gồm: 2 inputs và 1 output.
Ngõ ra output của hệ thống được nối tới 3.5mm stereo jack và 1 ngõ vào
được nối tới microphone trong khi ngõ vào còn lại tại vị trí CON10. *Ethernet Interface
Giao tiếp Ethernet sử dụng chip Davicom DM9000 và connector RJ45
chứa 2 cuộn dây, do đó người dùng chỉ cần 1 cáp mạng thông thường để kết
nối giữa mini2440 với router hoặc switch. * System Bus Interface
Bus hệ thống trên board tại vị trí CON5 bao gồm 16 dây data (D0-D15),
8 dây địa chỉ (A0-A6, A24) và một số dây điều khiển tín hiệu ( chọn chip,
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 13
R/W, reset,…).Ngoài ra, nó cũng là nguồn cung cấp áp 5V cho các thiết bị
ngoài. * GPIO
GPIO (General Purpose Input Output) viết tắt của giao tiếp xuất nhập
cho mục đích đa dụng.Trên board, 34pin GPIO được nối ra header CON4
Thực ra, CON4 không chỉ bao gồm các GPIO pins mà còn các pin CPU
khác như: AD0-AD3, CLKOUT,...Các chức năng này hoàn toàn có thể thay
đổi bởi việc cài đặt với CPU.
Sơ đồ chân:
Hình 2.16. Các chân của CON4 trên Board
2.2. VI ĐIỀU KHIỂN S3C2440 2.2.1. Giới Thiệu Chung
Ngày 26/4/1985 mẫu sản phẩm ARM đầu tiên được sản xuất tại công
ty kĩ thuật VLSI SanJose, bang California được chuyển tới trung tâm máy
tính Acorn ở Cambridge, Anh Quốc.Nửa thập niên sau đó, ARM được phát
triển nhanh chóng để làm nhân máy tính để bàn của Acorn, nền tảng cho các
máy tính hỗ trợ giáo dục ở Anh. Trong thập niên 1990, dưới sự phát triển của
Acorn Limited, ARM đã thành một thương hiệu đứng đầu thế giới về các ứng
dụng sản phẩm nhúng đòi hỏi tính năng cao, sử dụng năng lượng ít và giá
thành thấp.
Chính nhờ sự nối trội về thị phần đã thúc đẩy ARM liên tục được phát
triển và cho ra nhiều phiên bản mới.Những thành công quan trọng trong việc
phát triển ARM ở thập niên sau này:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 14
Giới thiệu ý tưởng về định dạng các chỉ lệnh được nén lại
(thumb) cho phép tiết kiệm năng lượng và giá thành của các hệ thống nhỏ.
Giới thiệu họ ARM 9, ARM 11, ARM Cotex…
Các ứng dụng hệ thống nhúng trên lõi ARM ngày càng rộng rãi
Hầu hết các nguyên lí của hệ thống trên chip (System on Chip – SoC)
và cách thiết kế bộ xử lí hiện đại được sử dụng trong ARM. ARM còn đưa ra
một số khái niệm mới như “giải nén động các dòng lệnh”.Việc sử dụng 3
trạng thái: nhận lệnh – giải mã – thực thi trong mỗi chu kì máy mang tính
quy phạm để thiết kế các hệ thống xử lí thực. Do đó nhân ARM được sử
dụng rộng rãi trong các hệ thống phức tạp.
SAMSUNG S3C2440A là dòng vi điều khiển 16/32-bit RISC được
thiết kế để cung cấp cho các thiết bị cầm tay và các ứng dụng với yêu cầu
tiêu thụ năng lượng thấp.
Nó được phát triển với lõi ARM920T, 0.13um theo chuẩn CMOS với
thiết kế đơn giản, ổn định, tiêu thụ năng lượng ít và theo cấu trúc bus mới
AMBA (Advanced Micro Controller Bus Architecture).
2.2.2. Đặc Tính Cơ Bản
Cấu trúc (Architecture)
Cấu trúc 16/32-bit RISC với lõi CPU ARM920T và cấu trúc bus
nội AMBA.
Quản lí hệ thống ( System Manager)
Hỗ trợ cả Little/ Big Endian và các chế độ bus nhanh hoặc chế độ
bus không đồng bộ.
Vùng địa chỉ 128MBytes cho mỗi bank với tổng cộng 1GBytes và độ
rộng data bus 8/16/32 bit. Có tất cả 8 bank vùng nhớ được chia ra: 6 bank
vùng nhớ cho ROM, SRAM; 2 bank cho ROM/SRAM/DRAM đồng bộ.
NAND Flash Boot Loader
Hỗ trợ boot từ vùng nhớ Nand flash.
4KB buffer nội cho việc boot.
Xung Clock và quản lí nguồn ( Clock & Power manager)
- On-chip MPLL & UPLL:
UPLL cấp xung clock cho hoạt động của USB host và USB
device; MPLL cấp xung clock cho hoạt động của MCU ở tần số 400MHz.
- Các chế độ năng lượng:
CPU có tất cả 4 chế độ khác nhau
* Normal Mode: chế độ hoạt động bình thường và xung
clock được cung cấp cho CPU cũng như các ngoại vi.Năng lượng tiêu thụ sẽ
ở mức tối đa khi tất cả các ngoại vi đều được bật. Điều này cho phép người
dùng điểu khiển hoạt động của ngoại vi thông qua phần mềm.
* Slow Mode: chế độ không có vòng khóa pha PLL (Phase
Locked Loop).Chế độ Slow mode sử dụng nguồn xung clock bên ngoài trực
tiếp do đó năng lượng tiêu thụ chỉ phụ thuộc vào tần số nguồn bên ngoài.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 15
* Idle Mode: xung clock được cấp cho tất cả các ngoại vi và
không được kết nối tới CPU nhờ đó giảm năng lượng tiêu thụ.Bất kì nguồn
ngắt nào tới CPU cũng đánh thức nó khỏi chế độ Idle Mode.
* Sleep Mode: tắt các nguồn năng lượng nội bao gồm cả
lõi và các ngoại vi.Khi ở chế độ này, CPU có thể đánh thức bởi các ngắt
ngoài EINT hoặc ngắt RTC alarm.
Bộ điều khiển ngắt
Có tất cả 60 nguồn ngắt khác nhau trong đó các nguồn ngắt ngoài
có thể cài đặt ở chế độ ngắt cạnh hoặc ngắt mức với các mức ưu tiên lập trình
được.
Ngoài ra CPU còn hỗ trợ các nguồn ngắt nhanh (Fast Interrupt
Request) cho các yêu cầu tức thời.
Timer & PWM
4 kênh 16-bit Timer trong đó 1 kênh 16-bit chỉ có chức năng đếm
timer (interval timer).
Cho phép lập trình tần số, chu kì và có thể nhận nguồn xung clock
từ bên ngoài.
GPIO (General Purpose Input / Output Ports)
24 chân ngắt ngoài và 130 chân input/output đa dụng khác.
AD Converter
8 kênh chuyển đổi ADC với độ phân giải 10-bit
UART
3 kênh UART với tốc độ baud lập trình được, cho phép truyền
hoặc nhân data 5-bit, 6-bit, 7-bit hoặc 8-bit
Giao tiếp camera (Camera Interface)
Độ phân giải tối đa 4096x4096 pixels và cho phép quay hình
ảnh theo các trục X,Y hay 180.
Định dạng ngõ ra camera: RGB 16/24 bit
Điện áp hoạt động
* Lõi CPU: 1.20V với tần số 300MHz
1.30V với tần số 400MHz
* Bộ nhớ: 1.8V/ 2.5V/ 3.0V/ 3.3V
* Ngoại vi I/O: 3.3V
Tần số hoạt động:
* Max Fclk = 400MHz
* Max Hclk = 136 MHz
* Max Pclk = 68 MHz
Kiến trúc ARM
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 16
Hình 2.17. Kiến trúc S3C2440A
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 17
2.2.3. Ngõ Vào Ra Mục Đích Chung GPIO * Đặc Điểm Chung
S3C2440A có tất cả 130 pin I/O và được chia làm 8 ports:
* Port A: 25-output port
* Port B: 11-input/ output port
* Port C: 16-input/ output port
* Port D: 16-input/ output port
* Port E: 16-input/ output port
* Port F: 8-input/ output port
* Port G: 16-input/ output port
* Port H: 9-input/ output port
* Port J: 13-input/ output
Vì mỗi chân pin có nhiều chức năng khác nhau do đó người dùng nên
định nghĩa chức năng của mỗi chân trước khi bắt đầu chương trình chính.
Ví dụ:
Port F bao gồm 8 pins, mỗi pin, ngoài chức năng input/ output
thông thường, còn đươc sử dụng như các nguồn ngắt ngoài.
Hình 2.18. Các chân của Port F
* Các Thanh Ghi Điều Khiển I/O
Mỗi port của vi điều khiển bao gồm một số thanh ghi điều khiển được
sử dụng để cài đặt chức năng chân, lưu giữ dữ liệu hay thanh ghi điều khiển
nguồn ngắt ngoài.
* Thanh ghi cài đặt cổng (Port Configuration Register)
- Số lượng: bao gồm GPACON – GPJCON (từ port A – port J)
- Mục đích: lựa chọn chức năng của chân vi điều khiển.
* Thanh ghi dữ liệu cổng (Port Data Register)
- Số lượng: GPADAT – GPJDAT
- Mục đích: chứa dữ liệu được ghi ra hoặc đọc vào tùy theo port
được cài đặt ở chế độ output hay input.
* Thanh ghi kéo cổng (Port Pull- Up Register)
- Số lượng: GPBUP - GPJUP
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 18
- Mục đích: được sử dụng để cho phép hay không cho phép điện
trở kéo lên ở mỗi nhóm cổng.
Bit tương ứng = 0 điện trở kéo lên được cho phép
Bit tương ứng = 1 không cho phép điện trở kéo lên.
* Thanh ghi điều khiển hỗn tạp (Miscellaneous Control Register)
Được sử dụng điều khiển điện trở kéo lên DATA trong các chế độ
Sleep Mode, USB pad và CLKOUT.
Ví dụ:
- Các thanh ghi Port B:
Hình 2.19. Bảng các thanh ghi Port B
- Thanh ghi điều khiển GPBCON:
Hình 2.20. Thanh ghi điều khiển Port B
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 19
- Thanh ghi dữ liệu (GPBDAT)
Hình 2.21. Thanh ghi dữ liệu Port B
- Thanh ghi kéo cổng (GPBUP)
Hình 2.22. Thanh ghi kéo cổng Port B
* Thanh ghi điều khiển ngắt ngoài (External Interrupt Control
Register)
Tất cả 24 nguồn ngắt ngoài gây ngắt tới CPU bởi các tín hiệu khác
nhau.Thanh ghi EXTINT cài đặt tín hiệu đó theo mức thấp, mức cao, cạnh
lên, cạnh xuống hay cả hai cạnh.
Hình 2.23. Các thanh ghi điều khiển ngắt ngoài
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 20
Hình 2.24. Thanh ghi 0 điều khiển ngắt ngoài
Hình 2.25. Thanh ghi 1 điều khiển ngắt ngoài
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 21
Hình 2.26. Thanh ghi 2 điều khiển ngắt ngoài
2.2.4. Interrupt Controller 1.Giới Thiệu Chung
Bộ điều khiển ngắt trong S3C2440A nhận tín hiệu ngắt từ 60 nguồn
ngắt khác nhau bao gồm cả các ngoại vi nội như DMA, UART, IIC,…
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 22
Khi nhận được nhiều tín hiệu ngắt khác nhau bao gồm cả ngắt ngoài
và ngắt nội, bộ điều khiển sẽ sinh ngắt FIQ (Fast Interrupt) hoặc IRQ (
Interrupt) sau quá trình phân loại.
Quá trình phân loại phụ thuộc vào mức logic ưu tiên phần cứng và kết
quả được ghi vào thanh ghi chờ đợi ngắt.
*Quá trình xử lí ngắt:
Tất cả các nguồn yêu cầu ngắt từ các nguồn ngắt trước tiên đều được
đăng kí tại thanh ghi chờ nguồn (SRCPND). Sau đó, chúng được chia ra
thành 2 nhóm: FIQ và IRQ tùy theo thanh ghi chế độ ngắt (INTMOD). Quá
trình phân loại các ngắt IRQ dựa vào thanh ghi ưu tiên ngắt (PRIORITY)
Hình 2.27. Quá trình xử lí ngắt.
2.Các Thanh Ghi Điều Khiển Ngắt
* Thanh ghi trạng thái chương trình (PSR – Program Status Register)
Thanh ghi PSR có bit F-bit và I-bit, được sử dụng để cho phép các
loại ngắt.
F-bit = 1 không chấp nhận ngắt FIQ (Fast Interrupt Request)
I-bit = 1 không chấp nhận ngắt IRQ (Interrupt Request)
cần xóa các bit F-bit & I-bit để cho phép bộ điều khiển ngắt nhận
tín hiệu ngắt.
* Thanh ghi nguồn ngắt (SRCPND –Source Pending Register)
Thanh ghi SRCPND bao gồm 32 bit tương ứng với các nguồn ngắt
khác nhau. Mỗi bit được tự động set lên 1 bởi nguồn ngắt tùy theo giá trị bit
trong thanh ghi INTMASK và chỉ ra nguồn ngắt đó đang đợi phục vụ.Thêm
nữa, thanh ghi này không ảnh hưởng tới mức ưu tiên của các ngắt.
Trong chương trình phục vụ ngắt, người dùng nên xóa bít tương
ứng bằng cách ghi dữ liệu 0 ra vị trí bit.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 23
Hình 2.28. Thanh ghi nguồn ngắt SRCPND
* Thanh ghi kiểu ngắt (INTMOD_ Interrupt Mode Register)
ARM920T có 2 kiểu ngắt khác nhau: FIQ (Fast Interrupt Request)
và IRQ (Interrupt Request). Nguồn ngắt thuộc kiểu FIQ nếu bit tương ứng
trong thanh ghi INTMOD bằng 1, trường hợp khác thuộc kiểu IRQ.
Cần chú ý rằng, chỉ duy nhất 1 ngắt FIQ được phục vụ do đó người
dùng chỉ nên sử dụng FIQ cho các ngắt khẩn cấp.
Hình 2.29. Thanh ghi kiểu ngắt INTMOD
* Thanh ghi mặt nạ ngắt (INTMSK – Interrupt Mask Register)
Các bit trong thanh ghi xác định nguồn ngắt nào được phục vụ.
Hình 2.30. Thanh ghi mặt nạ ngắt INTMSK
* Thanh ghi chờ ngắt (INTPND – Interrupt Pending Register)
Các bit của thanh ghi này chỉ ra tín hiệu ngắt nào mà đang đợi
phục vụ có mức ưu tiên cao nhất.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 24
Hình 2.31. Thanh ghi chờ ngắt INTPND
2.2.5 Timer & PWM 1.Giới Thiệu Chung
S3C2440A có 5 timer 16-bit trong đó các timer 0, timer 1,timer 2 và
timer 3 có chức năng PWM.Timer 4 chỉ có chức năng làm interval timer và
không có chân output.Ngoài ra timer 0 có bộ sinh vùng chết (dead-zone
generator) được sử dụng với các thiết bị dòng lớn.
2 bộ 8-bit prescaler và 2 bộ 4-bit divider được dùng để định tần số
xung cho timer và PWM thông qua các bit trong thanh ghi điều khiển TCFG0
và TCFG1.
Thanh ghi bộ đệm đếm timer (TCNTBn) chứa các giá trị đầu được
load vào bộ đếm xuống khi timer được cho phép. Giá trị bộ đệm so sánh
timer (TCMPBn) chứa giá trị được load vào thanh ghi so sánh để so sánh với
giá trị đếm xuống.Các giá trị này cho phép thay đổi ngõ ra ổn định và có thể
thay đổi được tỉ lệ.
Mỗi timer bao gồm một bộ đếm xuống 16-bit, khi giá trị đếm bằng 0
thì ngắt timer sẽ được sinh ra để thông báo CPU biết quá trình hoạt động của
timer đã hoàn tất, đồng thời giá trị trong TCNTBn sẽ tự động được nạp trở lại
vào trong bộ đếm xuống cho lần đếm kế tiếp.Tuy nhiên, quá trình nạp này sẽ
không xảy ra nếu timer dừng (bit cho phép chạy timer không tích cực).
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 25
Hình 2.32. Giản đồ các timer & PWM
2.Các Thanh Ghi Điều Khiển Timer PWM
* Thanh ghi 0 cài đặt timer (TCFG0 – Timer Configuration Register 0)
Mục đích:
Thanh ghi được dùng để cài đặt giá trị Prescaler cho các Timer
Công thức tính giá trị xung clock của timer:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 26
Hình 2.33. Thanh ghi 0 cài đặt timer TCFG0
* Thanh ghi 1 cài đặt timer (TCFG1 – Timer Configuration Register 1)
Mục đích: Cài đặt giá trị divider của timer
Hình 2.34. Thanh ghi 1 cài đặt Timer TCFG1
* Thanh ghi điều khiển timer (TCON – Timer Control Register)
Mục đích:
Dùng để điều khiển các hoạt động của timer như: chạy/ dừng,
cập nhật giá trị, inverter on hoặc off.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 27
Hình 2.35. Thanh ghi điều khiển Timer TCON
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 28
* Các thanh ghi bộ đệm đếm và thanh ghi bộ đệm so sánh (TCNTBn &
TCMPBn)
Thanh ghi TCNTBn là thanh ghi bộ đệm đếm timer, được dùng để
chứa giá trị đầu được tự động nạp vào bộ đếm xuống TCNTn mỗi khi timer
được cho phép hay đếm tới giá trị 0.
Thanh ghi TCMPBn là thanh ghi bộ đếm so sánh timer, chứa giá
trị được nạp vào thanh ghi so sánh TCMPn để so sánh giá trị đếm xuống của
timer.Khi 2 giá trị này bằng nhau, mức logic của ngõ ra sẽ thay đổi.Vì vậy,
giá trị của TCMPBn được sử dụng cho mục đích điều rộng xung (PWM) để
xác định thời gian turn – on hay turn- off của ngõ ra PWM.
Các thanh ghi TCNTBn & TCMPBn của timer 0, timer 1, timer 2
và timer 3 tương tự nhau.
Hình 2.36. Các thanh ghi bộ đệm đếm và bộ đệm so sánh
Riêng Timer 4 chỉ có chức năng làm timer nội (Interval Timer) và
không có chân output nên chỉ có thanh ghi TCNTB4.
Hình 2.37. Thanh ghi bộ đệm đếm Timer 4
3.Hoạt Động Của Timer
* Chế độ tự động nạp giá trị (Auto –Reload)
Timer PWM S3C2440A cho phép tự động nạp giá trị cho lần hoạt
động kế tiếp mà không cần phải dừng timer hiện tại.Giá trị timer được ghi
vào thanh ghi bộ đệm đếm timer (TCNTBn) và giá trị đếm hiện tại của timer
có thể đọc từ thanh ghi quan sát đếm timer (TCNTOn).
Quá trình tự động nạp của timer thực hiện việc copy giá trị trong
thanh ghi TCNTBn vào thanh ghi đếm xuống TCNTn khi thanh ghi đếm
xuống bằng 0 và chế độ tự động nạp được cho phép.Đồng thời với đó, tín
hiệu ngắt được sinh ra báo CPU về quá trình đếm hoàn tất.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 29
Hình 2.38. Ví dụ về chế độ tự nạp giá trị của Timer
* Các bước để chạy timer:
1. Ghi giá trị ban đầu vào thanh ghi TCNTBn và TCMPBn
2. Set giá trị bit cho phép update bằng tay (manual update bit) và
cài đặt chế độ đảo nếu có (inverter on/ off).
3. Xóa bit cho phép update bằng tay và set giá trị start bit để chạy
timer.
Hình 2.39. Ví dụ cài đặt chạy timer
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 2: BOARD MINI2440 GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 30
* Ví dụ hoạt động của timer chế độ PWM
Hình 2.40. Ví dụ về ngõ ra PWM.
Chức năng PWM được sử dụng thông qua thanh ghi so sánh
TCMPBn. Tần số PWM được xác định bởi thanh ghi TCNTBn và giá trị duty
cycle được xác bởi thanh ghi TCMPBn.
Nhờ vào chế độ tự động nạp giá trị nên việc ghi giá trị nạp vào thanh
ghi so sánh TCMPBn có thể được thực hiện tại bất kì điểm nào trong chu kì
PWM hiện tại hoặc trong chương trình phục vụ ngắt ISR (Interrupt Service
Routine).
* Điều khiển mức logic ngõ ra:
Mức logic ngõ ra PWM được điều khiển thay đổi từ 1qua 0 hoặc 0
qua 1 tùy thuộc vào chế độ đảo hay không (inverter on/ off).
Hình 2.41. Mức logic ngõ ra PWM ở chế độ đảo on &off (Inverter on & off)
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 31
CHƢƠNG 3
EMBEDDED LINUX (BUSY BOX)
3.1 Tìm Hiểu Kiến Thức Cơ Bản Về Linux
3.1.1 Giới thiệu hệ điều hành Linux
3.1.1.1 Lịch sử nhân hệ điều hành Linux
-Linux là một nhân hệ điều hành được phát triển bởi Linus
Torvalds vào năm 1991 trên cơ sở cải tiến phiên bản UNIX có tên Minix do
giáo sư Andrew S.Tanenbaum xây dựng và phổ biến . Sau đó Linus Torvalds
đã công bố mã nguồn của mình cho mọi người và mong muốn mọi người có
thể đóng góp ý kiến , phát hiện lỗi và phát triển nó ngày càng tốt hơn . Và
cũng từ thời điểm đó , theo tư tưởng GNU rất nhiều chuyên gia trên toàn thế
giới đã tham gia vào quá trình phát triển Linux và vì vậy Linux ngày càng
phát triển , mạnh mẽ , ổn định , có độ tin cậy cao và đáp ứng được nhu cầu
của người dùng .
Một số mốc lịch sử quan trọng trong quá trình phát triển nhân hệ điều hành
Linux :
-Sau ba năm nhân Linux ra đời , đến ngày 14-3-1994, hệ điều hành
Linux phiên bản 1.0 được phổ biến . Thành công lớn nhất của Linux 1.0 là nó
đã hỗ trợ giao thức mạng TCP/IP chuẩn UNIX , sánh với giao thức socket
BSD- tương thích cho lập trình mạng . Trình điều khiển thiết bị đã được bổ
sung để chạy IP trên một mạng Ethernet hoặc trên tuyến đơn hoặc qua
modem. Hệ thống file trong Linux 1.0 đã vượt xa hệ thống file của Minix
thông thường , ngoài ra đã hỗ trợ điều khiển SCSI truy nhập đĩa tốc độ cao.
Điều khiển bộ nhớ ảo đã được mở rộng để hỗ trợ điều khiển trang cho các
file swap và ánh xạ bộ nhớ của file đặc quyền .
-Vào tháng 3-1995 , nhân 1.2 được phổ biến. Điều đáng kể của Linux
1.2 so với Linux 1.0 ở chỗ nó hỗ trợ một phạm vi rộng và phong phú phần
cứng , bao gồm cả kiến trúc tuyến phần cứng PCI mới . Nhân Linux 1.2 là
nhân kết thúc dòng nhân Linux chỉ hỗ trợ PC .
-Cách đánh chỉ số các dòng nhân (hệ điều hành) Linux : Hệ thống chỉ số
được chia thành một số mức, chẳng hạn hai mức như 2.4 hoặc ba mức như
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 32
2.2.5. Trong cách đánh chỉ số như vậy , quy ước rằng với các chỉ số từ mức
thứ hai trở đi , nếu là số chẵn thì dòng nhân đó đã khá ổn định và tương đối
hoàn thiện , còn nếu là số lẻ thì dòng nhân đó vẫn đang được phát triển tiếp .
-Tháng 6-1996 , nhân Linux 2.0 được phổ biến . Có hai đặc trưng nổi
bật của Linux 2.0 là hỗ trợ kiến trúc phức hợp , bao gồm cả cổng Alpha 64-
bit đầy đủ , và hỗ trợ kiến trúc đa bộ xử lý . Phân phối nhân Linux 2.0 cũng
thi hành được trên bộ xử lý Motorola 68000 và kiến trúc SPARC của SUN .
-Tới năm 2000 , nhân Linux 2.4 được phổ biến . Một trong đặc điểm
được quan tâm của nhân này là nó hỗ trợ mã ký tự Unicode 32 bít , rất thuận
lợi cho việc xây dựng các giải pháp toàn diện và triệt để đối với vấn đề ngôn
ngữ tự nhiên trên phạm vi toàn thế giới .
-Nhân Linux là phần mềm tự do được phân phối theo Giấy phép sở hữu
công cộng phần mềm GNU GPL ( General Public License ) .
Vật lấy phước của nhân Linux là chú chim cánh cụt - Tux .
Hình 3.1: Linus Torvalds và vật lấy phước chú chim cánh cụt
3.1.1.2 Tổ chức của nhân hệ điều hành Linux
-Nhân được ví như trái tim của hệ điều hành . Về bản chất nhân cũng là
một chương trình phần mềm máy tính nhưng ở cấp độ hệ thống có vai trò
điều khiển các thành phần của hệ thống máy tính , quản lý tài nguyên của hệ
thống , cung cấp một số dịch vụ và phần mềm cơ bản cho máy tính , cung
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 33
cấp môi trường thực thi có các ứng dụng khác nhau chạy trên hệ thống .
Nhân chính là cầu nối giữa phần cứng vật lý của máy tính với và chương
trình ứng dụng .
-Các dịch vụ của nhân được chạy trong chế độ đặc quyền của bộ xử lý .
Trái lại , các chương trình ứng dụng được chạy trong chế độ người dùng hoàn
toàn cách ly với hệ điều hành . Khi ứng dụng chạy trong chế độ người dùng
gọi tới một dịch vụ hệ thống thông qua một giao diện , bộ xử lý chặn lại lời
gọi và thi hành dịch vụ mức nhân hệ điều hành . Thông thường việc thi thực
thi ở mức nhân đơn giản và nhanh hơn bởi vì nó không bị chuyển giữa chế độ
đặc quyền và không đặc quyền .
Nhân của Linux gồm năm tiểu hệ thống :
-Bộ phân thời gian cho tiến trình ( Process Schedule – SCHED ) :
-Hoạt động của máy tính , tại một thời điểm chỉ có một lệnh được thực
thi . Tuy nhiên các hệ điều hành đa nhiệm như Windows, Linux … đều cho
phép nhiều chương trình chạy cùng một lúc . Các hệ điều hành đa nhiệm có
thể làm được như vậy bằng cách chuyển quyền thực thi qua lại giữa các
chương trình thật nhanh làm cho người dùng có cảm giác các chương trình
chạy cùng lúc với nhau . Vi dụ người dùng có thể vừa soạn thảo văn bản vừa
có thể nghe . Trong hệ điều hành đa nhiệm thì bộ phân thời gian tiến trình
đảm nhiệm nhiệm vụ này .
SCHED được chia thành bốn khối :
-Khối luật định thời (scheduling policy): chịu trách nhiệm phân bố xem
tiến trình ( process ) nào được quyền truy xuất CPU. Hệ thống hoạt động có
thông suốt hay không nhờ vào bộ luật này, tránh trường hợp một tiến trình lợi
dụng sơ hở của điều luật mà chiếm thời gian hệ thống quá nhiều làm các tiến
trình khác bị đóng băng (freeze) .
-Khối phụ thuộc kiến trúc ( architeture-specific ): khối này gồm các mã
assembly phụ thuộc vào mỗi loại CPU dùng để tạm ngưng hoạt động của tiến
trình .
-Khối độc lập kiến trúc (architeture-independent): Khối gọi các hàm từ
khối phụ thuộc kiến trúc và khối luật để chuyển giửa các tiến trình đồng thời
nó còn gọi các hàm ở MM để thiết lập bộ nhớ ảo cho các tiến trình được hồi
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 34
phục lại . Khối phụ thuộc kiến trúc sẽ khác nhau ở mỗi loại CPU (ỉ386, apha,
v.v) nhưng khối độc lập kiến trúc thì không đổi .
-Khối hàm gọi hệ thống ( system call ) . Gồm các hàm mà người dùng
có thể dùng để tương tác với SCHED. Khi lập trình Linux và Unix sẽ quen
với các hàm gọi hệ thống này.
Bộ quản lý bộ nhớ ( Memory Manager - MM) :
-Bộ nhớ qui ước của các máy tính chỉ có 640KB . Do BIOS chỉ quản lý
được tới FFFF , vùng nhớ cao từ A0000 trở lên dùng để ánh xạ BIOS , video
card memory và các thiết bị ngoại vi khác , vùng nhớ còn lại tử 9FFFF trở
xuống tương đương với 640KB. Trong chế độ bảo vệ ( protect mode ) của
CPU 32 bit đưa ra khái niệm bộ nhở ảo ( Virtual Memory ) . Lúc này mỗi
tiến trình được cấp tới 4GB bộ nhớ ảo . Nhưng nhân hệ điều hành sẽ tạo ra
một bảng mô tả từng trang của bộ nhớ ảo với bộ nhớ vật lý .Bộ nhớ vật lý
bây giờ bao gồm cả bộ nhớ RAM và vùng nhớ hoán vị trên đĩa cứng .
Hệ thống file ảo :
-Hệ thống này không chỉ cung cấp truy suất đến hệ thống file trên đĩa
cứng mà còn tất cả các ngoại vi . Trong Linux tất cả các tập tin , thư mục và
các thiết bị đều được coi như là file . Ví dụ như máy in , cổng nối tiếp , các ổ
đĩa … đều được truy cập như là file . Linux cũng cung cấp các thuộc tính
truy cập cho file và thư mục , các thuộc tính có thể được thiết lập như cho
phép đọc , cho phép ghi , cho phép thực thi . Linux thiết lập chế độ bảo vệ
đối với các file hệ thống và hạn chế quyền truy cập đối với các thiết bị .
-Giao diện mạng ( Network Interface - NET) :
-Trong nhân Linux dựng sẵn giao thức TCP/UDP , IP và Ethernet .
Bộ truyền thong nội bộ (Inter-process communication IPC) :
Một tiến trình trong Linux giao tiếp với các tiến trình khác và với nhân hệ
điều hành thông qua một cơ chế được gọi là bộ truyền thông nội bộ - IPC .
Nó cho phép các tiến trình gửi hoặc nhận các thông điệp từ một tiến trình
khác , sử dụng chung vùng nhớ chia sẻ và đồng bộ với các tiến trình khác .
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 35
3.1.1.3 Tổ chức thƣ mục
Các file trong hệ thống Linux được đặt theo một trật tự trong các thư mục .
Có một thư mục chính trong đó chứa các thư mục con và các file .
Thư mục ./bin : Chứa các file thực thi dạng nhị phân và các chương trình
khởi dộng của hệ thống được .
Thư mục ./boot : Thư mục này chứa file ảnh ( image file ) của nhân dùng cho
quá trình khởi động .
Thư mục ./dev : Thư mục này chứa các file thiết bị .
Thư mục ./etc : Thư mục này chứa các file cấu hình toàn cục của hệ thống .
Thư mục ./home : Thư mục này chứa các thư mục con đại diện cho mỗi
người dùng khi đăng nhập . Đây là nơi làm việc thường xuyên của người
dùng . Khi người quản trị tạo tài khoản cho một người dùng thì sẽ cấp cho
người dùng một thư mục cùng tên với tài khoản người dùng nằm trong thư
mục /home . Người dùng cho mọi quyền thao tác trên thư mục của mình và
không ảnh hưởng đến người dùng khác .
Thư mục ./lib : Thư mục này chứa các file thư viện .so hoặc .a . Các thư viện
C và lien kết động cần cho chương trình chạy và cho toàn hệ thống .
Thư mục ./lost+found : Khi chạy chương trình fsck , nếu tìm thấy một chuỗi
dữ liệu nào thất lạc trên đĩa cứng và không lien quan đến các tập tin , Linux
sẽ gom chúng lại và đặt trong thư mục này để nếu cần người dùng có thể đọc
và giữ lại dữ liệu bị mất .
Thư mục ./mnt : Thư mục này chứa các kết gán ( mount ) tạm thời đến các ổ
đĩa hoặc thiết bị khác .
Thư mục ./sbin : Thư mục này chứa các file thực thi của hệ thống dành cho
người quản trị hệ thống .
Thư mục ./tmp : thư mục này dùng để chứa các file tạm mà chương trình tạo
ra lúc chạy . Các file này sẽ được hệ thống dọn dẹp khi các chương trình kết
thúc .
Thư mục ./usr : Thư mục này chứa nhiều thư mục con như /usr/bin ,
/usr/local … và đây cũng là một trong những thư mục con quan trọng của hệ
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 36
thống , bên trong thư mục con này (/usr/local) cũng chứa đầy đủ các thư mục
con tương tự ngoài thư mục gốc như sbin, lib, bin… Nếu nâng cấp hệ thống
thì các chương trình người dùng cài đặt trong thư mục /usr/local vần giữ
nguyên và không sợ các chương trình bị mất mát.
Thư mục ./var : Thư mục này chứa các file biến thiên bất thường như các file
dữ liệu đột nhiên tăng kích thước trong một thời gian ngắn sau đó lại giảm
kích thước xuống còn rất nhỏ. Điển hình là các file dùng làm hàng đợi chứa
dữ liệu cần đưa ra máy in hoặc các hàng đợi chứa thư điện tử .
3.1.1.4 Các lệnh cơ bản trong linux
a. Lệnh liên quan đến hệ thống
• exit: thoát khỏi cửa sổ dòng lệnh.
• logout: tương tự exit.
• reboot: khởi động lại hệ thống.
• halt: tắt máy.
• startx: khởi động chế độ xwindows từ cửa sổ terminal.
• mount: gắn hệ thống tập tin từ một thiết bị lưu trữ vào cây thư mục chính.
• unmount: ngược với lệnh mount.
b. Lệnh thao tác trên tập tin
• ls: lấy danh sách tất cả các file và thư mục trong thư mục hiện hành.
• pwd: xuất đường dẫn của thư mục làm việc.
• cd: thay đổi thư mục làm việc đến một thư mục mới.
• mkdir: tạo thư mục mới.
• rmdir: xoá thư mục rỗng.
• cp: copy một hay nhiều tập tin đến thư mục mới.
• mv: đổi tên hay di chuyển tập tin, thư mục.
• rm: xóa tập tin.
• wc: đếm số dòng, số kí tự... trong tập tin.
• touch: tạo một tập tin.
• cat: xem nội dung tập tin.
• vi: khởi động trình soạn thảo văn bản vi.
• df: kiểm tra dung lượng đĩa.
• du: xem dung lượng đĩa đã dùng cho một số tập tin nhất định
c. Lệnh khi làm việc trên terminal
• clear: xoá trắng cửa sổ dòng lệnh.
• date: xem ngày, giờ hệ thống.
• cal: xem lịch hệ thống.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 37
d. Lệnh quản lí hệ thống
• rpm: kiểm tra gói đã cài đặt hay chưa, hoặc cài đặt một gói, hoặc sử dụng để
gỡ bỏ một gói.
• ps: kiểm tra hệ thống tiến trình đang chạy.
• kill: dừng tiến trình khi tiến trình bị treo. Chỉ có người dùng super-user mới
có thể dừng tất cả các tiến trình còn người dùng bình thường chỉ có thể dừng
tiến trình mà mình tạo ra.
• top: hiển thị sự hoạt động của các tiến trình, đặc biệt là thông tin về tài
nguyên hệ thống và việc sử dụng các tài nguyên đó của từng tiến trình.
• pstree: hiển thị tất cả các tiến trình dưới dạng cây.
• sleep: cho hệ thống ngừng hoạt động trong một khoảng thời gian.
• useradd: tạo một người dùng mới.
• groupadd: tạo một nhóm người dùng mới.
• passwd: thay đổi password cho người dùng.
• userdel: xoá người dùng đã tạo.
• groupdel: xoá nhóm người dùng đã tạo.
• gpasswd: thay đổi password của một nhóm người dùng.
• su: cho phép đăng nhập với tư cách người dùng khác.
• groups: hiển thị nhóm của user hiện tại.
• who: cho biết ai đang đăng nhập hệ thống.
• w: tương tự như lệnh who.
• man: xem hướng dẫn về dòng lệnh như cú pháp, các tham số...
Để hiểu và sử dụng tốt các câu lệnh trên, các chúng ta có thể sử dụng
lệnh man với cú pháp: man ten_cau_lenh để có được những thông tin đầy đủ
về chức năng cũng như cú pháp của câu lệnh
3.2 Hệ Điều Hành BUSY BOX
3.2.1 Giới thiệu chung
3.2.1.1 Định nghĩa: Mệnh danh là The Swiss Army Knife of Embedded
Linux, busy box cung cấp một file thực thi duy nhất busybox có khả năng
chạy rất nhiều ứng tiêu chuẩn trên môi trường Linux nhưng ping, cat, telnet...
Các ứng dụng này đáp ứng tốt nhu cầu sử dụng của người dùng mặc dù một
số chức năng và option của các ứng dụng đã bị bỏ bớt để phù hợp với kích
thước của môi trường nhúng (Vd: lệnh ping trong busy box không cho phép
người dùng chỉ định interval (-I) như lệnh ping chạy trên một host x86).
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 38
- BUSY BOX là hệ điều hành thu nhỏ chỉ chứa những thàh phần cơ
bản của hệ điều hành như nhân,các bộ dịch,các gói lệnh….Và do đó ta có thể
add thêm những công cụ hay các bộ dịch cần thiết cho công việc thực hiện
các ứng dụng điều khiển của chúng ta.Một mặt thuận lợi là đây là hệ điều
hành thu nhỏ nên rất thích hợp với những tài nguyên hạn chế của board.Ta
chỉ cần thiết lập những cong cụ cần thiết cho việc sử dụng lập trình điều
khiển,chứ không tích hợp nhiều thứ không cần thiết như Qtopia 2.2.0,chiếm
đến 48Mbytes.
- Busy box có thể download tại trang chủ BusyBox. Busy box có giao
diện compile rất giống với giao diện compile của Linux kernel
3.2.2 Cài đặt Busybox cho platform Arm9 và mini2440
-Download linux-busybox-mini2440-1.13.3.tgz từ địa chỉ sau:
Code:
http://friendlyarm.net/dl.php?file=linux-busybox-mini2440-1.13.3.tgz
.
- Giải nén file linux-busybox-mini2440-1.13.3.tgz , ở đây nó được
giải nén vào thư mục gốc /, tuy nhiên có thể giải nén vào bất cứ thư mục nào
cũng được.
Code:
# tar –xvzf ./ linux-busybox-mini2440-1.13.3.tgz –C /
-Tại thư mục vừa giải nén gõ lệnh để config cho busy box:
Code:
@host:/busybox# make xconfig
Trong phần config này, có 2 chức năng quan trọng nhất cần quan tâm cho
platform ARM là cross compile và thư mục cài đặt. Các phần config bên
dưới sẽ chỉ ra ứng dụng nào cần được cross compile và tích hợp vào file thực
thi busybox, chúng ta check vào các ứng dụng cần thiết để activate chúng.
Code:
@host:/busybox# make
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 39
@host:/busybox# make install
-Để có thể gọi các ứng dụng của busy box trực tiếp từ dòng lệnh mà
không cần phải chỉ đường dẫn, chúng ta sẽ đưa /bin của busy box vào search
PATH của mini2440
Code:
@host/# gedit /nfs/root/.bashrc
export PATH=$PATH:/busybox/bin
-Khi install busy box đã tự tạo cái soft link với tên tương ứng với các
ứng dụng và dẫn đến file thực thi busybox, chúng ta chỉ cần gọi tên ứng dụng
là có thể chạy được bình thường.
3.3 ROOT FILE SYSTEM
3.3.1 Giới thiệu chung
-Bên cạnh boot loader và kernel, root file system là một thành phần
quan trọng của hệ thống. Root file system có thể build độc lập với 2 phần còn
lại, miễn là kernel có thể hỗ trợ định dạng của root file system. Root file
system này sẽ chứa tất cả các directory, file và tài khoản người dùng trong hệ
thống Linux
Một root file system cơ bản bao gồm các directory sau đây:
/bin chứa các file thực thi của người dùng.
/boot Chứa các file dùng cho việc boot hệ thống.
/dev Chứa các device file.
/etc Chứa các file cấu hình cho hệ thống và ứng dụng.
/home thư mục home của các user khác là thư mục con của thư mục này.
/lib chứa các thư viện liên kết động.
/media một directory chuyên dùng để mount các media.
/mnt directory để mount các file system tạm thời
/opt chứa các software tùy chọn.
/proc điểm để mount một file system ảo, chứa thông tin của kernel đang chạy
hiện hành.
/root thư mục home của tài khoản root.
/sbin chứa các file thực thi với quyền super user.
/sys điểm để mount filesystem ảo, chứa thông tin và điều khiển hệ thống
(device, bus, drivers...).
/tmp mount một file system ảo trên RAM, sẽ bị xóa hết khi hệ thống khởi
động lại.
/usr chứa các ứng dụng cho các users.
/var chứa dữ liệu do các trình daemon ghi lại (log file, update packages...).
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 40
3.3.2 Build root file system
-Tạo thư mục có tên là rootfs:
Code:
mkdir /embeddedlinux/mini2440/rootfs
-Copy những gì build được trong thư mục busybox/_install bỏ vào trong
rootfs.
Code:
cd /embeddedlinux/mini2440/rootfs
cp -a /embeddedlinux/mini2440/toolchain/busybox/_install/* ./
Ta sẽ có một số các thư mục mới trong rootfs:
-Tạo các thư mục cần thiết còn lại
Code:
mkdir dev
mkdir -p etc/init.d
mkdir lib
mkdir mnt
mkdir proc
mkdir sys
mkdir -m 777 tmp
mkdir var
-Copy các thư viện trong arm-linux-gcc-4.3.2 bỏ vào trong thư mục lib
Code:
cd /embeddedlinux/mini2440/rootfs/lib
cp -a /embeddedlinux/mini2440/toolchain/usr/local/arm/4.3.2/arm-none-
linux-gnueabi/libc/armv4t/lib/* .
-Tạo thêm một output
Code:
cd /embeddedlinux/mini2440/rootfs/dev
mknod console c51
-Tạo file inittab trong thư mục /embeddedlinux/mini2440/rootfs/etc với
nội dụng
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 41
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a
::restart:/sbin/init
::respawn:/sbin/getty -L 115200 /dev/tty0 vt100
-Tạo file có tên là rcS trong thư mục
/embeddedlinux/mini2440/rootfs/etc/init.b
Code:
gedit ./etc/init.b/rcS
Trong file này ta cần sửa nội dung như sau:
#! /bin/sh
#Setup the bin file location and export to system PATH
PATH=/sbin:/bin:/usr/sbin:/usr/bin
umask 022
export PATH
# mount the filesystem directories
mount -a
mkdir /dev/pts
mount -t devpts devpts /dev/pts -o mode=0622
# create device nodes and directories
echo /sbin/mdev>/proc/sys/kernel/hotplug
mdev -s
mkdir /var/lock
# start logging utility services
klogd
syslogd
# set system clock from RTC
hwclock -s
# set host and config loopback interface
ifconfig lo 127.0.0.1
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 42
-Tạo file mdev.conf file trong thưc mục
/embeddedlinux/mini2440/rootfs/etc
Code:
gedit mdev.conf
Sau khi mở cửa sổ soạn code ta soạn thảo chương trình như sau:
# system all-writable devices
full 0:0 0666
null 0:0 0666
ptmx 0:0 0666
random 0:0 0666
tty 0:0 0666
zero 0:0 0666
# console devices
tty[0-9]* 0:5 0660
vc/[0-9]* 0:5 0660
# serial port devices
s3c2410_serial0 0:5 0666 =ttySAC0
s3c2410_serial1 0:5 0666 =ttySAC1
s3c2410_serial2 0:5 0666 =ttySAC2
s3c2410_serial3 0:5 0666 =ttySAC3
# loop devices
loop[0-9]* 0:0 0660 =loop/
# i2c devices
i2c-0 0:0 0666 =i2c/0
i2c-1 0:0 0666 =i2c/1
# frame buffer devices
fb[0-9] 0:0 0666
# input devices
mice 0:0 0660 =input/
mouse.* 0:0 0660 =input/
event.* 0:0 0660 =input/
ts.* 0:0 0660 =input/
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 43
# rtc devices
rtc0 0:0 0644 >rtc
rtc[1-9] 0:0 0644
# misc devices
mmcblk0p1 0:0 0600 =sdcard */bin/hotplug
sda1 0:0 0600 =udisk * /bin/hotplug
-Tạo file fstab trong thư mục /embeddedlinux/mini2440/rootfs/etc
# device mount-point type options dump fsck order
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
var /var tmpfs defaults 0 0
-Tạo file group trong thư mục /embeddedlinux/mini2440/rootfs/etc
Code:
grep root
/etc/group>group
-Tạo file password trong thư mục /embeddedlinux/mini2440/rootfs/etc
Code:
grep root /etc/passwd>passwd
-Tạo file profile trong thư mục /embeddedlinux/mini2440/rootfs/etc
Code:
USER="`id -un`"
LOGNAME=$USER
PS1='[\u@\h \W]\# '
PATH=$PATH
HOSTNAME=`/bin/hostname`
export USER LOGNAME PS1 PATH HOSTNAME
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 44
-Tạo file issue trong thư mục /embeddedlinux/mini2440/rootfs/etc
Code:
Welcome to Mini2440
Kernel \r on an \m (\l)
-Tạo file resolv.conf trong thư mục /embeddedlinux/mini2440/rootfs/etc
Code:
nameserver 192.168.55.244
nameserver 168.95.1.1
3.3.3 Cài đặt
-Để có thể tạo được một root file system chạy được, chúng ta
phải chép các file vào các thư mục ở trên cho phù hợp (libc vào /lib,
configuration file vào /etc, các file thực thi vào /bin, ...), điều này không khó
nhưng tốn thời gian để có thể cross compile tất cả các file thực thi và thư viện
cần thiết, và chép thủ công vào root file system này. Chúng ta có thể sử dụng
một root file system có sẵn để làm phần khung và cài đặt thêm ứng dụng
hoặc chỉnh sửa các phần có sẵn cho phù hợp với mục đích sử dụng của mình.
Ở đây, chúng ta sử dụng root file system của Embedian có thể download tại
http://mini2440.googlecode.com/files...talled.tar.bz2. Sau khi tải về chúng ta
giải nén file
Code:
@host:# tar -xjvf emdebian-grip-090306-armel-lenny-installed.tar.bz2 -C
/nfs
-Các thư mục được xả nén ra trong /nfs có cấu trúc tương tự như
cái thư mục giới thiệu ở phía trên. Chúng ta có thể thay đổi, hiệu chỉnh trên
thư mục này, sau đó chúng ta có thể dùng nó để làm root file system cho
Mini2440 thông qua mạng (network file system) , hoặc biến thư mục này
thành một file ảnh và chép vào NAND memory. Ở đây, chúng ta giải nén file
vào thư mục /nfs để tiếp tục phát triển..
-Khung sườn mini2440_rootfs đã khá là hoàn chỉnh nhưng vẫn
thiếu một số ứng dụng cần thiết cho phát triển mini2440. Việc đưa một ứng
dụng sang chạy được trên platform ARM của mini2440 khó hay dễ phụ thuộc
vào source code của ứng dụng, nếu ứng dụng là portable thì chúng ta có thể
dễ dàng chạy lệnh ./configurate với các thông số phù hợp để tiến hành cross
compile, các ứng dụng phức tạp hơn đòi hỏi phải cross compile các thư viện
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 45
kèm theo ứng dụng, và phức tạp nhất là chỉnh sửa code của ứng dụng để có
thể cross compile.
3.4 CROSS COMPILE DROPBEAR
3.4.1 Giới thiệu chung
-Các hệ thống nhúng trong khi phát triển có thể dùng cáp serial để nối
trực tiếp và cấu hình nhưng khi hệ thống đã chạy ổn định và có thể kết nối
mạng sẽ sinh ra nhu cầu cấu hình từ xa cho hệ thống (vd như các router và
switch trong mạng). Busybox cung cấp inetd, một ứng dụng chạy daemon
giúp người dùng có thể telnet vào thiết bị, tuy nhiên các phiên cấu hình dùng
telnet là không an toàn vì dữ liệu hoàn toàn không được mã hóa và có thể đọc
được dễ dàng (kể cả mật khẩu để telnet vào thiết bị). Để tạo một kết nối cấu
hình an toàn hơn, chúng ta có thể sử dụng ssh, daemon cho ứng dụng này là
dropbear.
3.4.2 Cài đặt
-Dropbear có thể được download tại Dropbear SSH server and client.
Sau đây chúng ta sẽ tiến hành cross compile dropbear cho ARM platform.
-Dropbear yêu cầu liên kết với thư viện zlib, nên đầu tiên chúng ta cần
download zlib tại zlib Home Site(www.zlib.net) và cross compile nó
Code:
@host:# tar -xvf ./zlib-1.2.5.tar.gz
@host:# cd ./zlib-1.2.5/
@host:/zlib-1.2.5$ mkdir build
@host:/zlib-1.2.5$ CC=arm-linux-gcc ./configure --prefix=./build
@host:/zlib-1.2.5$ make
@host:/zlib-1.2.5$ make install
Quá trình cross compile dropbear như sau:
@host:/# tar -xvf ./dropbear-0.52.tar.gz
@host:/# cd ./dropbear-0.52/
@host:/# dropbear-0.52$ mkdir build
@host:/# dropbear-0.52$ CC=arm-linux-gcc ./configure --with-zlib=/zlib-
1.2.5/build --prefix=/dropbear-0.52/build/ --host=arm
@host:/# dropbear-0.52$ make scp
@host:/# dropbear-0.52$ make
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 46
@host:/# dropbear-0.52$ make install
@host:/# dropbear-0.52$ cp ./scp ./build/bin/
Bây giờ, chúng ta có thể chép các file thực thi của dropbear lên root file
system của mini2440:
Code:
@host:/dropbear-0.52# cp ./build/bin/* /nfs/bin/
@host:/dropbear-0.52# cp ./build/sbin/* /nfs/sbin/
@host:/dropbear-0.52# mkdir /nfs/etc/dropbear
@host:/dropbear-0.52# cp ./dropbear_dsa_host_key /nfs/etc/dropbear/
@host:/dropbear-0.52# cp ./dropbear_rsa_host_key /nfs/etc/dropbear/
-Chúng ta cần cho phép dropbear autorun khi hệ thống bắt đầu khởi
động
Code:
@host:/# gedit /nfs/etc/init.d/dropbear.sh
-Ghi nội dung này vào file dropbear.sh
Code:
echo “dropbear daemon started”
/sbin/dropbear -F -d /etc/dropbear/dropbear_dsa_host_key -r
/etc/dropbear/dropbear_rsa_host_key &
@host:/# chmod 777 /nfs/etc/dropbear/dropbear.sh
@host cd /nfs/etc/rc2.d/
@host:/nfs/etc/rc2.d/# ln -s ../init.d/dropbear.sh ./S99dropbear
-Cần lưu ý là soft link ở trên phải là một relative path, do nếu dùng
absolute path thì khi khởi động mini2440 sẽ không hiểu thư mục /nfs ở đâu.
Để thực hiện ssh vào mini2440, chúng ta dùng lệnh sau
Code:
@host:/# ssh root@mini2440_ip
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 47
3.5 BUILD GDB CHO EMBEDDED LINUX
-Như chúng ta đã biết gdb là một công cụ khá hiệu quả để debug cho
chương trình. Hiện tại trong gói toolchain arm-linux-gnu cũng có sẵn công cụ
này nhưng lại không chạy được. Vì vậy đễ cài đặt cho embedded linux, ta chỉ
có cách là build lại và cài lại. Các bước thực hiện như sau. Lưu ý nên thực
hiện vô cùng cẩn thận từng bước.
Bƣớc 1: Biên dịch gdb client đễ chạy trên máy tính
-Download gói cài đặt gdb 7.0 về máy. Sau đó giải nén và build theo các
lệnh sau:
Code:
1. tar xvf gdb-6.8.tar.gz
2. cd gdb-7.0
3. ./configure --build=x86 --host=x86 --target=arm-linux
4. make
5. make install DESTDIR=$PWD/_build
Sau khi biên dịch xong thì vào trong trong thư mục _build kiếm file thực thi
arm-linux-gdb bỏ riêng ra để xài về sau.
Bƣớc 2: Biên dịch gdb server đễ chạy trên board.
-Trước tiên ta phải build một gói thư viện phụ tên là termcap. Đầu tiên
down termcap về sau đó giải nén và tiến hành cài đặt:
Code:
export CC=arm-linux-gcc
export RANLIB=arm-linux-ranlib
./configure --host=powerpc-7450-linux-gnu --prefix=$HOME/term/termcap
make install
-Sau khi biên dịch thành công tiến hành khai báo bổ sung hai biến môi
trường:
Code:
export LDFLAGS="-static -L$HOME/term/termcap/lib"
export CPPFLAGS="-I$HOME/term/termcap/include"
-Cuối cùng tiến hành biên dịch cho gdb server. Giải nén gdb 7.0 ra
máy, lưu ý là giải nén chứ không xài lại gdb 7.0 dùng ở bước 1, sau đó tiến
hành configure và biên dịch.
Code:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 48
# cd gdb-7.0
# ./configure --host=arm-linux
# make install DESTDIR=$PWD/_build
-Khi máy biên dịch xong, vào trong thư mục _build lấy ra file
gdbserver bỏ vào thư mục /usr/bin/ của board.
Bƣớc 3: Kiểm tra gdb:
-Ta viết một chương trình đơn giản rồi bỏ lên board, lúc biên dịch
chương trình thêm đối số -g vào lệnh biên dịch. Sau đó trên board thực hiện
gọi gdbserver:
Code:
gdbserver 192.168.1.10:1234 myprograme
-Trong đó 192.168.1.10 là ip của máy tính host nối với board.Trên
máy host ta gọi chương trình arm-linux-gdb
Code:
arm-linux-gdb --se=myprograme
target remote 192.168.1.11:1234
Trong đó 192.168.1.11 là ip của board.
Nếu connect thành công thì thực hiện tương tự như gdb bình thường (chi tiết
tham khảo gdb user manual).
3.6 QT VIRTUAL FRAMEBUFFER 3.6.1 Giới thiệu
-QT Virtual Framebuffer (QVFb) được cung cấp như là một phần của
gói phân phối chuẩn.QVFb cho phép chương trình Qt/Embedded có thể
được phát triển trên máy để bàn mà không cần phải chuyển giữa thiết bị xuât
nhập điều khiển và hệ điều hành window.Nó chạy như một ứng dụng window
bình thường trên máy tính để bàn nhưng lại cung cấp một bộ nhớ đệm ảo cho
các ứng dụng nhúng Qt/Embedded.Nhữn thiết bị Linux xuất vào màn hình
dùng một bộ nhớ đệm ảo và QVFb giả lập hành vi này.
-Khi QVFb được bắt đầu tạo những file mà các ứng dụng Qt/Ebedded
có thể phát hiện được và sử dụng để kết nối đến QVFb.Chuyện này cũng
được làm tương tự nếu các tập tin đã ở trên các thiết bị thật mà đã được liên
kết với bộ nhớ đệm, do đó đối với ứng dụng chạy trên QVFb cũng không có
sự khác biệt.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 49
-Nếu mà một ứng dụng nhúng chạy trên máy tính mà không sử dụng
QVFb thì màn hình sẽ có những hành vi sai lệch.Việc hiển thị có lẽ sẽ xuất
hiện như thể là nó bị tấn công bởi một virus và bất cứ thông tin nào được
hiển thị sẽ vô nghĩa.
-Để cài đặt virtual framebuffer mô phỏng màn hình embedded linux trên
PC x86 ta cần phải cài đặt tất cả 3 phiên bản Qt trên máy tính
+ Qt for x86 dùng cho việc build qvfb vỉtual framebuffer
+Qt embedded for x86 dùng cho việc build các ứng dụng
embedded linux chạy trên vỉtual framebuffer
+Qt embedded for arm dùng cho việc build ứng dụng chạy trên
board arm
source download từ http://ftp3.ie.freebsd.org/pub/trolltech/pub/qt/source/qt-
everywhere-opensource-src-4.6.2.tar.gz
Qt everywhere được dùng để build cho cả 3 phiên bản Qt (x86 và arm)
compiler arm-linux-gcc cho qt embedded
g++ cho Qt for x86
3.6.2 Qt for x86
-Giải nén gói cài đặt
Code:
$ tar xzvf qt-everywhere-opensource-src-4.6.2.tar.gz -C /
-Rename thư mục vừa cài đặt tạo thành qt-x86
-Vào thư mục qt-x86 thiết lập cấu hình,build và cài đặt
Code:
$ cd /qt-x86
$ ./configure -prefix /usr/local/qt-x86 -qvfb
$ make
$ make install
Đến đây Qt for x86 đã được cài đặt vào thư mục /usr/local/qt-x86 nhưng
QVFb vẫn chưa cài đặt.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 50
-Ta tiến hành build QVFb
Code:
$ cd /qt-x86/tools/qvfb/
$ /usr/local/qt-x86/bin/qmake qvbf.pro
$ make
Đến đây ta đã có file thực thi qvfb.
Ta có thể chỉ đuờng dẩn cho biến môi trường PATH đến /qt-x86/bin (nên làm
theo cách này) hoặc copy qvfb từ thư mục /qt-x86/bin/ vào thư mục dành
riêng cho Qt for x86 /usr/local/qt-x86/bin và chỉ PATH đến đây.
3.6.3 Qt embedded cho x86
-Cần cài đặt gói libxtst-dev, libtiff4-dev, libdbus-1*
Code:
$ apt-get install libxtst-dev
$ apt-get install libtiff4-dev
$ apt-get install libdbus-1*
-Giải nén gói cài đặt
Code:
$ tar xzvf qt-everywhere-opensource-src-4.6.2.tar.gz -C /
rename thư mục vừa tạo thành qte-x86
-Vào thư mục qte-x86 để cấu hình,build và cài đặt
Code:
$ cd /qte-x86
$ ./configure -prefix /usr/local/qte-x86 -qvfb -qt3support -debug-and-release
-system-zlib -system-libtiff -system-libpng -system-libjpeg -qt-libmng -make
libs -nomake examples -nomake demos -nis -no-cups -xplatform qws/linux-
x86-g++ -embedded x86 -depths 16,24,32 -qt-gfx-qvfb -no-gfx-linuxfb -no-
gfx-transformed -no-gfx-vnc -no-gfx-multiscreen -plugin-sql-sqlite -no-glib -
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 51
dbus -qt-kbd-qvfb -qt-mouse-qvfb
$ make
$make install
Qt embedded for x86 build xong sẽ nằm trong thư mục /usr/local/qte-x86,
nhưng sẽ không có các ví dụ lẫn demo. Để sử dụng các ví dụ lẫn demo ta
phải trở lại thư mục source /qte-x86
3.6.4 Qt Embedded cho ARM
Tiến hành cài đặt như ở phần cài đặt Qt embedded cho arm ở chương 5.
3.6.5 Demo ứng dụng với virtual framebuffer
-Bật 1 terminal để tiến hành lệnh thêm đường dẫn vào biến môi trường
Code:
$ PATH=$PATH:/qt-x86/bin
-Mở của sổ virtual framebuffer
Code:
$ qvfb
-Bật 1 terminal khác để build và chạy demo
Code:
$ cd /qte-x86/example/qws/simpledecoration
$ /usr/local/qte-x86/bin/qmake simpledecoration
$ make
$ ./simpledecoration -qws
Kết luận: virtual có thể mô phỏng hầu hết các ứng dụng liên quan
đến framebuffer của embedded linux vì cơ chế hiện thực tương đối giống
nhau. Tuy nhiên vẫn còn một số lỗi nhỏ chưa khắc phục được.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 52
3.7 TOOLCHAIN: là một tập các công cụ phần mềm cần thiết để xây dựng
các chương trình trên máy tính. Thường thì toolchain bao gồm linker,
assember, archiver, C compiler, C library và C headers.
3.7.1./Arm-Linux-Gcc
Cross-platform toolchain hay thường được gọi tắt là cross toolchain được
dùng để chạy trên platform các máy tính dùng để phát triển (development
platform – thường là các máy x86) và xây dựng chương trình để chạy trên một
platform khác. Ta sẽ sử dụng cross toolchain chạy trên platform x86, sau đó
thực hiện xây dựng các chương trình cần thiết phù hợp với kiến trúc ARM9 và
nạp lên board Friendly ARM mini2440.
Công việc đầu tiên thường là cấu hình và xây dựng một cross toolchain
thích hợp dùng để phát triển toàn bộ hệ thống. Tuy nhiên công việc này rất
phức tạp và đòi hỏi sự hiểu biết sâu sắc về sự liên quan giữa các thành phần
trong toolchain, nắm vững các chi tiết về các version của GNU toolchain và
một loạt những công việc nhàm chán khác. Thường thì việc này không dành
cho những người mới bắt đầu làm quen với việc phát triển hệ thống nhúng
Linux. Do đó hầu hết sẽ sử dụng các cross toolchain được xây dựng sẵn và
cung cấp bởi các site có uy tín. Trong đề tài này, cross toolchain được sử dụng
là bộ arm-linux-gcc phiên bản 4.3.2 được xây dựng sẵn và có trên website của
FriendlyARM. Việc chuẩn bị cross toolchain sẽ được trình bày từng bước ngay
sau đây.
- Download arm-linux-gcc-4.3.2.tgz tại địa chỉ sau:
Code:
http://www.friendlyarm.net/dl.php?file=arm-linux-gcc-4.3.2.tgz
.
- Giải nén file arm-linux-gcc-4.3.2.tgz, ở đây nó được giải nén vào thư
mục gốc /, tuy nhiên có thể giải nén vào bất cứ thư mục nào cũng được.
Code:
# tar –xvzf ./arm-linux-gcc-4.3.2.tgz –C /
- Sau khi giải nén, đường dẫn đến các file thực thi của bộ cross toolchain
này cần phải được thêm vào biết môi trường PATH để ta có thể sử dụng chúng
khi đang đứng ở bất cứ thư mục nào trên máy tính đang dùng để phát triển hệ
thống.
Code:
# gedit /home/<username>/.bashrc
Thêm dòng sau vào file .bashrc:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 53
Code:
export PATH=$PATH:/usr/local/arm/4.3.2/bin
- Sau đó, save lại và thoát chương trình gedit. Tại dòng lệnh ta gõ lệnh
bash để Terminal cập nhật biến PATH.
-Tại dòng lệnh ta có thể gõ lệnh : # arm-linux-gcc - v để kiểm tra, nếu cài
đặt đúng sẽ hiện ra hình giống phía dưới đây:
Hình 3.2 Kết quả sau khi cài thành công arm-linux-gcc
Từ đây ta đã có một bộ cross toolchain dùng để phát triển các chương trình trên
kiến trúc ARM phù hợp với board đang sử dụng.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 54
3.7.2 Cài đặt MINICOM trên Ubuntu
Vào Terminial gõ lệnh:
+sudo apt-get install minicom :Để cài đặt
+minicom –s để thiết lập thông số
Hình 3.3 Chọn port nối tiếp
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 55
Hình 3.4 Cấu hình cho port nối tiếp
+Sau khi thiết lập ta chọn Exit để thoát thiết lập
+Minicom để kết nối với board
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 56
Hình 3.5 Mở vivi
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 57
3.7.3 Thay thế vivi bằng uboot
-Kết nối với PC thông qua cổng nối tiếp ta sẽ gõ lệnh minicom ->được
màn hình như trên
-Kết nối PC với mini2440 thông qua đường USB,thông báo với vivi là ta
cần 239016 bytes Ram để load một số thứ từ USB,với địa chỉ bắt đầu là
0x31000000
Supervivi> load ram 0x31000000 239016 u
USB host is connected. Waiting a download.
-Gõ lệnh sau để download u-boot xuống RAM
$ sudo ./s3c2410_boot_usb u-boot.bin
-Sau khi gõ password ta sẽ thấy các dòng sau
csum = 0xd542
send_file: addr = 0x33f80000, len = 0x0003a5a8
Error downloading program
-Bỏ qua các lỗi đó,trở lại vivi ta sẽ thấy
Now, Downloading [ADDRESS:31000000h,TOTAL:239026]
RECEIVED FILE SIZE: 239026 (233KB/S, 1S)
Downloaded file at 0x31000000, size = 239016 bytes
-Và bây giờ ta sẽ bắt đầu tiến hành ghiuboot vào RAM
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 58
-Gõ tiếp hai lệnh sau để xem thông tin của Nand flash và xóa Nand flash:
MINI2440 # nand info
MINI2440 # nand scrub
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 59
-Tạo bảng phân vùng mới và phân vùng Nand flash dùng uboot với
các giá trị config mặc dịnh
MINI2440 # nand createbbt
MINI2440 # mtdparts
-Ghi uboot
MINI2440 # nand write 0x31000000 u-boot
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 60
3.7.4 Cài đặt giao thức truyền nhận TFTP
Boot bằng NfS, cái này thuận tiện để chúng ta viết code hơn rất nhiều. Sau đây
là các bước thực hiện:
-Cài đặt các gói tftpd-hpa, nfs-kernel-server
Code:
sudo apt-get install tftpd-hpa nfs-kernel-server
-Cài đặt uboot lên nand (already done)
-Cấu hình file /etc/exports (trên máy tính) sử dụng lệnh
Code:
sudo gedit /etc/exports
-Đưa vào đường dẫn tới thư mục chứa root_fs, vd
Code:
/home/jack/root_fs *(rw,sync,no_root_squash,subtree_check)
-Cấu hình file /etc/inet.conf (trên máy tính):
Thay đường dẫn tftp mặc định bằng đường dẫn tới thư mục chứa uImage, vd:
Code:
tftp dgram udp wait root /usr/sbin/in.tftpd /usr/
sbin/in.tftpd -s /home/cuong/root_fs
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 3: EMBEDDED LINUX GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 61
Nếu file /etc/inet.conf không tồn tại thì cấu hình trong file /etc/default/tftpd-
hpa: thay đường dẫn mặc định (/var/lib/tftp ) thành đường dẫn tới thư mục
chưa uImage.
-Cấu hình tftp, nfs cho uboot (trên board):
printenv để xem các lệnh dưới đã được set chưa rồi thêm vào nếu chưa có
Code:
setenv set_root_nfs 'setenv root_nfs root=/dev/nfs rw nfsroot=$
{serverip}:${root_nfs}'
setenv ifconfig_static 'setenv ifconfig ip=${ipaddr}:${serverip}::$
{netmask}:mini2440:eth0'
setenv set_bootargs_nfs 'run set_root_nfs; setenv bootargs $
{bootargs_base} ${bootargs_init} ${mini2440} ${root_nfs} $
{ifconfig}'
Code:
setenv bootcmd 'tftp 0x31000000 uImage;bootm 0x31000000'
(file uImage là kernel được để trong thư mục root_fs trên máy)
saveenv để lưu lại cấu hình.
set lại giá trị ipaddr, serverip, root_nfs cho phù hợp
vd:
Code:
setenv netmask 255.255.255.0
setenv ipaddr 192.168.1.85
setenv serverip 192.168.1.10
setenv root_nfs /home/cuong/root_fs
(đường dẫn tới root_fs trên máy)
-Chạy các script:
Code:
run ifconfig_static
run set_bootargs_nfs
saveenv
boot kernel bằng lệnh boot hoặc khởi động lại để chạy autoboot
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 62
CHAPTER 4
QT FEATURES
4.1. Giới Thiệu Chung
4.1.1. Qt Là Gì
Qt là bộ khung lập trình giao diện và ứng dụng xuyên các platform (cross-
platform application programming framework).Điều này được hiểu là khả năng
chạy chương trình Qt trên nhiều platform khác nhau, do đó người dùng chỉ cần
viết ứng dụng 1 lần và có thể sử dụng trên nhiều hệ điều hành nhúng khác nhau
mà không cần phải viết lại code nguồn.
Các platform mà Qt hỗ trợ như: hệ điều hành Linux nhúng (Embeded
Linux), Mac OSX, Windows, Linux/X11, Window Mobile, Window CE,
Symbian, Maemo and MeegGo.
Hình 4.1. Các Platform Qt hỗ trợ.
Các thành phần của Qt bao gồm:
Hàm giao diện lập trình ứng dụng (APIs – Application Programming
Interfaces): giao tiếp phần mềm được dùng bởi các ứng dụng khác nhau.
Bộ thư viện lớp C++ (C++ class library).
Các công cụ tích hợp cho phát triển giao diện người dùng (GUI-
Graphical User Interfaces): Qt Creator, GUI designer, IDE Integration,
cross-platform build tool.
4.1.2. Lịch Sử Của Qt
Qt được phát triển ban đầu bởi Haavard Nord (Trolltech‟s CEO) và Eirik
Chambe-Eng (Trolltech‟s President).Hai người gặp nhau ở viện công nghệ
Norwegian nơi cả hai đã lấy bằng master ngành khoa học máy tính.
Năm 1991: Haavard bắt đầu viết các lớp và cùng với Eirik trong việc thiết
kế.Vài năm sau đó, họ đã bắt đầu đưa ra khái niệm “Signals and Slots”, một trong
những mẫu lập trình GUI đơn giản và hiệu quả.
Năm 1994: họ bắt đầu đưa vào thị trường thương mại với không khách hàng,
không sản phẩm hoàn thiện. Kí tự „Q‟ được chọn như là chữ cái đầu tiên vì nó nhìn
rất đẹp trong font Emacs, còn „t‟ được viết tắt cho „toolkit‟. Công ty được thành lập
với tên ban đầu là Quasar Technologies nhưng sau đó được đổi thành Troll Tech và
ngày nay là Trolltech.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 63
Năm 1995: bản public đầu tiên Qt 0.90 được công bố. Qt có thể được sử
dụng cho cả Windows và Unix, cung cấp các API chung cho cả 2 platform. Nó được
cung cấp đồng thời 2 bản: một bản cho thương mại và một bản mã nguồn mở.
Năm 2000: Qtopica Core hay còn gọi là Qt/Embeded được phát hành.Nó
được thiết kế để chạy trên các thiết bị Linux nhúng.Vào cuối năm 2000, phiên bản
đầu tiên của Qtopia được công bố, đây là một trong các platform ứng dụng cho các
thiết bị di động và các PDAs (Personal Digital Assitants).
Năm 2005: Qt4.0 được phát hành. Với khoảng 500 classes và hơn 9000
hàm, Qt 4 lớn và mạnh hơn bất kì phiên bản nào trước đó.
Năm 2008: Nokia đã mua Qt và tên được đổi sang Qt Software sau đó là Qt
Development Frameworks.
Năm 2009/2010: tập trung vào platform di động (Symbian và Maemo).
Qt có thể dễ dàng download từ các trang web tại địa chỉ:
http://qt.nokia.com/downloads
Phiên bản được dùng trong luận văn này là Qt4.6.2
4.2. Qt Creator 4.2.1 Giới Thiệu Chung
Qt Creator là một môi trường phát triển tích hợp (IDE – Integrated
Development Environment) cung cấp nhiều công cụ cho người phát triển Qt. Nó
chạy trên các hệ điều hành Windows, Linux/X11 và Mac OSX và cho phép người
dùng tạo ra các ứng dụng chạy đồng thời trên nhiều platform khác nhau.
Một trong những điểm nổi bật của Qt Creator là khả năng cho phép một
nhóm phát triển chia sẻ một project thông qua các platform phát triển khác nhau với
một công cụ chung cho việc phát triển và debug.Ngoài ra, nó còn cho phép người
dùng chỉ ra những cài đặt dịch riêng biệt cho từng platform phát triển khác nhau.
Qt Creator được tích hợp công cụ cho việc dịch tự động thông qua qmake và
CMake.Thêm vào đó, ngoài thư viện Qt, người dùng còn có thể link ứng dụng của
mình tới các thư viện khác như thư viện hệ thống hoặc thư viện của người dùng. Khi
đó, để dịch project của mình, người dùng cần phải add thêm các thư viện đó vào
trong project.Thủ tục thêm các thư viện tùy thuộc vào hệ thống build mà người dùng
sử dụng.
Qt Creator còn hỗ trợ việc dịch và chạy các ứng dụng cho môi trường
desktop và thiết bị di động.Khi chúng ta cài đặt gói Nokia Qt SDK, việc cài đặt và
chạy cho các mục tiêu Maemo và Symbian được tự động.Tuy nhiên, chúng ta nên
cài đặt và cấu hình thêm một số phần mềm trên thiết bị.
Lưu ý: Hệ thống dịch duy nhất được hỗ trợ cho các ứng dụng di động trong Qt
Creator là qmake.
Khi ứng dụng di động đã sẵn sàng, người dùng có thể kiểm tra kết quả thông
qua bộ mô phỏng Qt Simulation.Sau khi kiểm tra, ứng dụng có thể sử dụng trên các
thiết bị di động.
Tuy nhiên, cần lưu ý rằng việc phát triển các ứng dụng cho các thiết bị di
động khác so với phát triển ứng dụng trên desktop.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 64
4.2.2. Các Thành Phần Của Qt Creator
Hình 4.2. Các thành phần của Qt Creator
* Projects
Tại sao chúng ta phải cần projects?
Để có thể dịch và chạy các ứng dụng,Qt Creator cần một thông tin như
nhau giống như các bộ dịch compiler cần.Thông tin này được chỉ ra trong cách cài
đặt và chạy chương trình của project.
Việc tạo ra một project cho phép chúng ta:
Nhóm các files với nhau
Thêm bước dịch đối tượng
Thêm các forms và resource files
Chỉ ra cách cài đặt cho việc chạy ứng dụng
Khi tạo một project, Qt Creator sẽ tạo ra các file cần thiết tùy thuộc vào loại
project mà chúng ta muốn tạo.
Ví Dụ:
Khi tạo một ứng dụng GUI (Graphical User Interface) , Qt sẽ sinh ra 5 files cơ
bản : “main.cpp”;”name.cpp”;”name.h”;”name.pro”;”name.ui”
Trong đó, file “name.ui” có thể chỉnh sửa bởi người dùng thông qua công cụ tích
hợp Qt Designer.
* Editors
Công cụ biên tập của Qt Creator bao gồm: 1 biên tập code (Code Editor) và
2 biên tập visual tích hợp cho việc thiết kế và dịch các ứng dụng GUI từ các đối
tượng của Qt.
- Code Editor:
Vì là một IDE, điểm khác biệt cơ bản giữa Qt Creator và biên tập văn
bản (text editor) là nó biết cách dịch và chạy một ứng dụng.Điều đó được hiểu ngôn
ngữ C++ và QML như là code chứ không phải là văn bản thuần túy.Vì thế:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 65
Viết các lệnh đúng format
Hiểu những gì người dùng đang viết và hoàn thành lệnh
Hiển thị lỗi và thông tin cảnh báo theo dòng.
Cho phép định hướng theo lớp, hàm và biểu tượng.
Đổi tên biểu tượng theo một cách thông minh vì thế các biểu tượng
cùng tên khác thuộc các phạm vi khác không phải đổi tên.
Hiển thị vùng lệnh mà hàm được khai báo và được gọi.
*UI Designer
Qt Creator cung cấp 2 công cụ visual editor tích hợp gồm: Qt Designer và
Qt Quick Designer.
Qt Designer là một công cụ dùng để thiết kế và dịch chương trình GUI từ
các đối tượng con của Qt (Qt Widgets).Widget và form được tạo bởi Qt Designer
được tích hợp cùng với code và sử dụng kĩ thuật “signals & slots” cho phép người
lập trình dễ dàng thay đổi các kết nối của các tác vụ tương ứng của thành phần
graphic với các hàm tương ứng.Tất cả các đặc tính được cấu hình trong Qt Designer
có thể thay đổi dễ dàng bằng code.Thêm nữa, các đặc tính của widget cho phép
chúng ta tạo ra các đối tượng con widget cho riêng mình.
Đối với Qt Quick Designer, nó cho phép chúng ta dễ dàng phát triển các
hiệu ứng bằng cách sử dụng các ngôn ngữ lập trình khai báo gọi là QML (Qt Meta-
Object Language).Trong QML, giao tiếp người dùng được chỉ ra như là cái cây của
các đối tượng với các thuộc tính của nó.Chúng ta có thể dùng bộ biên tập visual để
tạo ra các mẫu, màn hình và các ứng dụng cũng như định nghĩa các trạng thái, quá
trình chuyển từ trạng thái này sang trạng thái khác và tác vụ người dùng để thay đổi
các trạng thái đó.Qt Quick Designer sẽ sinh ra các lệnh tương ứng.
* Languages Người lập trình có thể sử dụng bộ biên tập lệnh với ngôn ngữ C++ hoặc
ngôn ngữ lập trình khai báo QML.
QML hay Qt Metal- Object Language là ngôn ngữ khai báo, dựa trên Java
Script cho việc thiết kế giao diện người dùng.Nó được sử dụng cho các ứng dụng di
động mà ở đó hiệu ứng, ngõ vào touch là chủ yếu.
* Qt Simulator
Được sử dụng để mô phỏng và chạy thử các ứng dụng Qt trong môi trường
PC tương tự như môi trường trên các thiết bị di động.Nó được cài đặt như một phần
của gói Nokia Qt SDK.
* Debuggers: Cho phép kết nối tới các debugger để debug chương trình.
4.2.3. Tạo Project Trong Qt Creator
Việc mở Qt Creator được bắt đầu với Welcome Mode, cho phép người dùng:
Mở tutorial và các ví dụ minh họa.
Xem các thủ thuật trong việc sử dụng Qt.
Tạo và mở project.
Mở các project gần đây.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 66
Chúng ta có thể sử dụng chọn lựa mode (Mode Selector) để thay đổi các
mode của Qt.
Giao diện của Qt:
Hình 4.3. Giao diện chính của Qt Creator
Chúng ta có thể sử dụng Qt dưới các modes sau:
1. Edit Mode: biên tập project và source code.
2. Design Mode: thiết kế và phát triển các ứng dụng giao diện người dùng.
3. Debug Mode: kiểm tra trạng thái của chương trình trong khi thực hiện
debug.
4. Projects Mode: cấu hình việc build và thực thi project. Mode này được
cho phép khi project được mở.
5. Help Mode: xem các tài liệu về Qt
Để tạo 1 project mới trong Qt Creator: File New Project.
Khi tạo một project, Qt Creator cho phép nhiều lựa chọn khác nhau: QML
Application, Empty Qt 4 Project, Qt 4 Gui Application, Qt4 Console Application,
C++ Library,…Tuy nhiên ở đây chúng ta chỉ sử dụng ứng dụng Qt 4 Gui
Application. Khi đó Khi đó Qt tự động sinh ra 5 files mặc định : “main.cpp”;“name.cpp”;”name.h”;”name.pro”;”name.ui”
Giao diện cây thư mục khi tạo Qt4 Gui Application.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 67
Hình 4.4. Giao diện cây thư mục khi tạo Qt 4 Gui
Mỗi file có một chức năng riêng:
File Mô Tả main.cpp Thực hiện khởi tạo và chạy ứng dụng name.h Định nghĩa các lớp, đối tượng, các hàm slots,…sử dụng
trong chương trình name.cpp Định nghĩa các tác vụ của các đối tượng, các hàm,… name.ui Thiết kế giao diện UI name.pro Chứa thông tin liên kết giữa các file để build chương
trình
Hình 4.5. Bảng giới thiệu sơ lược chức năng các file trong project * Ngõ Ra Output
Tồn tại trong tất cả các modes và nhấn Alt+F9 cho phép mở rộng tối đa màn
hình Output.
Ngõ ra bao gồm các chức năng và thông tin: Build Issuse, Search Results,
Application Output, Compile Output, General Messages và Version Control.
Build Issues: cung cấp thông tin về lỗi cũng như các cảnh báo trong
quá trình dịch chương trình.Việc sắp xếp các lỗi theo thứ tự và thể hiện vị trí của
lỗi trong file nào, hàng mấy.
Hình 4.6. Giao diện Build Issues.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 68
Search Results: Cho phép hiển thị kết quả của quá trình tìm kiếm
trong phạm vi file hiện tại hay file trên đĩa hay toàn projects.
Hình 4.7. Giao diện Search Results
Application Output: Hiển thi trạng thái của chương trình khi nó được
thực thi và ngõ ra debug
Hình 4.8. Giao diện Application Output
Compile Output: cung cấp tất cả các thông tin ngõ ra của bộ dich
complier.Ngõ ra Compiler là thông tin chi tiết được hiển thị trong Build Issues.
Hình 4.9. Giao diện Compile Output
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 69
4.3. Xây Dựng Một Ứng Dụng UI 4.3.1. Signals và Slots
- Signal and Slot là một trong những đặc tính nổi bật của Qt. Nó được sử
dụng để liên kết hay giao tiếp giữa các đối tượng (object) với nhau.
Ví dụ:
Khi nhấn click button Close, chúng ta muốn hàm close() được gọi.
- Đặc trưng cơ bản của Signals và Slots:
Trong Qt, Signal là tín hiệu được sinh ra khi có một sự kiện cụ thể
tương ứng xảy ra. Slot là một hàm được gọi để đáp ứng với tín hiệu cụ thể đã được
sinh ra.Như vậy, khi một tín hiệu được sinh ra nó sẽ gọi tới hàm slot tương ứng.
Mỗi đối tượng có rất nhiều các signals và slots được định nghĩa trước.
Hình 4.10. Mô tả quan hệ giữa Signal và Slot
Tất cả các lớp thừa kế từ QObject hay các lớp con của nó (QWidget) có
thể chứa signal và slot. Signal được sinh ra bởi đối tượng khi nó thay đổi trạng thái
mà ảnh hưởng tới các đối tượng khác. Slot có thể dùng để nhận signal nhưng nó có
thể làm hàm thành viên bình thường.
Người dùng có thể kết nối nhiều signal tới 1 slot và 1 signal tới nhiều
slots thậm chí có thể 1 signal trực tiếp tới 1 signal khác.
- Cách khai báo kết nối giữa signals và slots:
Cách 1: Thực hiện trong Qt Desinger (Mục 4.3.2)
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 70
Cách 2: Thực hiện định nghĩa thủ công trong chương trình bằng cách sử
dụng QObject::connect() và các macros SIGNAL(), SLOT(). (Mục 4.3.3)
4.3.2. Xây dựng UI bằng Qt Designer
Có 4 bước cơ bản để xây dựng một project với Qt designer
1. Lựa chọn form và đối tượng.
2. Đặt các đối tượng trên form (quá trình này gọi là Layout đối tượng).
3. Liên kết giữa signals và slots.
4. Thực hiện dịch và chạy ứng dụng.
Trong mục này, giả sử rằng chúng ta cần thiết kế một đối tượng nhỏ chứa
các nút điều khiển các giá trị màu RGB (Red, Green, Blue) như sau:
Hình 4.11. Giao diện UI cần thiết kế
Bước 1: Lựa chọn form và các đối tượng
Chúng ta chọn Widget từ hộp thoại New Form
Hình 4.12. Lựa chọn Widget từ New Form
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 71
Bước 2: Đặt các đối tượng con (widget) lên Form
Thực hiện khá đơn giản bằng cách nhấp chuột giữ các đối tượng từ cột bên
trái chứa chúng và thả vào form.
Để thay đổi nhãn của các text, nhấp đúp vào đối tượng và thay đổi.Chúng ta
có thể sắp xếp các đối tượng theo thứ tự mong muốn.
Hình 4.13. Đặt các đối tượng lên Form
Sử dụng chuột để chọn các đối tượng: Label, Spinbox và Slider ở cột bên
trái và kéo qua màn hình Form bên phải như trên.
Để đảm bảo rằng các đối tượng được đặt trên form một cách chính xác như
mong muốn, chúng ta cần phải đặt các đối tượng vào các lớp layout bằng các lớp
Layout khác nhau như: QVBox Layout (sắp xếp theo hàng dọc), QHBox Layout (
sắp xếp theo hàng ngang), QGrid Layout ( sắp xếp thành dạng lưới ma trận).
Trong ví dụ này, chúng ta sắp xếp các đối tượng theo 3 nhóm tương ứng với
3 màu.Lựa chọn nhãn “RED” sau đó nhấn Ctrl để chọn các đối tượng spinbox và
slider trong cùng nhóm với “RED” label và sau đó chọn kiểu Grid Layout.
Thực hiện cách Layout này cho hai nhãn còn lại cùng với các đối tượng liên
quan.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 72
Hình 4.14. Cách Layout các đối tượng trên Form
Cần để ý rằng, chúng ta mới chỉ thực hiện Layout cho từng nhòm riêng rẽ.Vì
thế, bước tiếp theo là kết hợp tất cả các Layout vào trong cùng một mainLayout
duy nhất.
MainLayout là lớp trên cùng cao nhất của layout đối tượng.Quá trình layout
lớp trên cùng này đảm bảo rằng các đối tượng trong cửa sổ sẽ không bị thay đổi kích
thước khi cửa sổ bị thay đổi kích thước (ex: zoom in, out,…).
Để thực hiện cài đặt Layout cho lớp trên cùng, nhấp chuột bất kì tại vị trí
nào trên Form và bên ngoài cả 3 layout riêng biệt trên.Sau đó, lựa chọn kiểu Layout
(ex: Layout Horizontally)
Hình 4.15. Layout tất cả các đối tượng trên Form
Lưu ý rằng, mainLayout không thể quan sát trên form. Cách đơn giản để
kiểm tra việc thực hiện mainLayout là cố gắng thay đổi kích thước form, các đối
tượng con trên form cũng sẽ thay đổi theo kích cỡ tỉ lệ tương ứng. Ngoài ra, chúng
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 73
ta có thể quan sát điều này thông qua Qt Designer‟s Object Inspector. Nếu quá trình
mainLayout chưa được thực hiện, chúng ta có thể thấy biểu tượng layout bị gãy kế
bên biểu tượng form như
Bước 3: Liên kết giữa Signals và Slots
Việc định nghĩa signals và slots đã được đề cập ở trên.
Trong ví dụ này, khi nhấn kéo slider để thay đổi tới một giá trị xác định,
chúng ta muốn rằng hộp thoại spinbox sẽ cập nhật vị trí của slider bằng cách hiển thị
giá trị tương ứng.Thêm nữa, signal valueChanged() được sinh ra mỗi khi slider
thay đổi vị trí và slot setValue() tương ứng của spinbox. Do đó, để thay đổi được
đáp ứng này, chúng ta cần thực hiện liên kết giữa tín hiệu valueChanged() của slider
tới slot setValue() của spinbox.
Cách đơn giản để thực hiện trong Qt Designer bằng cách click chuột phải
lên đối tượng slider và lựa chọn hộp thoại Configure Connection xuất hiện
Trong hộp thoại này, ta thực hiện lựa chọn các slot tương ứng cho các signal và
nhấn OK.
Hình 4.16. Thực hiện liên kết Signals & Slots trong Qt Designer
Bước 4: Thực hiện dịch và chạy chương trình
Bằng cách lựa chọn các Icon: RUN, BUILD hoặc từ mục Build Build All
4.3.3. Xây Dựng UI Bằng Dòng Lệnh
Ở đây, việc định nghĩa các đối tượng cũng như quan hệ signals và slots
hoàn toàn dựa trên mã code.
Như trên đã nói, khi tạo một project Qt4 Gui Application, Qt Creator tự
động sinh ra các file cần thiết: “name.ui”,“name.cpp”,“name.h”,“main.cpp”, “name.pro”
Tuy nhiên vì định nghĩa UI bằng dòng lệnh chúng ta chỉ cần quan tâm tới 3
file: “name.ui”, “name.cpp” và “name.h”
Có 3 bước cơ bản:
Bước 1: Định nghĩa các class, đối tượng trowng hàm “name.h”
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 74
Để định nghĩa được các đối tượng (widget), cần phải include các thư viện
tương ứng.
Ví dụ:
Để sử dụng button #include <qpushbutton.h>
Trong “name.h” chúng ta cần phải khai báo các hàm (slots) và các đối tượng
(widget) trong chương trình
Ví dụ: Định nghĩa các button: addButton, subtractButton,…
Và các slots: add(), subtract(),…
Hình 4.17. Ví dụ về định nghĩa các đối tượng và slots
Bước 2: Viết điều khiển trong hàm “name.cpp”
Đây là nơi chúng ta thực hiện tất cả các tác vụ từ định nghĩa các widgets,
layout cho từng đối tượng (sắp xếp chúng trên giao diện), liên kết các signals và
slots thực hiện các hàm,…
Do việc lập trình là lập trình hướng đối tượng nên cấu trúc lệnh hoàn toàn
dựa trên lớp (class) đối tượng (object), đặc tính (property), tính kế thừa
(inheritance)…
Các bước lập trình một đối tượng:
Include các thư
viện tương ứng
Định nghĩa các slots
(function)
Khai báo các đối
tượng.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 75
Định nghĩa đối tượng cũng như các thuộc tính:
Ví dụ:
Định nghĩa các button với các tên: cộng, trừ, nhân, chia và close
Hình 4.18. Ví dụ về khai báo các button
Định nghĩa các signals và slots:
Format: Connect (Sender, SIGNAL(), Receiver, SLOT())
Ví dụ:
Giả sử khi button Stop được nhấn sinh ra signal: clicked() hàm slot:
close() tương ứng được gọi.
Cách khai báo: Connect (stopButton, SIGNAL(clicked()),this, SLOT(close()));
Hình 4.19. Ví dụ về khai báo liên kết signal & slot
Thực hiện sắp xếp các đối tượng (widgets) trên giao diện:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 76
Hình 4.20. Ví dụ về Layout các đối tượng lên form
Figure: Layout các đối tượng trên Form bằng dòng lệnh
QVBoxLayout: sắp xếp các đối tượng theo hàng dọc.
QHBox Layout: sắp xếp các đối tượng theo hàng ngang.
QGridLayout: chia không gian thành dạng lưới ma trận với các giá trị hàng và cột
tương ứng.
Thực hiện định nghĩa các hàm slots tương ứng:
Ví dụ:
Thực hiện hàm add() cộng 2 giá trị nhập vào 2 ô từ bàn phím và xuất kết quả
lên ô thứ 3.
Hình 4.21. Định nghĩa Slot add()
Bước 3: Thực hiện Buid và Run ứng dụng
Khi thực hiện chạy trên PC, Qt tự động tạo liên kết và trả về kết quả
khi nhấn một trong các cách:
Build Build All
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 77
Icon
Lưu ý:
Cả 2 cách tạo file UI ở trên chỉ khác nhau ở 1 điểm duy nhất: một cách tạo
file UI bằng Qt Designer và một cách tạo file UI bằng dòng lệnh (thủ công). Việc sử
dụng Qt Designer làm cho việc thiết kế đơn giản hơn nhưng việc định nghĩa thủ
công bằng dòng lệnh cho phép dễ dàng sử dụng các hàm đặc biệt của Qt để tạo ra
các đối tượng con mong muốn cho người dùng ( sử dụng hàm vẽ tạo đồng hồ, bàn
phím,…).
Cách viết các file còn lại: định nghĩa các hàm slots, build, run, … là giống
nhau.
4.4. Một Số Ví Dụ Điển Hình Bài toán 1: Máy tính đơn giản: Simple Calculator
Nhập 2 số hạng từ bàn phím hiển thị lên 2 ô và thực hiện các phép toán số
học cộng, trừ, nhân, chia và hiển thị kết quả lên ô thứ 3.
Lưu ý: phép chia với 0 báo lỗi
Hàm “calculator.h”
#ifndef CACULATOR_H
#define CACULATOR_H
#include <QWidget>
#include <qapplication.h>
#include <qobject.h>
#include <qlineedit.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qtextedit.h>
class Caculator : public QWidget
{
Q_OBJECT
public:
Caculator(QWidget *parent = 0);
public slots:
void add();
void subtract();
void nhan();
void chia();
void close();
private:
QPushButton *addButton;
QPushButton *subtractButton;
QPushButton *nhanButton;
QPushButton *chiaButton;
QPushButton *closeButton;
QLineEdit *firstline;
QLineEdit *secondline;
QLineEdit *thirdline;
};
#endif // CACULATOR_H
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 78
Hình 4.22. Cách viết file header “calculator.h”
(định nghĩa các widgets & slots)
Hàm “calculator.cpp”
#include "caculator.h"
#include "ui_caculator.h"
#include <QtGui>
#include <qapplication.h>
#include <qobject.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qmessagebox.h>
#include <qstring.h>
double input1,input2;
double output;
Caculator::Caculator(QWidget *parent) :
QWidget(parent)
{
// create label
QLabel *label = new QLabel(tr("First Element:"));
firstline = new QLineEdit;
QLabel *Secondlabel = new QLabel(tr("Second Element:"));
secondline = new QLineEdit;
QLabel *Answerlabel = new QLabel(tr("Answer:"));
thirdline = new QLineEdit;
thirdline->setReadOnly(true);
// make new button
addButton = new QPushButton(tr("&Cong"));
addButton->show();
subtractButton = new QPushButton(tr("&Tru"));
subtractButton->show();
nhanButton = new QPushButton(tr("&Nhan"));
nhanButton->show();
chiaButton = new QPushButton(tr("&Chia"));
chiaButton->show();
closeButton = new QPushButton(tr("&Close"));
closeButton->show();
// make signals and slots
connect(addButton, SIGNAL(clicked()),this,SLOT(add()));
connect(subtractButton,SIGNAL(clicked()),this,SLOT(subtract()));
connect(nhanButton,SIGNAL(clicked()),this,SLOT(nhan()));
connect(chiaButton,SIGNAL(clicked()),this,SLOT(chia()));
connect(closeButton,SIGNAL(clicked()),this, SLOT(close()));
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 79
Hình 4.23. Khai báo các widget và liên kết signal & slot
void Caculator::add()
{
input1 = firstline->text().toDouble();
input2 = secondline->text().toDouble();
output = input1 + input2;
thirdline->setText(QString::number(output));
}
void Caculator::subtract()
{
input1 = firstline->text().toDouble();
input2 = secondline->text().toDouble();
output = input1 - input2;
thirdline->setText(QString::number(output));
}
void Caculator::nhan()
{
input1 = firstline->text().toDouble();
input2 = secondline->text().toDouble();
output = input1 * input2;
thirdline->setText(QString::number(output));
}
// Layout widgets
QVBoxLayout *buttonLayout1 = new QVBoxLayout;
buttonLayout1->addWidget(addButton,Qt::AlignTop);
buttonLayout1->addWidget(subtractButton);
buttonLayout1->addWidget(nhanButton);
buttonLayout1->addWidget(chiaButton);
buttonLayout1->addStretch();
QHBoxLayout *buttonLayout2 = new QHBoxLayout;
buttonLayout2->addWidget(closeButton);
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(label,1,0);
mainLayout->addWidget(firstline,1,1);
mainLayout->addWidget(Secondlabel,2,0);
mainLayout->addWidget(secondline,2,1);
mainLayout->addWidget(Answerlabel,3,0,Qt::AlignTop);
mainLayout->addWidget(thirdline,3,1);
mainLayout->addLayout(buttonLayout1,2,3);
mainLayout->addLayout(buttonLayout2,4,1);
setLayout(mainLayout);
setWindowTitle(tr("Simple Calculator"));
}
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 80
Hình 4.24. Khai báo các hàm slots
* Kết Quả:
Hình 4.25. Giao diện Simple Calculator
4.5. Cách Build Chương Trình Qt Lập Trình Cho ARM Qt là một công cụ phát triển ứng dụng GUI của nokia cho các thiết bị di động
và máy tính để bàn, thông tin tham khảo tại qt.nokia.com
Download phiên bản qt embedded 4.5.3 về máy và giải nén, thực hiện theo
các bước sau: Code:
void Caculator::chia()
{
input1 = firstline->text().toDouble();
input2 = secondline->text().toDouble();
if ( input2 == 0){
QMessageBox::warning( this, "warning",
"the second element can't be 0.\n"
"This program can't function correctly.\n ",
"Retry",
"Quit", 0, 0, 1);
}
else{
output = input1/input2;
thirdline->setText(QString::number(output));
}
}
void Caculator::close(){
close();
}
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 81
./configure -embedded arm -xplatform qws/linux-arm-
g++ -prefix /Qt -qt-mouse-tslib -little-endian
- Chỉnh sửa lại file /mkspecs/qws/linux-arm-g++
Code:
gedit /mkspecs/qws/linux-arm-g++
Thêm vào thiết lập: QMAKE_INCDIR =
/home/jack/build_test/toolchain/tslib/tslib/build/include
QMAKE_LIBDIR =
/home/jack/build_test/toolchain/tslib/tslib/build/lib
Hoặc copy trực tiếp từ thư mục build của tslib các thư viện cần thiết bỏ qua
thư mục lib của qt. make
make install
cp -a /qt/* /root_fs/
Thay đổi lại file ....
Lên mạng down thêm thư viện libg++.so bỏ vào thư mục lib.
Thưởng thức các ví dụ có sẳn trong thư mục /qt/example/qws/.
* Build Thêm Thư Viện Liên Kết Để lập trình và kết hợp với touch screen của board thi trên hệ điều hành
nhúng chúng ta phải cần cài thêm và build lại hai thư viện quan trọng là “tslib” và
“qtlib”.
Các bước build đồng thời cả hai thư viện:
install: autoconf libtool
Code:
#sudo apt-get install autoconf libtool
Download tslib-1.0 bỏ vào một thư mục mình
chọn:~/build_test/toolchain
Vào làm việc trong thư mục giải nén chứa tslib
Code:
#cd build_test/toolchain/tslib/tslib
Mở file autogen.sh và chỉnh sửa
Code:
#./atugen.sh
#gedit./configure
Sửa "ac_cv_func_malloc_0_nonnull=no" ===>
"ac_cv_func_malloc_0_nonnull=yes"
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 82
Thêm vào biến môi trường đường dẫn :
Code:
# export CC=arm-linux-gcc
# export CXX=arm-linux-g++
Chạy lệnh config để chuẩn bị build và install
Code:
#./configure --build=i386-linux --host=arm-linux --
target=arm --disable-inputapi --prefix=$PWD/build
# make
#make install
Chạy xong vao thư mục ./build copy toàn bộ nội dung bỏ qua
root_fs/lib và root_fs/bin riêng thư mục /include bỏ vào /usr/include.
Sửa lại cac file config
+ ts.conf: Bỏ comment dòng "module_raw input"
+ Thêm đoạn script sau vào file /etc/profile
export TSLIB_TSDEVICE=/dev/input/event0
export TSLIB_CALIBFILE=/etc/pointercal
export TSLIB_CONFFILE=/etc/ts.conf
export TSLIB_PLUGINDIR=/lib/ts
export TSLIB_FBDEVICE=/dev/fb0
export TSLIB_CONSOLEDEVICE=none
Vào thư mục /lib/ sửa lại file tslib.la trong đó có đường dẫn
libdir thành /lib. Vào thư muc /lib/ts sửa tất cả các file đuôi .la có đường dẫn libdir
thành /lib.
Vào thư muc pkgconfig sua file tslib-0.0.pc thành
prefix=/rootfs
exec_prefix=${prefix}
libdir=${prefix}/lib
includedir=${prefix}/usr/include
Name: tslib
Description: Touchscreen Access Library
Version: 0.0.2
Libs: -L${libdir} -lts
Cflags: -I${includedir}
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 4: QT GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 83
Khởi động lại hệ thống là hoàn thành và có thể chạy file để test:
Code:
./ts_test
* Build qtlib:
Code:
# gedit mkspecs/qws/linux-arm-g++/qmake.conf
# ./configure -embedded arm -xplatform qws/linux-arm-g++ -
prefix /usr/local/Qt -qt-mouse-tslib -ttle-endian -L
/home/jack/arm/tslib/lib/ -I
/home/jack/arm/tslib/usr/include/
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 84
CHAPTER 5
DEVICE DRIVERS
5.1. Giới Thiệu Chung 5.1.1. Vai Trò Của Device Drivers
Hệ điều hành thường là một lĩnh vực bí hiểm mà các lệnh được giới
hạn cho một số nhỏ người lập trình. Tuy nhiên, một trong những tiện ích lớn
nhất của hệ điều hành mở như Linux là khả năng cho phép chúng ta có thể
nhìn, đọc, hiểu và chỉnh sửa các phần bên trong nó. Devicer driver cung cấp
công cụ để làm việc đó.
Device Drivers đóng một vai trò đặc biệt trong nhân Linux (Linux
Kernel). Nó được coi là những hộp đen “black boxes” và làm cho phần cứng
thực thi những hàm API được định nghĩa sẵn trong kernel. Chúng giấu hoàn
toàn các chi tiết về cách thiết bị hoạt động.
Cần chú ý, device drivers cần phải đảm bảo tính linh động “flexible”
vì chức năng của nó là cung cấp phương thức (mechanism) chứ không phải
luật (policy). Cụ thể hơn, một driver được gọi là linh động nếu nó cung cấp
cách truy cập hardware mà không có sự ép buộc nào. Do đó, khi viết drivers,
người lập trình cần nhớ một khái niệm cơ bản đó là: viết lệnh kernel để truy
cập phần cứng (hardware) nhưng không được đặt ra một luật cụ thể nào cho
người dùng vì mỗi người sử dụng có nhu cầu khác nhau. Drivers phải làm
cho phần cứng hoạt động và chuyển cách sử dụng phần cứng tới ứng dụng
người dùng (applications). Tuy nhiên, thỉnh thoảng một số luật cũng cần
được đặt ra.
Ví dụ:
Digital I/O driver có thể chỉ cho phép truy cập hardware theo byte để
tránh trường hợp lệnh ngoài (extra code), những lệnh cần cho xử lí từng bit
riêng rẽ.
Ngoài ra, chúng ta cũng có thể nhìn driver ở một quan điểm khác: nó
chính là lớp phần mềm nằm giữa ứng dụng người dùng (applications) và thiết
bị thực (actual device). Các drivers khác nhau cung cấp các khả năng khác
nhau thậm chi cho cùng một thiết bị nên khi thiết kế một driver thực tế cần
phải xem xét nhiều yếu tố khác nhau. Trong đó, việc cân bằng giữa nhiều lựa
chọn khác nhau cho người dùng và thời gian viết cũng như mong muốn đơn
giản hóa là một trong những điều cần xem xét chính.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 85
Hình 5.1. Vị trí của Device Drivers
5.1.2. Cấu Trúc Nhân Kernel
Trong hệ thống Unix tồn tại nhiều quá trình (processes) khác nhau với
các tác vụ khác nhau được chạy cùng lúc. Mỗi một process đòi hỏi tài nguyên
hệ thống, bộ nhớ, kết nối mạng hoặc các tài nguyên khác. Vì vậy, kernel làm
nhiệm vụ đáp ứng cho các yêu cầu đó. Chúng có nhiệm vụ tạo ra, xóa bỏ các
process và quản lí các kết nối của nó với bên ngoài cũng như giao tiếp giữa
các process với nhau. Chúng ta có thể phân chia chức năng của kernel tương
đối thành các phần như sau:
* Quản lí quá trình (Process Management)
Quản lí hệ thống có nhiệm vụ điều khiển cách các process chia sẻ
CPU hay nói cách khác là nhiều process trên cùng một CPU.
* Quản lí bộ nhớ (Memory Management)
Bộ nhớ máy tính là một nguồn tài nguyên chính và việc sử dụng
chúng yêu cầu các luật chặt chẽ. Kernel xây dựng một không gian địa chỉ ảo
cho tất cả các quá trình. Các phần khác nhau của kernel giao tiếp với hệ
thống thứ cấp quản lí bộ nhớ thông qua các hàm từ những hàm đơn giản như
malloc/free,…
* Hệ thống File( File System)
Unix được xây dựng dựa trên khái niệm file hệ thống (filesystems)
nghĩa là hầu hết mọi thứ trên Unix đều có thể coi như một file. Kernel xây
dựng một hệ thống file có cấu trúc trên nền của các phần cứng không cấu
trúc. Linux hỗ trợ nhiều kiểu file hệ thống khác nhau, các kiểu này khác nhau
cách sắp xếp tổ chức dữ liệu.
Ví dụ: ổ đĩa được định dạng theo chuẩn linux ext3 filesystem
* Điều khiển thiết bị (Device Control)
Hầu hết các hoạt động của hệ thống được ánh xạ tới các thiết bị vật lí.
Ngoại trừ vi xử lí và bộ nhớ, các hoạt động điều khiển thiết bị được thể hiện
bởi lệnh cụ thể tới các thiết bị được định địa chỉ. Các lệnh này gọi là device
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 86
driver. Kernel phải nhúng vào trong nó các driver của mọi ngoại vi trên hệ
thống từ các đĩa cứng, bàn phím,…
* Kết nối mạng (Networking)
Kết nối này phải được quản lí bởi hệ điều hành bởi vì hầu hết các hoạt
động mạng không được cụ thể tới một quá trình nào.
Ví dụ:
Gói packets được truyền tới là một sự kiện bất đồng bộ. Do đó, nó phải
được thu nhận, xác định trước khi các quá trình xử lí.
Hình 5.2. Cấu Trúc nhân Kernel
5.1.3. Loadable Modules
Một trong những đặc tính hay của Linux là khả năng cho phép mở
rộng tại thời điểm chạy. Điều này được hiểu là chúng ta có thể thêm các chức
năng vào kernel hoặc loại bỏ chúng trong khi hệ thống đang chạy.
Mỗi đoạn code được add vào kernel tại thời điểm chạy được gọi là
một module. Linux kernel hỗ trợ một số kiểu khác nhau của modules trong
đó có device drivers. Mỗi module được tạo ra từ object code (chưa được link
tới file thực thi hoàn tất). Chúng có thể dễ dàng kết nối tới kernel đang chạy
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 87
thông qua chương trình insmod và ngắt kết nối thông qua chương trình
rmmod.
Hình 5.3. Loadble Modules
5.1.4. Sự Phân Chia Devices và Modules
Linux phân chia thiết bị thành 3 nhóm chính:
Character devices
Block device
Network interface.
* Character Device
Device được truy cập như một byte stream (giống như một file) và
truy cập tuần tự. Char driver của character device có nhiệm vụ thực hiện chức
năng này. Nó thường bao gồm ít nhất các hàm hệ thống như: open,
close, read and write.
Char device được truy cập thông qua node file hệ thống (filesystem
nodes) như /dev/tty1 và dev/lp0.
Điều khác nhau duy nhất giữa char device and file thông thường là
chúng ta chỉ có thể truy cập tuần tự đối với char device.
* Block Device
Giống như char device, block device được truy cập bởi nút hệ thống
(filesystem) trong thư mục /dev. Một block device là thiết bị có thể sở hữu
một file hệ thống. Trong hầu hết các hệ thống Unix, thao tác I/O được thực
hiện theo dạng block thường là 512bytes/ block.
Tuy nhiên, Linux cho phép người dùng có thể đọc hoặc ghi một block
device giống như char device. Kết quả là, block device và char device chỉ
khác nhau ở 1 điểm duy nhất là cách dữ liệu được lưu trữ nội bởi kernel.
* Network Device
Thể hiện dưới dạng các interface do đó nó là một thiết bị có thể trao
đổi dữ liệu với các host khác. Thông thường, các interface là các thiết bị phần
cứng như NIC ( Network Interface Card) hoặc có thể là thiết bị phần mềm
thuần túy như một interface ảo (loopback interface).
Một giao tiếp mạng (network interface) làm nhiệm vụ gửi và nhận dữ
liệu dạng packets. Driver của network device chủ yếu xử lí dữ liệu theo
Kernel at
runtime Loadable
Modules
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 88
packets mà không cần quan tâm đến các tầng cao hơn như connection của
TCP. Việc giao tiếp giữa kernel và network driver hoàn toàn khác so với char
và block driver. Thay vì sử dụng các hàm hệ thống như read và write,
chúng sử dụng các hàm hệ thống liên quan đến việc chuyển packets.
Tóm lại, ngoại trừ network device, các device khác được truy cập
thông qua một loại file đặc biệt gọi là device file. Device file không giống
như file thông thường khác ở điểm các truy cập vào device file sẽ được thực
hiện bởi các hàm tương ứng do driver cung cấp thay vì truy xuất đĩa như các
file thông thường.
5.1.5. User Space và Kernel Space
Bộ nhớ hệ thống trong Linux có thể được chia ra làm 2 vùng riêng biệt:
Kernel space: nơi mà nhân chạy và cung cấp các dịch
vụ của nó.
User space: vùng nhớ nơi các quá trình của người dùng
(user processes) thực thi.
Kernel space có thể được truy cập bởi các user processes thông qua sử
dụng các hàm hệ thống (system calls). Theo lí thuyết hệ điều hành, một
module chạy trong kernel space trong khi đó ứng dụng (application) chạy
trong user space. Unix sẽ chuyển thực thi từ user space sang kernel space khi
các ứng dụng gọi tới các system calls hoặc bị dừng bởi các ngắt phần cứng.
Các ứng dụng thường chạy theo tuần tự từ bắt đầu tới kết thúc và không
quan tâm tới bất cứ điều gì xảy ra có thể thay đổi môi trường của nó. Kernel
Code được xây dựng trên ý tưởng nhiều processes có thể chạy cùng lúc, sử
dụng một driver tại cùng thời điểm. Điều này được định nghĩa là sự thực thi
đồng thời trong lập trình kernel (concurrency in kernel programming).
Mặc dù kernel modules không thực thi tuần tự như application, các tác
vụ trong kernel đều được thực hiện dựa trên một process cụ thể. Lệnh kernel
có thể chỉ ra process đang thực thi bằng cách truy cập biến toàn cục
current, được định nghĩa trong thư viện <asm/current.h>.
5.2. Các Thành Phần Chính Của Một Module Chúng ta sẽ bắt đầu với ví dụ về chương trình “hello world” như là một
ví dụ điền hình và đơn giản để hiểu cấu trúc của một module.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 89
Hình 5.4. Module “hello world”
Module “hello world” không làm việc gì khác ngoài gọi lệnh prink
(tương đương lệnh printf trong user space, lệnh printk chạy trong
kernel space) để in các thông tin khi module được đặt vào trong kernel thông
qua lệnh insmod và khi gỡ bỏ khỏi kernel thông qua lệnh rmmod
Kết quả chạy module như sau:
Xem xét module này chúng ta thấy được một module căn bản cần
include 2 file <linux/init.h> và <linux/module.h> và thực hiện ít
nhất 2 hàm module_init và module_exit.
Hàm module_init: được gọi khi module được liên kết với kernel
Hàm module_exit: được gọi khi module được gỡ bỏ khỏi nhân.
Đây là các macros đặc biệt của kernel dùng để chỉ ra chức năng của các
hàm này.
Ngoài các macros trên, kernel còn cung cấp các macros khác cho
module. Sau đây là các macros thường gặp:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 90
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR(“author”);
MODULE_DESCRIPTION(“description”);
MODULE_VERSION(“version”);
Hình 5.5. Các macros thường gặp trong module
Các macros này dùng để định nghĩa các thông tin về module như: tác
giả, mô tả, version, license, …
Hàm printk được định nghĩa trong nhân Linux và được sử dụng cho
modules, nó có chức năng tương tự như hàm printf trong thư viện C chuẩn.
Kernel cần một hàm có chức năng hiển thị cho riêng nó bởi vì nó chạy bởi
chính nó, không có bất cứ sự giúp đỡ nào của thư viện C. Module có thể gọi
tới hàm printk của kernel vì sau lệnh insmod, module được liên kết tới
kernel và nhờ đó có thể truy cập các biểu tượng toàn cục của kernel (hàm,
biến).
Module còn có thể nhận biến được truyền từ lệnh insmod với macro
#include <linux/moduleparam.h>
module_param(variable_name, type, permission);
module_param_array(name,type,num,perm);
Hiện tại các kiểu được hỗ trợ bao gồm: bool, invbool, charp, int, long,
short, uint, ulong, ushort. Permission được định nghĩa trong file
<linux/stat.h>. Phiên bản khác của module_param là module_param_array
cho phép chúng ta truyền vào một mảng các biến thay vì một biến riêng lẻ.
5.3. Character Device Drivers Chúng ta sẽ tìm hiểu cách viết một character drivers trước hết vì nó
phù hợp cho hầu hết các thiết bị phần cứng đơn giản và cũng dễ hiểu đơn
giản hơn so với block driver và networlk drivers. Hai loại drivers còn lại có
thể tham khảo thêm từ sách Linux Device Driver 3rd
(mục tài liệu tham khảo)
5.3.1. Major & Minor Number
Các device được truy cập thông qua một file đặc biệt gọi là device
file. Để tạo ra một device file, chúng ta dùng lệnh mknod và cần quan tâm
tới 3 thông số sau:
Device loại gì
Major number
Minor number.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 91
* Major Number
Được dùng để xác định device file do driver nào quản lí. Chúng ta có
thể tra các major number đã cấp phát sẵn trong file
/linux/Document/devices.txt.
Khi viết một driver mới và nếu đăng ký thành công vào source tree
của kernel chúng ta sẽ được cấp 1 major number ứng với driver của mình.
Nếu chỉ cần viết driver cho thiết bị của mình mà không cần đăng ký vào
source tree thì cách thức đơn giản nhất là cấp phát major number động. File
/proc/device sẽ chứa thông tin về các character device và block device có
trong hệ thống cùng với major number tương ứng, chúng ta có thể dùng file
này để tra major number nếu cấp phát major number động và dùng kết quả
này để tạo device file phục vụ việc truy cập
* Minor Number
Được sử dụng bởi kernel để xác định chính xác thiết bị nào đang được
đề cập tới. Thông số này có ý nghĩa khác nhau đối với mỗi loại device
Ví dụ:
Đối với ổ đĩa, minor number sẽ tương ứng với các partition
Đối với serial port thì thông số này được sử dụng để chỉ thứ tự của port
vật lí.
Bên trong kernel, 2 thông số này được biểu diễn chung bởi một loại
giá trị là dev_t (được định nghĩa trong <linux/types.h>) Việc chuyển
đổi giữa dev_t và major, minor number và ngược lại được thực hiện bởi
các macro ( định nghĩa trong <linux/kdev_t.h>)
MAJOR(dev_t devno);
MINOR(dev_t devno);
MKDEV(int major, int minor);
Hình 5.6. Khai báo thông số major & minor number
Character Device Driver có thể được cấp phát dev_t theo 2 cách:
Cấp phát tĩnh
Cấp phát động
* Cấp Phát Tĩnh Major Number
Thực hiện bằng cách sử dụng hàm được định nghĩa trong <linux/fs.h>
int register_chrdev_region(dev_t first, unsigned int
count, char *name);
Hình 5.7. Các cấp phát tĩnh thông số Major Number
Trong đó:
first là chỉ số đầu tiên của dev_t ( tạo ra từ MKDEV với major
number định trước và minor number bằng 0).
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 92
count là tổng số lượng device mà driver yêu cầu.
name là tên được đăng ký cho driver này, tên này sẽ hiển thị trong
/proc/devices. Hàm này sẽ trả về 0 nếu đăng ký thành công.
Ví dụ:
int major = PREDEFINED_MAJOR;
dev_t devno = MKDEV( major, 0);
int result =register_chrdev_region(devno, 10,
“example”);
if (result) goto check_error;
Hình 5.8. Ví dụ về cách cấp phát tĩnh Major Number
* Cấp Phát Động Major Number
Điều này giúp cho driver có tính linh hoạt cao tránh trùng lặp với major
number của các driver có sẵn và tiện cho việc quản lý.
Chức năng này được thực hiện qua hàm
int alloc_chrdev_region(dev_t *devno, unsigned int
firstminor,unsigned int count, char *name);
Hình 5.9. Cách cấp phát động Major Number
Trong đó:
firstminor thường được gán bằng 0
count và name có ý nghĩa tương tự như hàm cấp phát tĩnh.
devno là một output nhận giá trị trả về từ hàm nếu thành công.
Hàm thành công sẽ trả về 0.
Ví dụ:
dev_t devno;
int result = alloc_chrdev_region(&devno, 0, 10,
“example”);
if(result) goto check_error;
Hình 5.10. Ví dụ về cách cấp phát động Major Number
Cả hai hàm này thường được gọi trong phần module_init của driver.
Khi driver không còn sử dụng nữa, cần phải trả lại major number cho hệ
thống thông qua hàm sau
void unregister_chrdev_region(dev_t first, unsigned int
count);
Hình 5.11. Trả Major Number cho hệ thống
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 93
5.3.2. Các Cấu Trúc Dữ Liệu Quan Trọng
Việc đăng kí device number chỉ là một trong những nhiệm vụ mà
driver code phải làm. Hầu hết các hoạt động cơ bản của một driver bao gồm
3 thành phần cấu trúc dữ liệu kernel sau: file_operations, file và inode.
* File Operation
Như trên chúng ta đã định nghĩa device number để sử dụng nhưng
hoàn toàn chưa liên kết bất kì tác vụ nào của driver tới các number này. Cấu
trúc File_operations là cách một char driver thiết lập liên kết này. Cấu trúc
này được định nghĩa trong <linux/fs.h> và là một tập hợp của các
pointer hàm.
Một chương trình chạy trên user space sẽ sử dụng các hàm thư viện (ví
dụ: fopen, fclose, fread, fwrite,...) và các hàm này bên trong sẽ gọi đến các
hàm system call tương ứng do hệ điều hành cung cấp (ví dụ: open, close,
read, write,...). Sau đó, các system call lại được ánh xạ vào hàm tương ứng do
driver thực hiện. Mỗi driver sẽ có một bảng ánh xạ hàm, thể hiện qua cấu trúc
struct file_operations.
Bảng liệt kê các ánh xạ hàm quan trọng của driver
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char __user *,
size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *,
size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, const struct iovec *,
unsigned long, loff_t);
ssize_t (*aio_write) (struct kiocb *,
const struct iovec *,
unsigned long, loff_t);
int (*readdir) (struct file *, void *, filldir_t); unsigned
int (*poll) (struct file *,
struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *,
unsigned int, unsigned long);
long (*unlocked_ioctl) (struct file *,
unsigned int, unsigned long);
long (*compat_ioctl) (struct file *,
unsigned int, unsigned long);
int (*mmap) (struct file *,
struct vm_area_struct *);
int (*open) (struct inode *, struct file *); int (*flush)
(struct file *, fl_owner_t id); int (*release) (struct inode
*, struct file *); int (*fsync) (struct file *, struct dentry
*,
int datasync);
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 94
int (*aio_fsync) (struct kiocb *, int datasync); int
(*fasync) (int, struct file *, int); int (*lock) (struct file
*, int, struct file_lock *); ssize_t (*sendpage) (struct file
*, struct page *,
int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *,
unsigned long, unsigned long,
unsigned long, unsigned long);
int (*check_flags)(int); int (*flock) (struct file *, int,
struct file_lock *); ssize_t (*splice_write)(struct
pipe_inode_info *,
struct file *, loff_t *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, loff_t *,
struct pipe_inode_info *, size_t, unsigned int); int
(*setlease)(struct file *, long, struct file_lock **);
};
Hình 5.12. Bảng liệt kê các tác vụ của driver định nghĩa thông qua struct
file_operations.
Ở đây, chúng ta chỉ giải thích một số tác vụ điển hình và hay dùng nhất 1. struct module *owner
Trường đầu tiên của cấu trúc struct file_operations không thực sự là một
tác vụ. Nó là một pointer trỏ tới module sở hữu cấu trúc này. Trường này
được định nghĩa để tránh trường hợp một module đã gỡ bỏ nhưng các tác vụ
của nó vẫn được sử dụng.
Thông số owner này thường được gán bởi macro THIS_MODULE.
2. int (*open) (struct inode*, struct file*);
Mặc dù đây là tác vụ đầu tiên trên device file nhưng các driver không
yêu cầu khai báo các phương thức tương ứng. Nếu điểm vào này là NULL,
các device vẫn được mở thành công tuy nhiên driver không biết.
3. int (*release) (struct inode *, struct file*);
Tác vụ này được gọi khi cấu trúc file được tự do. Giống như tác vụ
open, release có thể trả về kiểu NULL.
4. ssize_t(*read) (struct file*, char __user*,
size_t, loff_t*);
Tác vụ được sử dụng để nhận dữ liệu từ device.
Nếu vị trí là null pointer thì hàm hệ thống read sẽ trả về lỗi –EINVAL(
“Invalid Argument”).
Hàm trả về giá trị không âm chính là số bytes được nhận thành công từ
device.
5. ssize_t(*write) (struct file*, char __user*,
size_t, loff_t*);
Tác vụ này được dùng để gửi dữ liệu tới device.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 95
Nếu NULL, giá trị -EINVAL được trả về cho hàm đã gọi hàm hệ thống
write. Trong trường hợp khác, giá trị không âm trả về chính là số bytes thành
công đã ghi ra device.
6. int (*ioctl)(struct inode*,struct file*,usigned int, unsigened long);
Hàm hệ thống ioctl cung cấp một cách để truyền lệnh xuống thiết bị
(chẳng hạn như định dạng ổ đĩa). Nếu thiết bị không cung cấp ioctl, hàm gọi
hệ thống sẽ trả về lỗi cho bất cứ yêu cầu nào không được định nghĩa trước (-
ENOTTY, “ No such ioctl for device”)
vÍ Dụ:
File_operation của led_driver
struct file_operations mini2440_leds_fops = {
.owner = THIS_MODULE,
.read = mini2440_leds_read,
.write = mini2440_leds_write,
.ioctl = mini2440_leds_ioctl,
.open = mini2440_leds_open,
.release= mini2440_leds_release,
};
Hình 5.13. Ví dụ file_operation của Led_driver
* File Structure
Struct file được định nghĩa trong <linux/fs.h> là cấu trúc dữ liệu
quan trọng thứ 2 được sử dụng cho device drivers. Nó là một cấu trúc kernel
chỉ xuất hiện trong kernel code khác so với một file được định nghĩa trong
thư viện C chỉ xuất hiện trong chương trình user space.
* Inode Structure
5.3.3. Đăng kí Char Device
Việc tiếp theo là cần kết nối struct file_operations với character
device. Kernel hỗ trợ việc này thông qua hai cách sau
Cách 1: tạo character device và gắn kết với file_operations bằng phương
pháp thủ công
struct cdev * leds_cdev = cdev_alloc( );
leds_cdev->ops = &mini2440_leds_fops;
Hình 5.14. Đăng kí Char Device bằng thủ công
Cách 2: Sử dụng hàm khởi tạo
void cdev_init(struct cdev *cdev, struct file_operations
*fops);
struct cdev leds_cdev;
cdev_init( &leds_cdev, &mini2440_leds_fops);
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 96
Hình 5.15. Đăng kí Char Device bằng hàm khởi tạo
Cũng giống như struct file_operations, character device chứa một
trường owner và chúng ta phải gán trường này với macro THIS_MODULE,
bất chấp bước phía trước dùng phương pháp nào để tạo và liên kết character
device với struct file_operations.
leds_cdev->owner = THIS_MODULE;
Việc cuối cùng cần làm để đăng ký character device với hệ thống là
liên kết dev_t number với character device cdev. Điều này chỉ được thực hiện
khi chúng ta đã đảm bảo mọi khởi tạo trong driver đã hoàn tất thành công, vì
ngay khi đăng ký với hệ thống, driver có thể được các ứng dụng bên ngoài sử
dụng ngay lập tức và việc khởi tạo chưa hoàn chỉnh có thể làm hệ thống hư
hỏng. Prototype của hàm như sau:
int cdev_add(struct cdev *dev, dev_t num, unsigned int
count);
Hình 5.16. Liên kết dev_t number với char device
Trong đó: dev là cdev structure đã được tạo và khởi tạo ở trên.
num là giá trị đầu tiên của device number.
count là số lượng device number được liên kết với thiết bị.
Ví dụ:
int result = cdev_add( &led_cdev, devno, 10);
if (result <0) goto add_cdev_error;
Hình 5.17. Ví dụ về liên kết dev_t number với char device
Cuối cùng, khi driver được unload, ta phải gỡ character device ra khỏi
hệ thống với hàm:
void cdev_del(struct cdev *dev);
Hình 5.17. Gỡ bỏ char device khỏi hệ thống
Điểm khác biệt rất lớn giữa device driver và các program thông
thường là device driver code phải luôn quan tâm đến vấn đề code bị gọi song
song. Code của device driver có thể phục vụ nhiều user space program cùng
một lúc và driver còn có thể bị interrupt handler gọi trong khi nó đang thực
thi một việc khác. Do đó khi viết một driver người viết luôn cần lưu ý đến
tính năng truy cập song song này và bảo vệ các phần code có thể gây ra chạy
đua.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 97
Khi viết một driver mới thuộc loại character device chúng ta không sử
dụng riêng struct cdev mà nhúng nó vào một struct lớn hơn, trong struct lớn
này sẽ bao gồm thêm các thành phần cần thiết khác (ví dụ như một
semaphore để đồng bộ việc truy cập).
Ví dụ:
struct leds_dev { dev_t devno;
struct semaphore sem; /* mutual exclusion semaphore */
struct cdev cdev; /* Char device structure*/
};
Hình 5.18. Nhúng struct cdev vào struct semaphore
Ngoài hai cách đã đề cập ở trên, chúng ta cũng có thể gặp một cách cổ
điển khác dùng để đăng kí character device như sau
int register_chrdev (unsigned int major, const char
*name, struct file_operations *fops);
Hình 5.19. Cách cổ điển đăng kí char device
Trong đó: major là major number
name: tên của driver ( trong /proc/devices)
fops: cấu trúc mặc định của file_operations
Drivers sử dụng cách đăng kí này phải xử lí hàm open cho tất cả 256
minor numbers và chúng không thể sử dụng các giá trị major hoặc minor
number lớn hơn 255.
Khi sử dụng register_chrdev để đăng kí, chúng ta có thể sử dụng hàm
sau để remove device khỏi hệ thống
int unregister_chrdev (unsigned int major, const char
*name);
Hình 5.20. Cách gỡ bỏ char device theo cách cổ điển
Trong đó thông số major và name tương tự như hàm đăng kí ở trên.
5.3.4. Truy Cập Dữ Liệu User Space Và Hardware
Device driver nằm giữa user space program và hardware do đó nó cần
truy cập dữ liệu cả hai khu vực này.
* Trao Đổi Dữ Liệu Với User Space
Như đã nói ở trên, tác vụ read được sử dụng để copy dữ liệu tới
application trên user space trong khi đó write được sử dụng để ghi dữ liệu từ
application program. Do đó protype của 2 tác vụ này cơ bản giống nhau.
ssize_t read (struct file*flip, char __user *buff,
size_t count, loff_t*offp);
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 98
ssize_write(struct file*flip, const char __user *buff,
size_t count, loff_t*offp);
Hình 5.21. Các tác vụ để trao đổi dữ liệu
Trong đó: flip là file pointer
Count: là kích cỡ của dữ liệu cần chuyển.
Buff: chỉ tới vùng user buffer, được sử dụng để chứa dữ liệu để ghi hoặc
vùng buffer trống để chứa dữ liệu được đọc về.
Dĩ nhiên, việc trao đổi dữ liệu giữa driver và user space program
không thực hiện trực tiếp mà phải thông qua các hàm dịch vụ do kernel cung
cấp. Các hàm này được định nghĩa trong <linux/access.h>. Các hàm này
có chức năng tương tự như hàm memcpy.
unsigned long copy_to_user(void __user *to, const void
*from, unsigned long count);
unsigned long copy_from_user(void *to, const void
__user *from, unsigned long count);
Hình 5.22. Các hàm dịch vụ để trao đổi dữ liệu
Trong đó: các thuộc tính __user là buffer thuộc về user space và thành phần
buffer còn lại thuộc về kernel space.
count là số phần tử của buffer
Hàm trả về giá trị 0 khi thành công.
Hình 5.23. Mô tả tác vụ đọc dữ liệu
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 99
Ví dụ 1: Trả về một biến int cho user space
static ssize_t mini2440_leds_read (struct file *file,
char *buf, size_t count, loff_t *ppos)
{
int result;
...
err = copy_to_user (buf, &result, sizeof(int));
if(err) return -EFAULT;
...
}
Hình 5.24. Ví dụ trả biến về user space
Ví dụ 2: Đọc một biến int từ user space
static ssize_t mini2440_leds_write (struct file *file,
const char *buf, size_t count, loff_t *ppos)
{
int wri;
...
err = copy_from_user (&wri, buf, sizeof(int));
if ( err != 0 ) return -EFAULT;
...
}
Hình 5.25. Ví dụ nhận biến từ user space
* Trao Đổi Dữ Liệu Với Hardware
Trong các hệ thống SoC, việc truy cập phần cứng chủ yếu thực hiện
qua các thanh ghi cấu hình (configuration registers), thanh ghi dữ liệu (data
registers) và các thanh ghi trạng thái (status registers).
Linux kernel sử dụng bộ nhớ ảo nên chúng ta không thể đơn giản chỉ dùng
con trỏ chỉ vào địa chỉ vùng nhớ vật lý và dùng con trỏ này để gán giá trị cho
vùng nhớ. Linux kernel đòi hỏi các địa chỉ thanh ghi này phải được ánh xạ
vào địa chỉ ảo thuộc kernel space và việc đọc gán giá trị cho các thanh ghi
cũng sử dụng các hàm dịch vụ thay vì gán trực tiếp.
Các hàm liên quan đến việc ánh xạ địa chỉ vật lý của thanh ghi vào địa
chỉ kernel gồm
#include <linux/ioport.h>
struct resource *request_mem_region(unsigned long start,
unsigned long len, char *name);
Hình 5.26. Ánh xạ thanh ghi vào địa chỉ kernel
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 100
Hàm này xin cấp phát tài nguyên có địa chỉ vật lý từ start, và có độ dài len,
name là tên đăng ký để chúng ta có thể kiểm tra trong /proc/iomem xem
driver nào đang chiếm tài nguyên. Hàm trả về giá trị non-NULL nếu thành
công.
void release_mem_region(unsigned long start,
unsigned long len);
Hình 5.27. Hàm trả tài nguyên
Hàm này trả lại tài nguyên được cấp phát bởi request_mem_region. Chúng ta
cần gọi hàm này khi không dùng đến tài nguyên nguyên nữa.
#include <asm/io.h>
void *ioremap_nocache(unsigned long phys_addr,unsigned
long size);
void iounmap(void * addr);
Hình 5.28. Hàm ánh xạ địa chỉ vật lí
Hàm ioremap_nocache ánh xạ địa chỉ vật lý chỉ định bởi phys_addr, có độ
dài size vào kernel address space, con trỏ void trả về chính là địa chỉ trong
kernel space. Chúng ta sẽ sử dụng con trỏ void này để truy cập vào các thanh
ghi bằng cách dùng con trỏ void này làm thông số đầu vào cho các hàm read,
write do kernel cung cấp. Hàm iounmap nhận con trỏ void sinh ra bởi hàm
ioremap_nocache và bỏ ánh xạ này ra khỏi hệ thống.
Các hàm read, write do kernel cung cấp được định nghĩa trong <asm/io.h>
unsigned int ioread8(void *addr);
unsigned int ioread16(void *addr);
unsigned int ioread32(void *addr);
void iowrite8(u8 value, void *addr);
void iowrite16(u16 value, void *addr);
void iowrite32(u32 value, void *addr);
void ioread8_rep(void *addr, void *buf,unsigned long count);
void ioread16_rep(void *addr, void *buf,unsigned long count);
void ioread32_rep(void *addr, void *buf,unsigned long count);
void iowrite8_rep(void *addr, const void *buf,unsigned long
count);
void iowrite16_rep(void *addr, const void *buf,unsigned long
count);
void iowrite32_rep(void *addr, const void *buf,unsigned long
count);
void memset_io(void *addr, u8 value, unsigned int count);
void memcpy_fromio(void *dest, void *source,unsigned int
count);
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 101
void memcpy_toio(void *dest, void *source,unsigned int
count);
Hình 5.29. Bảng các hàm trao đổi dữ liệu với hardware
Con trỏ void* addr đầu vào của các hàm là giá trị trả về của hảm
ioremap_nocache. Hàm io[read|write][8|16|32] cho phép đọc ghi trên các giá
trị [8|16|32] bits. Hàm io[read|write][8|16|32]_rep thực hiện lặp lại
io[read|write][8|16|32] count lần (count không phải là số byte đọc/ghi mà là
số lần lặp lại hàm). Ba hàm cuối cùng sử dụng cho một memory block.
Tóm lại, việc truy cập 1 thanh ghi gồm các bước sau:
Xin cấp phát vùng nhớ với request_mem_region().
Ánh xạ địa chỉ vật lý vừa xin với ioremap_nocache().
Truy cập thanh ghi từ con trỏ trả về từ ioremap_nocache() với
các hàm dịch vụ do kernel cung cấp.
Ví dụ:
Một đoạn code config thanh ghi của PORTB trên processor S3C2440,
MINI2440_GPBCON_PA là địa chỉ vật lý của bộ thanh ghi cấu hình cho
PORTB (0x56000010). PORTB có 3 thanh ghi 32 bit: thanh ghi cấu hình
(0x56000010), thanh ghi dữ liệu (0x56000014) và thanh ghi pullup register
(0x56000018).
if (! request_mem_region(MINI2440_GPBCON_PA ,4*3, "mini2440_leds"))
{
printk( KERN_ERR "mini2440-leds: can't get I/O mem address
0x%x\n",MINI2440_GPBCON_PA );
return -ENODEV;
}
unsigned long *leds_base_addr = (unsigned
long*)ioremap_nocache((unsigned long)MINI2440_GPBCON_PA, 4*3);
if( leds_base_addr == NULL){
printk( KERN_ERR"cannot map portB to kernel space\n");
release_mem_region((unsigned long)MINI2440_GPBCON_PA, 4*3);
return -ENODEV;
}
// config pull-up registers
temp = ioread32(leds_base_addr+2);
temp &= ~(0x0f<<5); // enable pull up resistors for 4 pins 5 6 7 8
iowrite32(temp, leds_base_addr+2);
Hình 5.30. Ví dụ về trao đổi dữ liệu với hardware
5.3.5. Các Tác Vụ Nâng Cao Của Char Driver
Như các phần trên đã xây dựng, chúng ta đã xây dụng một device driver
hoàn tất cho phép người dùng có thể đọc hoặc ghi dữ liệu từ device. Ngoài ra,
các thiết bị thực còn cung cấp thêm các chức năng khác. Trong mục này sẽ
giới thiệu về hàm hệ thống ioctl được xem là giao tiếp điển hình để điều
khiển thiết bị.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 102
Ngoài ra còn các tính năng nâng cao khác như: đặt process vào chế độ
ngủ (sleep mode), cách đánh thức (wake up process), thông báo cho user
space biết khi nào thiết bị sẵn sàng cho việc đọc và ghi,… ( các tính năng này
tham khảo tài liệu).
Ioctl
Device drivers có thể điều khiển các device thông qua phương thức
ioctl, được thực hiện qua hàm hệ thống system call cùng tên.
Trong user space, protype của ioctl như sau
int (*ioctl)(struct inode *inode, struct file *flip, unsigned
int cmd, unsigned long arg);
Hình 5.31. Protype ioctl
Trong đó:
Pointer inode và flip là các giá trị tương ứng với file descriptor fd, giống như
tham số truyền trong tác vụ open.
Các thông số cmd, arg được truyền từ user.
Thông thường, giá trị cmd được sử dụng để xây dựng cấu trúc switch –
case trong tác vụ ioctl cho phép định nghĩa các hành vi khác nhau tùy theo
giá trị của thông số cmd.
Ví dụ:
User program calling ioctl
#define CDROMEJECT 1
int main (int argc, char* argv[])
{
/* Open a file descriptor to the device specified on the
command line. */
int fd = open (argv[1], O_RDONLY); //argv[1] is /dev/cdrom
/* Eject the CD-ROM. */
ioctl (fd, CDROMEJECT); /*CDROMEJECT become device_ioctl..
int cmd parameter */
/* Close the file descriptor. */
close (fd);
return 0;
}
Device driver ioctl
static int device_ioctl(struct inode *inode, struct file
*filp, unsigned int cmd, unsigned long arg)
{
switch(cmd)
{
case CDROMEJECT:
printk("CD-ROM EJECTED\n");
break;
default:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 103
printk("IOCTL DEFAULT COMMAND EXECUTED\n");
}
return 0;
}
Hình 5.32. Ví dụ về sử dụng ioctl
5.4. Interrupt Handling Như đã biết, ngắt là một tín hiệu bất đồng bộ được hardware gửi tới khi
nó muốn vi điều khiển chú ý tới. Khi đó, CPU sẽ lưu trạng thái thực thi hiện
tại và nhảy tới chương trình phục vụ ngắt. Trong linux, driver có nhiệm vụ
cài đặt ngắt và quản lí chúng khi ngắt xảy ra.
5.4.1.Thiết Lập Ngắt
Để thiết lập ngắt ta sử dụng hàm được khai báo trong
<linux/interrupt.h>
int request_irq(unsigned int irq,
irqreturn_t(*handler)(int,void*, struct pt_regs*),
unsigned long flags, const char *dev_name, void
*dev_id);
Hình 5.33. Các hàm thiết lập ngắt
Trong đó:
unsigned int irq: thứ tự ngắt được yêu cầu.
irqreturn_t (*handler)(int, void*, struct pt_regs): pointer chỉ tới chương trình
phục vụ ngắt
unsigned long flags: bit liên quan tới quản lí ngắt
const char*dev_name: một chuỗi được gửi tới hàm request_irq và sử dụng
trong /proc/interrupts để chỉ ra chủ sở hữu của ngắt này.
void *dev_id: Pointer sử dụng cho chia sẻ đường ngắt.
Hàm trả về giá trị 0 nếu thành công, giá trị âm nếu có lỗi xảy ra.
Việc cài đặt ngắt cót thể thực hiện khi init một driver hoặc chỉ khi mở
thiết bị. Nếu một module yêu cầu ngắt ngay tại init ban đầu, nó sẽ không cho
phép các driver khác sử dụng ngắt này. Vì số lượng đường ngắt rất hạn chế
do đó nên cài đặt ngắt khi thiết bị được mở lần đầu vì cho phép chia sẻ tài
nguyên.
Khi thiết bị được đóng và phần cứng không sinh bất cứ ngắt nào nữa thì
cần giải phóng ngắt bằng hàm sau:
void free_irq (unsigned int irq, void *dev_id);
Hình 5.34. Hàm giải phóng ngắt
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 104
5.4.2. Giá Trị Trả Về (return value)
Chương trình phục vụ ngắt cần trả về giá trị để chỉ ra rằng có ngắt xảy
ra thực sự hay không.Trong trường hợp có ngắt nên trả về giá trị
IRQ_HANDLED, trong trường hợp khác giá trị trả về là IRQ_NONE. Chúng
ta có thể trả giá trị về thông qua macro sau:
IRQ_RETVAL(handled);
Hình 5.35. Trở về từ ngắt
Ví dụ:
Hình 5.36. Ví dụ về khai báo ngắt
Ngoài ra, trong một số trường hợp driver cần cấm ngắt hoặc cho phép
ngắt với một số ngắt cụ thể. Kernel cung cấp 3 hàm để thực hiện việc này và
chúng được khai báo trong <asm/irq.h>
void disable_irq(int irq);
void disable_irq_nosync(int irq);
void enable_irq(int irq);
Hình 5.37. Các hàm cho phép và cấm ngắt
5.5. Cách Build Một Driver Module 5.5.1. Build Môi Trường Để Biên Dịch Cho Driver Or Modules:
- Download kernel from www.friendlyarm.net : kernel 2.6.32
http://www.friendlyarm.net/dl.php?file=kernel 2.6.32.tgz
- Giải nén tại một thư mục nào đó trên ubuntu
Code:
#sudo tar xfvz kernel 2.6.32.tgz –C/
struct button_irq_desc {
int irq;
int pin;
int pin_setting;
int number;
char *name;
};
static struct button_irq_desc button_irqs [] = {
{IRQ_EINT8,S3C2410_GPG(0),S3C2410_GPG0_EINT8,0,
"KEY0"},
{IRQ_EINT9,S3C2410_GPG(1),S3C2410_GPG1_EINT9,1,
"KEY1"},
};
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 105
- Tiến hành cài đặt công cụ cần thiết để hỗ trợ build kernel
Code:
#sudo apt-get install ncurses-dev (config by
munuconfig)
Hoặc dùng lệnh #sudo apt-get install qt3-dev-tools
-Vào làm việc trong thư mục đã giải nén kernel 2.6.32
Code:
#cd */kernel 2.6.32
- Copy file cấu hình minh244o cho loại màn hình 3.5inch vào file
/.config
Code:
#cp config_mini2440_n35 ./.config
-Tiếp hành mở menuconfig
Code:
#ARCH = arm make oldconfig
#ARCH = arm make menuconfig
Thay đổi cấu hình của kernel theo các setting dưới đây:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 106
-Cài đặt kernel
Code:
# make
#ARCH =arm make modules_install
Có thể tham khảo thêm tại địa chỉ : Reference document: http://cchia-
cwp.blogspot.com/2010/03/mini2440-friendlyarm-for-embedded.html
5.5.2. Cách Load Và Unload Một Driver
Như đã nói ở phần 5.1,ngoại trừ network device, các device khác
được truy cập thông qua một loại file đặc biệt gọi là device file.
Nhằm mục đích tiện lợi chúng ta có thể viết một script đơn giản để
load và unload các module
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 5: DEVICE DRIVERS GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 107
Code:
#!/bin/sh
# load module script
module="my_driver"
device="my_device"
mode="664"
if grep -q '^staff:' /etc/group; then
group="staff"
else
group="wheel"
fi
# insmode or exit on error
/sbin/insmod ./$module.ko $* || exit 1
# find driver major number
major=$(awk "\$2==\"$module\" {print \$1}" /proc/devices)
minor=0
# create device file
rm -f /dev/${device}0
mknod /dev/${device}0 c $major $minor
chgrp $group /dev/${device}0
chmod $mode /dev/${device}0
#!/bin/sh
# unload module script
module="my_driver"
device="my_device"
# invoke rmmod with all arguments we got
/sbin/rmmod $module $* || exit 1
# delete device file
rm -f /dev/${device}0
Hình 5.38. Script để load và unload driver
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 108
CHƢƠNG 6
THIẾT KẾ VÀ THI CÔNG PHẦN CỨNG
6.1. Giới Thiệu Mô Hình Quản Lí Bãi Giữ Xe Hiện Nay Hiện nay, các bãi giữ xe tại thành phố HCM nói riêng và Việt Nam nói
chung đa phần đều áp dụng biện pháp thủ công (dùng vé xe ghi tay). Điều đó có
nghĩa khi xe đi vào bãi, người coi bãi có nhiệm vụ ghi vé và giao cho khách. Khi xe
khỏi bãi, khách giao ngược lại vé xe để người quản lí kiểm tra vé.
Cách thức quản lí này có rất nhiều nhược điểm:
Cần lượng nhân công lớn để ghi và soát vé
Trường hợp số lượng khách đông thì dễ gây ùn tắc, mất thời gian và
áp lực cho cả người quản lí và khách gửi.
Độ an toàn kém: nhân viên phải quan sát biển số xe vào/ra bằng mắt.
Hơn nữa, vé rất dễ bị làm giả, nhàu nát và thất lạc. Khi bị mất vé, các đối tượng
xấu nhặt được dễ dàng lấy được xe ra ngoài.
Về mặt quản lí: gây khó khăn cho việc quản lí chính xác lượng xe
hiện tại trong bãi, số xe gửi trong ngày, doanh thu thực tế,…
Hình 6.1. Quản lí bãi giữ xe bằng việc ghi vé tay
Bên cạnh đó, một số nơi cũng đang xuất hiện nhiều các hệ thống bãi giữ xe
thông minh (S- parking) và xu hướng thay thế dần cho các hệ thống bãi giữ xe cũ.
Hệ thống mới sử dụng camera, ứng dụng công nghệ nhận dạng ảnh và biển số tự
động lưu trữ dữ liệu qua thẻ chip.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 109
Mô hình hệ thống tại cửa vào
Hình 6.2. Mô hình cửa vào của bãi giữ xe thông minh S-parking
Hệ thống bao gồm :
2 camera: 1 camera để hiển thị nhận dạng chủ xe và 1 camera để
thu nhận biển số xe vào.
1 máy tính để xử lí công việc: chụp biển số xe vào tự động, tự
động nhận dạng biển số xe vào, quét thẻ chíp, lưu hình ảnh camera để đổi
chiếu cửa xe ra.
01 đầu ghi đọc thẻ chíp: cho phép ghi dữ liệu biển số, hình ảnh
xe và chủ xe vào thẻ chip.
Mô hình hệ thống tại cửa ra hoàn toàn tương tự như cửa vào.
*Nguyên Lí Hoạt Động:
Khi xe khách vào , nhân viên bảo vệ lấy 01 thẻ chip quẹt vào đầu đọc thẻ rồi
giao cho khách. Khi đó, hình ảnh biển số xe và hình ảnh mặt chủ xe được 02 camera
ghi lại và lưu trữ trong máy tính. Sau đó máy tính tiến hành nhận dạng biển số xe ra
dữ liệu text, cùng với thông tin số thẻ nhận về để thiết lập 01 bản ghi cơ sở dữ liệu
xe gửi gồm đầy đủ các thông tin: mã số thẻ, biển số xe (dạng text), hình ảnh biển số
xe, hình ảnh mặt chủ xe, ngày giờ xe vào…
Đối với xe nhân viên vào gửi, quá trình lặp lại tương tự trên chỉ khác là nhân
viên tự quẹt thẻ đã được cấp phát và thông tin nhân viên sẽ được hiển thị. Kết nối tự
động mở barie (nếu hệ thống có sử dụng barie)
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 110
Hình 6.3. Hình ảnh bãi giữ xe thông minh S- parking
Những ưu điểm chính:
Tốc độ tiếp nhận và giải phóng xe nhanh hơn nhờ đó tiết kiệm
thời gian cho cả khách hàng và người quản lí bãi.
Giảm sức lao động cũng như số lượng nhân công ít hơn.
Độ an toàn cao hơn: hệ thống tự kiểm tra 2 biển số trùng nhau,
tránh trường hợp làm giả thẻ xe cũng như nhặt được thẻ cũng không thể tìm
thấy xe.
Tuy nhiên, một số hạn chế nhất định:
Giá thành cao
Hệ thống tương đối cồng kềnh, phức tạp do phần xử lí nằm trên
máy tính, còn mạch điều khiển barrie riêng rẽ.
6.2. Giới Thiệu Mô Hình Quản Lí Bãi Giữ Xe Luận Văn Như đã nói trong phần 1.1, với xu hướng phát triển của hệ thống nhúng hiện
nay, vai trò của PC trong các hệ thống đang dần được thay thế thiết bị nhúng. Đó là
nhờ vào khả năng tích hợp nhỏ gọn, thuận tiện và giá thành ngày càng giảm.
Do đó, việc sử dụng board mini2440 làm thiết bị xử lí và điều khiển trung
tâm cho bãi giữ xe như là bước đầu trong việc phát triển các hệ thống trong đó vai
trò các thiết bị nhúng đã thay thế cho PC.
6.2.1. Tổng Quan Về Phần Cứng
- Sơ đồ tổng quát hoạt động của hệ thống
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 111
Board Mini2440 H Bridge (LMD18200 Module)
Webcam Barie (DC Motor)
Hình 6.4. Sơ đồ tổng quát của hệ thống
- Các thành phần phần cứng trong luận văn:
Webcam rời sử dụng để thu nhận hình ảnh xe vào bãi.
Board Mini2440 làm giao diện điều khiển người dùng đồng thời cũng
là mạch điều khiển động cơ DC mở cổng chắn.
Mạch cầu H ( H Bridge) sử dụng làm mạch động lực điều khiển động
cơ DC
DC Motor điều khiển barie chắn cổng, cho phép xe vào ra khỏi bãi.
6.2.2. Mô Tả Chi Tiết Phần Cứng
1. Board Mini2440
Mô tả board Mini2440 được trình bày trong chương 2
2. Mạch Điều Khiển Động Cơ
-Sơ đồ nguyên lí:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 112
Hình 6.5. Sơ đồ nguyên lí mạch cầu H
- Mạch động lực điều khiển động cơ dùng IC cầu H LMD18200 với các
đặc tính như sau:
Điện áp cung cấp 12V-55V. Dòng liên tục 3A và dòng đỉnh 6A
Ngõ vào tương thích TTL / CMOS
Bảo vệ ngắn mạch
Chân cảnh báo quá nhiệt (Thermal Flag Output)
Thường được ứng dụng trong:
Điều khiển động cơ DC và động cơ bước
Dùng trong robot
Trong các máy điều khiển chương trình số
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 113
Sơ đồ khối IC cầu H LMD18200
Hình 6.6. Sơ đồ khối LMD 18200
- Các pin 6 và 7 lần lượt là các chân cấp nguồn và GND.
- Pin 2 là Output 1 (OUT1) và Pin 10 là Output 2 (OUT2).
- Pin 3 (Direction Input): chân ngõ vào hướng điều khiển dòng giữa
OUT1 và OUT2 do đó điều khiển hướng quay của tải motor.
- Pin 4 (Brake Input): chân ngõ vào thắng, sử dụng để dừng motor.
- Pin 5 (PWM Input): chân ngõ vào xung PWM.
Bảng sự thật các trạng thái của LMD 18200
Hình 6.7. Bảng sự thật các trạng thái của LMD 18200
Để đơn giản cho việc điều khiển LMD18200, ta xuất tín hiệu PWM của vi
điều khiển tới chân 5 (PWM Input) và cấp các mức logic High hoặc Low cho chân
3 (Direction), 4 (Brake).
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 114
Khi đó động cơ DC được quay theo 1 chiều định trước và tốc độ được xác
định thông qua thời gian mức cao trong độ rộng xung PWM.
IC cầu H sử dụng trong luận văn là loại LMD18200T. Ưu điểm lớn nhất của việc sử
dụng IC cầu H này làm cho mạch thiết kế trở nên đơn giản và gọn gàng trong khi
vẫn đáp ứng đầy đủ những yêu cầu cần thiết trong ứng dụng điều khiển động cơ
như: tần số điều rộng xung lớn, dòng tải đỉnh lên tới 6A, có thể phát hiện quá nhiệt,
tương thích TTL và CMOS.
Hình 6.8. Hình dạng thực tế của IC Cầu H LMD18200
3. Động Cơ DC
Trong công nghiệp, động cơ điện một chiều được sử dụng ở những nơi
cần moment mở máy lớn hoặc trong yêu cầu điều chỉnh tốc độ và phạm vi rộng.
Nhược điểm chủ yếu của máy điện một chiều là có cổ góp làm cho cấu tạo phức tạp,
đắt tiền, kém tin cậy và nguy hiểm trong môi trường dễ cháy nổ. Khi sử dụng động
cơ điện một chiều cần có nguồn một chiều kèm theo.
Nguyên tắc hoạt động: Khi cho điện áp một chiều U vào 2 chổi điện,
trong dây quấn phần ứng có dòng điện I ư. Các thanh dẫn có dòng điện trong từ
trường sẽ chịu tác động lực Fdt tác động làm cho rotor quay.
Phương trình điện áp:
Trong đó: Eư: sức phản điện,
Iư: dòng điện trong dây quấn phần ứng
Rư: điện trở dây quấn phần ứng
U: điện áp đặt vào
Do đó để điều chỉnh tốc độ động cơ DC, ta có các phương pháp:
Điều chỉnh thông số mạch của máy điện
Thay đổi điện áp nguồn cung cấp cho phần ứng động cơ
Phương pháp điều rộng xung
Trong phương pháp điều rộng xung: là phương pháp điều chỉnh điện áp ra tải
hay nói cách khác phương pháp điều chế dựa trên sự thay đổi độ rộng của chuỗi
xung vuông dẫn đến thay đổi điện áp ra.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 115
Hình 6.9. Giản đồ xung điều khiển tốc độ động cơ DC
Tóm lại, tốc độ động cơ tỉ lệ với thời gian Ton trong 1 chu kì xung.
Hình 6.10. Hình ảnh thực tế động cơ DC
6.2.3. Nguyên Lí Hoạt Động Khi xe khách vào, camera sẽ thu nhận hình ảnh và hiển thị trên màn hình
điều khiển của nhân viên quản lí. Tiếp đó, người quản lí nhập vào thông tin khách
hàng (thường là biển số xe) trực tiếp trên giao diện điều khiển. Quá trình nhập kết
thúc bằng phím “Enter” xác nhận thông tin đã nhập là chính xác. Cuối cùng, bằng
một click “Start” thông tin khách hàng và hình ảnh thu nhận sẽ được lưu lại trong
bộ nhớ và hệ thống tự động cho phép mở barie bằng cách quay động cơ với tốc độ
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 6: THIẾT KẾ & THI CÔNG GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 116
mặc định trước. Khi đã mở barie ở độ cao để xe có thể vào, nhân viên nhấn “Stop”
để dừng động cơ.
Khi xe đi ra khỏi bãi và dừng lại, người quản lí nhập lại thông tin khách
hàng. Khi đó, hình ảnh xe ban đầu sẽ hiện ra cho phép xác định đúng xe, đúng
người sở hữu. Nếu thông tin hợp lệ, hệ thống tự động mở barie cho phép xe ra.
Tốc độ mở barie có thể thay đổi bởi người quản lí thông qua nút “Set
Speed” trên giao diện điều khiển.
Hệ thống cũng đưa ra một số cảnh báo khi người quản lí thao tác không
đúng bao gồm:
Nhập quá tốc độ cho phép của động cơ (3000 v/ph)
Chưa nhập mã thông tin khách hàng
Chưa nhấn “Enter” để xác nhận thông tin đã nhập
Màn hình giao diện điều khiển
Hình 6.11. Màn hình giao diện điều khiển
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 117
CHƢƠNG 7
CẤU TRÚC CHƢƠNG TRÌNH QUẢN LÍ BÃI GIỮ XE
7.1. Giới Thiệu Tổng Quát Như đã đề cập trong phần 5.1.5, hệ thống trong Linux được chia làm 2 vùng
riêng biệt: Kernel Space và User Space. Các modules chạy trong kernel space trong
khi các ứng dụng (user application) chạy trong user space.
Do đó, chương trình quản lí bãi giữ xe cũng được chia thành 2 phần riêng biệt:
Driver Module: camera, motor
Giao diện điều khiển người dùng GUI
Kernel Space User Space
Driver camera GUI Program
Driver motor
Hình 7.1. Cấu trúc chương trình
7.2. Driver Modules 7.2.1. Motor Driver
Như đã đề cập trong phần 5.2 và 5.3 (chương 5_ Device Drivers), chúng ta
đã biết cấu trúc của một module, cách viết một character device driver và cách định
nghĩa các tác vụ của chúng.
Do đó, trong mục này chúng ta sẽ trình bày cấu trúc của driver dưới dạng sơ
đồ nhiều hơn việc đi vào chi tiết.
GUI PROGRAM
KERNEL
DRIVERS
HARDWARE
Camera Motor
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 118
Hình 7.2. Cấu trúc tổng quát Motor Driver
Motor Driver thuộc loại character device driver và bao gồm các hàm, tác vụ sau:
Hàm module_init: được gọi khi module liên kết với kernel.
Hàm module_exit: được gọi khi module được gỡ bỏ khỏi nhân.
Các tác vụ cơ bản: open, close, read, ioctl điều khiển việc
truyền và nhận dữ liệu giữa user space và kernel space.
Chức năng chi tiết của từng hàm và các tác vụ tương ứng
1. Hàm module_init:
Được gọi khi module liên kết với kernel thông qua lệnh insmod.
Thực hiện việc đăng kí device number(major& minor) và liên kết các tác vụ
file_operations với character device.
2. Hàm module_exit:
Được gọi khi module bị gỡ bỏ khỏi nhân.
Thực hiện việc gỡ bỏ device khỏi hệ thống.
3. Tác vụ open:
Được định nghĩa bằng hàm s3c24xx_pwm_open(). Hàm thực hiện
mở device, cấp xung clock cho hệ thống.
4. Tác vụ release:
Được định nghĩa bằng hàm s3c24xx_pwm_close().
module_init
module_exit
File_Operations
s3c24xx_pwm_open()
s3c24xx_pwm_close()
s3c24xx_pwm_read()
s3c24xx_pwm_ioctl()
Functions
PWM_Stop()
PWM_Set_Speed() Switch
Case
button_interrupt()
timer_interrupt()
PID_controller()
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 119
Hàm này thực hiện gọi tới hàm con PWM_Stop()
5. Tác vụ read
Sử dụng truyền giá trị tốc độ thực động cơ về user space thông qua hàm
dịch vụ: copy_to_user(). (tham khảo 5.3.4)
6. Tác vụ ioctl
Sử dụng điều khiển các hành vi khác nhau của device bằng cấu trúc
switch_case.
Tùy theo giá trị của thông số cmd truyền từ user, các hàm tương ứng được gọi:
cmd = PWM_IOCTL_SET_SPEED:
Gọi hàm PWM_Set_Speed(arg) với đối số truyền vào là thông số
thứ 4 của cấu trúc ioctl. Chúng ta sử dụng thông số arg để truyền vào tốc độ đặt
ban đầu của động cơ. arg = tốc độ đặt ban đầu
cmd = PWM_IOCTL_STOP:
Gọi hàm PWM_Stop() để dừng motor.
7. Hàm PWM_Set_Speed(unsigned long)
Thực hiện cài đặt ban đầu cho phần cứng: ( tham khảo phần 5.4.1)
Chọn chân ngõ ra pwm, timer nội.
Chọn tỉ lệ chia mux, prescaler và cho phép chạy timer.
Cài đặt timer ở chế độ ngắt.
Cài đặt chân ngắt ngoài và cho phép ngắt.
8. Hàm PWM_Stop()
Thực hiện dừng ngắt timer và giải phóng các ngắt timer, ngắt ngoài
9. Hàm button_interrupt()
Đếm số xung ngắt ngoài trong khoảng thời gian của ngắt timer.
10. Hàm timer_interrupt():
Lấy giá trị tốc độ thực và gọi hàm hiệu chỉnh PID_controller().
11. Hàm PID_controller():
Thực hiện hiệu chỉnh tốc độ động cơ theo giải thuật PID số.
Lƣu ý:
Chương trình code có thể tham khảo trong CD đi kèm.
7.2.2. Camera Driver Để board có thể hỗ trợ usb camera thì trong thiết lập cấu build kernel ở
trên các module sau cần được check: uvc-camera, v4l2. Khi kernel đã hỗ trợ
camera lúc gắn vào camera sẽ được nhận và tạo một node trong /dev/video0.
Đa phần các usb camera sử dụng stream I/O để trao đổi dữ liệu với bên
ngoài thay vì sử dụng cơ chế read/write. Streaming I/O được thực hiện bởi cơ
chế memory mapping hoặc userpointer. Camera dùng trong project này sử
dụng cơ chế memory mapping.
Streaming I/O là một phương pháp I/O trong đó chỉ có pointer đến
buffer được truyền giữa application và driver, thay vì copy dữ liệu. Memory
mapping dùng để map buffer ở device vào không gian bộ nhớ của application.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 120
Streaming được thiết bị hỗ trợ nếu như flag V4L2_CAP_STREAMING thuộc
struct v4l2_capability được set.
Các bước khởi tạo bộ nhớ cho streamming I/O:
-Truyền thông báo cấp phát device buffer tới camera.
-Application truy vấn địa chỉ các buffer được tạo.
-Map tất cả các buffer của camera vào vùng nhớ của application.
Streaming drivers quản lý 2 buffer queue, incoming và outgoing queue.
Buffer sẽ được đẩy dữ liệu vào theo incoming queue, và được capture theo thứ
tự lấy ra từ outgoing queue. Hình dưới sẽ minh họa rõ hơn cơ chế hoạt động
của chúng.
Trao đổi dữ liệu với camera thông qua queue buffer.
Ban đầu tất cả các buffer của application đang ở trạng thái dequeue và
driver không thể truy xuất được, đầu tiên tất cả các buffer sẽ được enqueue
vào incoming queue. Khi đó driver có thể ghi được dữ liệu vào trong buffer.
Buffer khi được ghi xong dữ liệu sẽ được chuyển vào outgoing queue.
Applications chờ ở outgoing queue khi có buffer được ghi xong nó sẽ đọc
buffer đó để lấy dữ liệu và lại enqueue buffer đó vào incoming queue cho
driver.
Các bước đọc dữ liệu từ camera như sau:
-Application gửi lệnh enqueue tất cả các buffer
-Application gửi lệnh cho phép camera bắt đầu gửi dữ liệu
-Application thực hiện việc lấy dữ liệu từ buffer: dequeue một
buffer rồi đọc dữ liệu trong buffer đó, sau đó enqueue buffer trở lại cho
device.
-Gửi lệnh kết thúc việc truyền dữ liệu của camera.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 121
7.3. Giao Diện Điều Khiển Ngƣời Dùng Trong chương 4, chúng ta đã tìm hiểu được:
Cách xây dựng một project trong Qt
Khái niệm Signal & Slot
Viết một ứng dụng UI bằng Qt Designer và bằng dòng lệnh
Do đó, trong phần này chúng ta mặc nhiên đã biết cách viết các ứng dụng
thuần túy của Qt (keyboard, buttons, …) và chỉ trình bày các phần liên quan tới truy
xuất hardware như: truyền tốc độ đặt điều khiển động cơ, thu nhận ảnh từ camera.
7.3.1. Cấu Trúc File Của Chƣơng Trình Chính
Hình 7.3. Cấu trúc file của chương trình chính
Điều Khiển Camera
Điều Khiển Động Cơ Main Program
control.cpp control.h
motor_1.ui
common.h common.cpp
testcam.h testcam.cpp
Tạo Button
button.h button.cpp
main.cpp
motor_1.h
motor_1.cpp
ocr_proc.h
Motor_1.pro preview.h preview.cpp
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 122
Cấu trúc file của chương trình được chia làm 3 module chính tương ứng với 3
phần:
Main Program: chứa các file do Qt tự động sinh ra khi tạo một project.
Tạo Button: chứa các hàm dùng để tạo ra button.
Điều Khiển Động Cơ: chứa các hàm truyền điều khiển xuống
Motor_Driver như truyền tốc độ đặt ban đầu động cơ.
Điều Khiển Camera: chứa các hàm truyền điều khiển xuống
Camera_Driver như init, open, capture, close,…
Chương trình được xây dựng theo dạng module tạo điều kiện dễ dàng cho việc
quản lí trong đó các hàm được nhóm lại theo chức năng. Khi đó trong trường
chương trình muốn thực hiện tác vụ thì chỉ việc gọi và truyền đúng đối số cho hàm
con tương ứng tại mỗi modules.
Chúng ta sẽ thấy điều này qua các slots : Start_Clicked(),
Stop_Clicked(),Set_Clicked() tương ứng với các nút điều khiển trên
giao diện trong phần sau khi chúng gọi tới các hàm con tại các module khác.
Ví Dụ:
Trong slots : start_Clicked() tương ứng với việc nhấn button “START”
Hình 7.4. Cách chuyển dòng chảy chương trình giữa các file
7.3.2. Chi Tiết Giao Diện
Giao diện người dùng bao gồm:
Bàn phím cho phép nhập thông tin khách hàng (ID number) và đặt
tốc độ ban đầu của động cơ khi cần thay đổi (Set Speed).
2 line cho phép hiển thị giá trị thông tin đã nhập
Main program
Slots
Điều Khiển Động Cơ
Start_Clicked()
stop_motor()
Open_motor()
Set_speed()
Close_motor()
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 123
2 nút điều khiển nhập thông tin: “CLEAR” xóa giá trị vừa nhập
(trong trường hợp nhập sai) và “ENTER” xác nhận thông tin vừa nhập.
3 nút điều khiển: START, STOP, SET SPEED
*“START”
Thực hiện khi đã nhập đầy đủ và xác nhận thông tin hợp lệ.
Khi được nhấn, camera bắt hình ảnh xe vào và thông tin này được lưu trong bộ
nhớ cùng với mã ID đã nhập. Sau đó, động cơ DC được chạy với tốc độ đặt trước để
mở cổng chắn.
Trường hợp, chưa nhập ID hoặc chưa xác nhận thông tin thì sẽ đưa ra cảnh báo
“Some parameters are empty or press Enter to confirm”
* “STOP”
Khi được nhấn, trả hệ thống về trạng thái mặc định ban đầu: dừng động cơ và
camera về chế độ mặc định ( hiển thị hình ảnh lên màn hình điều khiển).
Thực hiện khi barie được mở tới vị trí phù hợp.
*“SET SPEED”
Được nhấn để nhập tốc độ quay của động cơ.
Thông thường, tốc độ mở động cơ ít thay đổi nên được đặt ở giá trị mặc đinh
1500v/ph. Tuy nhiên, trong một số trường hợp người quản lí bãi muốn thay đổi để
tăng hoặc giảm tốc độ mở cổng chắn, nút điều khiển này cho phép thực hiện việc
này.
Hình 7.5. Giao diện điều khiển người dùng chính
7.3.3. Chi Tiết Các Đối Tƣợng Chính
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 124
- Được tạo ra bằng cách định nghĩa dòng lệnh vì các đối tượng này (widget)
không được định nghĩa sẵn trong Qt Designer.
- Bao gồm 2 classes:
Motor_1 là đối tượng chính bao gồm tất cả các đối tượng của chương
trình. Do đó nó cũng chứa keyboard muốn tạo này.
Button là đối tượng sử dụng cho mỗi button. Nó thừa kế từ lớp
QToolButton.
1. Định nghĩa Class Motor_1
public:
MOTOR_1 (QWidget *parent = 0);
private slots:
void digitClicked();
void enterClicked();
void clear();
void startClicked();
void stopClicked();
void setClicked();
Hình 7.6. Định Nghĩa Class Motor_1
Class Motor_1 định nghĩa hàng loạt các slots tương ứng với các signals do các đối
tượng tạo ra.
Bảng tương ứng signal – slot
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 125
Hình 7.7. Bảng tương ứng giữa Signal và Slot
Tiếp theo, khai báo các đối tượng button: start, stop, set thừa kế từ class
QPushButton
Hàm xây dựng createButton() được khai báo nhằm sử dụng tạo ra các buttons
trong giao diện.
Vì đặc tính gần giống nhau của các button „0‟ tới button‟9‟ ( cùng một slots)
nên ta nhóm chúng tạo thành một group bằng cách khai báo theo kiểu enum.
private:
QPushButton *startButton;
QPushButton *stopButton;
QPushButton *setButton;
QLineEdit *bienso;
QLineEdit *tocdo;
private:
int fd;
Image grayImg;
SIGNAL SLOT
….
Button ‘0’
Button ‘9’
Button ‘Enter’’
Button ‘Clear’
digitClicked()
enterClicked()
startCliked()
Button ‘Set Speed’
Clear()
stopCliked()
setClicked()
Button ‘Start’
Button ‘Stop’
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 126
previewThread* t;
private:
Button *createButton(const QString &text, const char
*member);
enum { NumDigitButtons = 10 };
Button *digitButtons[NumDigitButtons];
Hình 7.8. Định nghĩa các button
2. Thực Thi Class Motor_1
Việc thực thi class Motor_1 được hiểu như sau:
Khai báo các đặc tính các buttons đã được định nghĩa trong phần định
nghĩa trên: size, name, signal,…
Thực hiện liên kết giữa các signals và slots (lưu ý: ở trên ta mới chỉ định
nghĩa các slots mà chưa liên kết).
Thực hiện Layout trên giao diện.
Các công việc này đã được giải thích rõ ràng trong chương 4 ( vì hoàn toàn thuần
túy các đặc tính của Qt)
Ví Dụ:
- Khai báo đặc tính của lineedit : hiển thị giá trị ID number và set Speed.
QLabel *label1 = new QLabel(tr("ID number:"));
bienso = new QLineEdit;
bienso->setReadOnly(true);
bienso->setAlignment(Qt::AlignRight);
bienso->setMaxLength(15);
QLabel *label2 = new QLabel(tr("Set Speed:"));
tocdo = new QLineEdit("1500"); tocdo->setReadOnly(true);
tocdo->setAlignment(Qt::AlignRight);
tocdo->setMaxLength(15);
Hình 7.9. Khai báo đặc tính các line Edit
- Tạo các button bằng hàm createButton() và liên kết signal & slot
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 127
Hình 7.10. Tạo các button bằng hàm
- Layout các đối tượng
Hình 7.11. Layout các đối tượng
- Khai báo các slots tương ứng
Hàm start_Clicked()
QGridLayout *keyLayout = new QGridLayout;
keyLayout->setSizeConstraint(QLayout::SetFixedSize);
for (int i = 1; i < NumDigitButtons; ++i) {
int row = ((9 - i) / 3) + 2;
int column = ((i - 1) % 3) + 1;
keyLayout->addWidget(digitButtons[i], row, column);
}
keyLayout->addWidget(digitButtons[0], 5, 1);
keyLayout->addWidget(enterButton, 5, 2);
keyLayout->addWidget(clearButton, 5, 3);
Button *startButton = createButton(tr("Start"), SLOT(startClicked()));
Button *stopButton = createButton(tr("Stop"), SLOT(stopClicked()));
Button *setButton = createButton(tr("Set Speed"), SLOT(setClicked()));
QFont font = bienso->font();
font.setPointSize(font.pointSize() + 6);
bienso->setFont(font);
tocdo->setFont(font);
for (int i = 0; i < NumDigitButtons; i++) {
digitButtons[i] = createButton(QString::number(i),
SLOT(digitClicked()));
}
Button *enterButton = createButton(tr("ENTER"),
SLOT(enterClicked()));
Button *clearButton = createButton(tr("CLEAR"), SLOT(clear()));
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 128
Hình 7.12. Khai báo tác vụ start_Clicked()
Hàm có nhiệm vụ kiểm tra các thông tin hợp lệ hay không sau đó cho phép bắt giữ
hình ảnh camera và chạy động cơ với tốc độ đặt cho trước.
Việc bắt hình ảnh và chạy động cơ thực hiện bằng cách gọi các hàm đã định nghĩa
trong các file “control” (động cơ) và “common”, “testcam”,”preview” (camera)
Hàm Stop_Clicked()
Hình 7.13. Khai báo tác vụ stop_Clicked()
Hàm thực hiện trả hệ thống về trạng thái mặc định ban đầu:
void MOTOR_1::stopClicked()
{
/* come back to the default status*/
bienso->setText("0");
tocdo->setText("1500");
vantocdat = 1500;
xuat = 1; /* enable to input next ID */
dat = 0; /* unable to set speed */
/* stop Motor */
ret = stop_motor();
if (ret<0){
QMessageBox::warning( this, "Warning",
"Cannot stop motor\n"
"Please try again!\n ",
"Quit", 0, 0, 1 );
}
/* come back the init status of camera*/
t = new previewThread();
fd = initCam();
t->previewCam(fd);
}
void MOTOR_1::startClicked()
{
if((xuat!=0)||(dat!=0)){
QMessageBox::warning( this, "Warning",
"Some parameters are empty or press Enter to confirm\n"
"Please check again!\n ",
"Quit", 0, 0, 1 );
return;
}
/*capture photo*/
t->terminate();
grayImg = capture(fd);
set_speed(vantocdat); /*run motor*/
}
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 129
- Dừng động cơ.
- Trả camera về trạng thái hiện thị hình ảnh lên màn hình.
-
Hàm set_Clicked()
Hình 7.14. Khai báo tác vụ set_Clicked()
Hàm cho phép thay đổi tốc độ của động cơ.
* Các hàm điều khiển camera
- Hàm init camera
Thực hiện các chức năng:
Init frame buffer
Kiểm tra camera
Định kích cỡ hình ảnh
void MOTOR_1::setClicked()
{
dat = 1; /* enable to set speed */
xuat = 0 ; /* unable to input ID*/
tocdo->setText(""); /* clear previous speed's value*/
}
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 130
int initCam()
{
int dev_fd;
struct v4l2_capability cap;
struct v4l2_format fmt;
/** Init frame buffer device */
initFrameBuffer();
frBuf.width = 240;
frBuf.height = 192;
/** Camera process */
if ((dev_fd = open( "/dev/video0", O_RDWR)) == -1)
perror("ERROR opening camera interface\n");
if (0 != ioctl(dev_fd, VIDIOC_QUERYCAP, &cap)) {
if (EINVAL == errno) {
fprintf (stderr, "No V4L2 device\n");
return 1;
} else {
perror ("VIDIOC_QUERYCAP");
return 1;
}
}
if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) {
fprintf (stderr, "No video capture device\n");
return 1;
}
/// set size of capture image
memset(&fmt,sizeof(fmt),0);
fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmt.fmt.pix.width = WIDTH;
fmt.fmt.pix.height = HEIGHT;
fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
if(0 != ioctl(dev_fd, VIDIOC_S_FMT, &fmt)){
perror("VIDIOC_S_FMT");
return 1;
}
if(fmt.fmt.pix.width != WIDTH || fmt.fmt.pix.height !=
HEIGHT) {
printf("mode %d x %d not support\n", WIDTH,
HEIGHT);
WIDTH = fmt.fmt.pix.width;
HEIGHT = fmt.fmt.pix.height;
}
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 131
- map buffer
/** map buffer */
buffers = calloc (reqbuf.count, sizeof (*buffers));
assert (buffers != NULL);
for (i = 0; i < reqbuf.count; i++) {
memset (&buffer, 0, sizeof (struct v4l2_buffer));
buffer.type = reqbuf.type;
buffer.memory = V4L2_MEMORY_MMAP;
buffer.index = i;
if (-1 == ioctl (dev_fd, VIDIOC_QUERYBUF, &buffer)) {
perror ("VIDIOC_QUERYBUF");
exit (EXIT_FAILURE);
}
buffers[i].length = buffer.length; /*remember for munmap()
*/
buffers[i].start = mmap (NULL, buffer.length,
PROT_READ | PROT_WRITE, /* recommended */
MAP_SHARED,
/* recommended */
dev_fd, buffer.m.offset);
if (MAP_FAILED == buffers[i].start) {
/* If you do not exit here you should unmap() and free()
the buffers mapped so far. */
perror ("mmap");
exit (EXIT_FAILURE);
}
}
/** Buffer rgb */
rgbBuf.width = WIDTH;
rgbBuf.height = HEIGHT;
rgbBuf.BPP = 16;
rgbBuf.addr = malloc(WIDTH* HEIGHT * sizeof(PIXEL));
int ret = 0;
int i;
/** set request buffer param */
memset (&reqbuf, 0, sizeof (reqbuf));
reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
reqbuf.memory = V4L2_MEMORY_MMAP;
reqbuf.count = NB_BUFFER;
/// request buffer
if (-1 == ioctl (dev_fd, VIDIOC_REQBUFS, &reqbuf)) {
if (errno == EINVAL)
printf ("Video capturing or mmap-streaming
is not supported\n");
else
perror ("VIDIOC_REQBUFS");
exit (EXIT_FAILURE);
}
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 132
Cho phép video steam
Hình 7.15. Khai báo hàm Init_Cam()
- Hàm capture : bắt giữ hình ảnh camera
Hình 7.16 Khai báo hàm capture()
7.3.4 Sự Liên Hệ Các File trên chƣơng trình Ứng Dụng & Driver Tƣơng Ứng
Rõ ràng trong phần trình bày, các file của chương trình ứng dụng lần lượt thực
hiện điều khiển tới phần cứng. Vấn đề đặt ra bằng cách nào?
Như đã trình bày trong các chương 5 (Device Drivers), cấu trúc Linux được
chia làm 2 phần: User Space & Kernel Space
Image capture(int fd){
int i, j;
// write buf
/** read from buffer */
//buffers[buffer.index].start
Image grayImg = createImage(HEIGHT, WIDTH);
for(j = 0; j < HEIGHT; j++){
for(i = 0; i < WIDTH;i++){
grayImg.pixels[j][i] = (*(uint8_t
*)(buffers[buffer.index].start+ 2*(i+j*WIDTH)));
}
}
printf("read complete\n");
/** Cleanup. */
for (i = 0; i < reqbuf.count; i++)
munmap (buffers[i].start, buffers[i].length);
close(fd);
return grayImg;
/** queue buffer */
for (i = 0; i < reqbuf.count; ++i)
{
memset(&buffer, 0, sizeof(struct v4l2_buffer));
buffer.index = i;
buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buffer.memory = V4L2_MEMORY_MMAP;
ret = ioctl(dev_fd, VIDIOC_QBUF, &buffer);
if (ret < 0)
{
perror("VIDIOC_QBUF - Unable to queue
buffer");
exit (EXIT_FAILURE);
}
}
/** enable video stream */
int type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(dev_fd, VIDIOC_STREAMON, &type);
if (ret < 0)
{
perror("VIDIOC_STREAMON - Unable to start capture");
exit (EXIT_FAILURE);
}
return dev_fd;
}
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 7: CHƯƠNG TRÌNH ĐIỀU KHIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 133
Trong đó: Driver chạy trong Kernel Space
User Program chạy trong User Space
Các ứng dụng trong user program thực hiện truy xuất tới phần cứng thông qua
các driver.
Như vậy việc thực hiện truy xuất phần cứng bao gồm các bước sau:
Hàm trong user space gọi và truyền các thông số tương ứng cho các tác
vụ được định nghĩa trong driver.
Các tác vụ trong driver tương ứng gọi tới các system call của kernel
Các system call thực hiện điều khiển hardware
Ví Dụ: User Program muốn điều khiển tốc độ động cơ với vận tốc định trước.
- “Control.h” & “control.cpp” trong user space định nghĩa các hàm tương
ứng: open_motor(), close_motor(),..
- Các hàm này thực hiện gọi tới các tác vụ trong Motor_Driver tương
ứng: open, ioctl,…
- Các tác vụ gọi các system call của kernel để đáp ứng.
Hình 7.17.: Mối liên hệ giữa các hàm trong User Space và Kernel Space
USER SPACE KERNEL SPACE
“control.h”
Functions
Open_motor()
stop_motor()
close_motor()
set_speed()
Motor_Driver
File_Operations
Module_init
open
Module_exit
release
read
ioctl
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 134
CHƢƠNG 8
XỬ LÍ ẢNH
8.1GIỚI THIỆU TỔNG QUAN VỀ XỬ LÍ ẢNH:
8.1.1 Xử Lí Ảnh Và Các Vấn Đề Cơ Bản Trong Xử Lí Ảnh
8.1.1.1 Địng nghĩa xử lí ảnh
Con người thu nhận thông tin qua các giác quan, trong đó
thị giác đóng vai trò quan trọng nhất. Những năm trở lại đây với sự phát
triển của phần cứng máy tính, xử lý ảnh và đồ hoạ đó phát triển một cách
mạnh mẽ và có nhiều ứng dụng trong cuộc sống. Xử lý ảnh và đồ hoạ
đóng một vai trò quan trọng trong tương tác người máy.
Quá trình xử lý ảnh được xem như là quá trình thao tác ảnh đầu vào
nhằm cho ra kết quả mong muốn. Kết quả đầu ra của một quá trình xử lý
ảnh có thể là một ảnh “tốt hơn” hoặc một kết luận.
Ảnh
XỬ LÝ ẢNH
Ảnh
“Tốt hơn”
Kết luận
Hình 8.1. Quá trình xử lý ảnh
Ảnh có thể xem là tập hợp các điểm ảnh và mỗi điểm ảnh được xem
như là đặc trưng cường độ sáng hay một dấu hiệu nào đó tại một vị trí nào
đó của đối tượng trong không gian và nó có thể xem như một hàm n biến
P(c1, c2,..., cn). Do đó, ảnh trong xử lý ảnh có thể xem như ảnh n chiều.
Sơ đồ tổng quát của một hệ thống xử lý ảnh:
Thu nhận ảnh
(Scanner,
Camera,Sensor)
Tiền xử lý
Trích chọn
đặc điểm
Hậu
xử lý
Hệ quyết định Đối sánh rút
ra kết luận
Lưu trữ
Hình 8.2. Các bƣớc cơ bản trong một hệ thống xử lý ảnh
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 135
Điểm ảnh được xem như là dấu hiệu hay cường độ sáng tại 1 toạ độ
trong không gian của đối tượng và ảnh được xem như là 1 tập hợp các
điểm ảnh.
* Mức xám, màu
Là số các giá trị có thể có của các điểm ảnh của ảnh
8.1.1.2 Khử nhiễu
Có 2 loại nhiễu cơ bản trong quá trình thu nhận ảnh
-Nhiều hệ thống: là nhiễu có quy luật có thể khử bằng các phép
biến đổi
-Nhiễu ngẫu nhiên: vết bẩn không rõ nguyên nhân → khắc phục
bằng các phép lọc
8.1.1.3 Chỉnh mức xám
Nhằm khắc phục tính không đồng đều của hệ thống gây ra. Thông thường
có 2 hướng tiếp cận:
-Giảm số mức xám: Thực hiện bằng cách nhóm các mức xám
gần nhau thành một bó. Trường hợp chỉ có 2 mức xám thì chính là chuyển
về ảnh đen trắng. Ứng dụng: In ảnh màu ra máy in đen trắng.
-Tăng số mức xám: Thực hiện nội suy ra các mức xám trung
gian bằng kỹ thuật nội suy. Kỹ thuật này nhằm tăng cường độ mịn
cho ảnh
8.1.1.4 Trích chọn đặc điểm
Các đặc điểm của đối tượng được trích chọn tuỳ theo mục đích nhận
dạng trong quá trình xử lý ảnh. Có thể nêu ra một số đặc điểm của ảnh
sau đây:
-Đặc điểm không gian: Phân bố mức xám, phân bố xác suất, biên độ,
điểm uốn v.v..
-Đặc điểm biến đổi: Các đặc điểm loại này được trích chọn bằng việc
thực hiện lọc vùng (zonal filtering). Các bộ vùng được gọi là “mặt nạ đặc
điểm” (feature mask) thường là các khe hẹp với hình dạng khác nhau (chữ
nhật, tam giác, cung tròn v.v..)
-Đặc điểm biên và đường biên: Đặc trưng cho đường biên của đối
tượng và do vậy rất hữu ích trong việc trích trọn các thuộc tính bất biến
được dùng khi nhận dạng đối tượng. Các đặc điểm này có thể được trích
chọn nhờ toán tử gradient, toán tử la bàn, toán tử Laplace, toán tử “chéo
không” (zero crossing) v.v..
Việc trích chọn hiệu quả các đặc điểm giúp cho việc nhận dạng các
đối tượng ảnh chính xác, với tốc độ tính toán cao và dung lượng nhớ lưu
trữ giảm xuống.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 136
8.1.1.5 Nhận dạng
Nhận dạng tự động (automatic recognition), mô tả đối tượng, phân
loại và phân nhóm các mẫu là những vấn đề quan trọng trong thị giác máy,
được ứng dụng trong nhiều ngành khoa học khác nhau. Tuy nhiên, một câu
hỏi đặt ra là: mẫu (pattern) là gì? Watanabe, một trong những người đi đầu
trong lĩnh vực này đã định nghĩa: “Ngược lại với hỗn loạn (chaos), mẫu là
một thực thể (entity), được xác định một cách ang áng (vaguely defined) và
có thể gán cho nó một tên gọi nào đó”. Ví dụ mẫu có thể là ảnh của vân tay,
ảnh của một vật nào đó được chụp, một chữ viết, khuôn mặt người hoặc
một ký đồ tín hiệu tiếng nói. Khi biết một mẫu nào đó, để nhận dạng hoặc
phân loại mẫu đó có thể:
Hoặc phân loại có mẫu (supervised classification), chẳng hạn phân
tích phân biệt (discriminant analyis), trong đó mẫu đầu vào được định danh
như một thành phần của một lớp đã xác định.
Hoặc phân loại không có mẫu (unsupervised classification hay
clustering) trong đó các mẫu được gán vào các lớp khác nhau dựa trên một
tiêu chuẩn đồng dạng nào đó. Các lớp này cho đến thời điểm phân loại vẫn
chưa biết hay chưa được định danh.
Hệ thống nhận dạng tự động bao gồm ba khâu tương ứng với ba giai
đoạn chủ yếu sau đây:
1. Thu nhận dữ liệu và tiền xử lý.
2. Biểu diễn dữ liệu.
3. Nhận dạng, ra quyết định.
Bốn cách tiếp cận khác nhau trong lý thuyết nhận dạng là:
1. Đối sánh mẫu dựa trên các đặc trưng được trích chọn.
2. Phân loại thống kê.
3. Đối sánh cấu trúc.
4. Phân loại dựa trên mạng nơ-ron nhân tạo.
Trong các ứng dụng rõ ràng là không thể chỉ dùng có một cách tiếp
cận đơn lẻ để phân loại “tối ưu” do vậy cần sử dụng cùng một lúc nhiều
phương pháp và cách tiếp cận khác nhau. Do vậy, các phương thức phân
loại tổ hợp hay được sử dụng khi nhận dạng và nay đã có những kết quả có
triển vọng dựa trên thiết kế các hệ thống lai (hybrid system) bao gồm nhiều
mô hình kết hợp.
Việc giải quyết bài toán nhận dạng trong những ứng dụng mới, nảy
sinh trong cuộc sống không chỉ tạo ra những thách thức về thuật giải, mà
còn đặt ra những yêu cầu về tốc độ tính toán. Đặc điểm chung của tất cả
những ứng dụng đó là những đặc điểm đặc trưng cần thiết thường là nhiều,
không thể do chuyên gia đề xuất, mà phải được trích chọn dựa trên các thủ
tục phân tích dữ liệu.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 137
8.1.1.6 Nén ảnh
Nhằm giảm thiểu không gian lưu trữ. Thường được tiến hành theo cả
hai cách khuynh hướng là nén có bảo toàn và không bảo toàn thông tin.
Nén không bảo toàn thì thường có khả năng nén cao hơn nhưng khả năng
phục hồi thì kém hơn. Trên cơ sở hai khuynh hướng, có 4 cách tiếp cận cơ
bản trong nén ảnh:
-Nén ảnh thống kê: Kỹ thuật nén này dựa vào việc thống kê tần xuất
xuất hiện của giá trị các điểm ảnh, trên cơ sở đó mà có chiến lược mã hóa
thích hợp. Một ví dụ điển hình cho kỹ thuật mã hóa này là *.TIF
-Nén ảnh không gian: Kỹ thuật này dựa vào vị trí không gian của
các điểm ảnh để tiến hành mã hóa. Kỹ thuật lợi dụng sự giống nhau của các
điểm ảnh trong các vùng gần nhau. Ví dụ cho kỹ thuật này là mã nén
*.PCX
-Nén ảnh sử dụng phép biến đổi: Đây là kỹ thuật tiếp cận theo
hướng nén không bảo toàn và do vậy, kỹ thuật thướng nến hiệu quả hơn.
*.JPG chính là tiếp cận theo kỹ thuật nén này.
-Nén ảnh Fractal: Sử dụng tính chất Fractal của các đối tượng ảnh,
thể hiện sự lặp lại của các chi tiết. Kỹ thuật nén sẽ tính toán để chỉ cần lưu
trữ phần gốc ảnh và quy luật sinh ra ảnh theo nguyên lý Fractal
8.1.2 Thu Nhận Và Biểu Diễn Ảnh
8.1.2.1 Thu nhận, các thiết bị thu nhận ảnh
Các thiết bị thu nhận ảnh bao gồm camera, scanner các thiết bị thu
nhận này có thể cho ảnh đen trắng
Các thiết bị thu nhận ảnh có 2 loại chính ứng với 2 loại ảnh thông
dụng Raster, Vector.
Các thiết bị thu nhận ảnh thông thường Raster là camera các thiết bị
thu nhận ảnh thông thường Vector là sensor hoặc bàn số hoá Digitalizer
hoặc được chuyển đổi từ ảnh Raster.
Nhìn chung các hệ thống thu nhận ảnh thực hiện 1 quá trình
- Cảm biến: biến đổi năng lượng quang học thành năng lượng điện
- Tổng hợp năng lượng điện thành ảnh
8.1.2.2 Biểu diễn ảnh
Ảnh trên máy tính là kết quả thu nhận theo các phương pháp số hoá
được nhúng trong các thiết bị kỹ thuật khác nhau. Quá trình lưu trữ ảnh
nhằm 2 mục đích:
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 138
- Tiết kiệm bộ nhớ
- Giảm thời gian xử lý
Việc lưu trữ thông tin trong bộ nhớ có ảnh hưởng rất lớn đến việc hiển
thị, in ấn và xử lý ảnh được xem như là 1 tập hợp các điểm với cùng kích
thước nếu sử dụng càng nhiều điểm ảnh thì bức ảnh càng đẹp, càng mịn và
càng thể hiện rõ hơn chi tiết của ảnh người ta gọi đặc điểm này là độ
phân giải.
Việc lựa chọn độ phân giải thích hợp tuỳ thuộc vào nhu cầu sử dụng
và đặc trưng của mỗi ảnh cụ thể, trên cơ sở đó các ảnh thường được biểu
diễn theo 2 mô hình cơ bản
a. Mô hình Raster
Đây là cách biểu diễn ảnh thông dụng nhất hiện nay, ảnh được biểu
diễn dưới dạng ma trận các điểm (điểm ảnh). Thường thu nhận qua các
thiết bị như camera, scanner. Tuỳ theo yêu cầu thực thế mà mỗi điểm ảnh
được biểu diễn qua 1 hay nhiều bít
Mô hình Raster thuận lợi cho hiển thị và in ấn. Ngày nay công nghệ
phần cứng cung cấp những thiết bị thu nhận ảnh Raster phù hợp với tốc độ
nhanh và chất lượng cao cho cả đầu vào và đầu ra. Một thuận lợi cho việc
hiển thị trong môi trường Windows là Microsoft đưa ra khuôn dạng ảnh
DIB (Device Independent Bitmap) làm trung gian. Hình 1.4 thể hình quy
trình chung để hiển thị ảnh Raster thông qua DIB.
Một trong những hướng nghiên cứu cơ bản trên mô hình biểu diễn này
là kỹ thuật nén ảnh các kỹ thuật nén ảnh lại chia ra theo 2 khuynh hướng là
nén bảo toàn và không bảo toàn thông tin nén bảo toàn có khả năng phục
hồi hoàn toàn dữ liệu ban đầu còn nếu không bảo toàn chỉ có khả năng
phục hồi độ sai số cho phép nào đó. Theo cách tiếp cận này người ta đã đề
ra nhiều quy cách khác nhau như BMP, TIF, GIF, PCX…
Hiện nay trên thế giới có trên 50 khuôn dạng ảnh thông dụng bao gồm
cả trong đó các kỹ thuật nén có khả năng phục hồi dữ liệu 100% và nén có
khả năng phục hồi với độ sai số nhận được.
BMP
PCC
.
Paint
DIB Cửa sổ
Thay đổi
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 139
Hình 8.3. Quá trình hiển thị và chỉnh sửa, lƣu trữ ảnh thông qua DIB
b. Mô hình Vector
Biểu diễn ảnh ngoài mục đích tiết kiệm không gian lưu trữ dễ dàng cho
hiển thị và in ấn còn đảm bảo dễ dàng trong lựa chọn sao chép di chuyển
tìm kiếm… Theo những yêu cầu này kỹ thuật biểu diễn vector tỏ ra ưu việt hơn.
Trong mô hình vector người ta sử dụng hướng giữa các vector của
điểm ảnh lân cận để mã hoá và tái tạo hình ảnh ban đầu ảnh vector được thu
nhận trực tiếp từ các thiết bị số hoá như Digital hoặc được chuyển đổi từ ảnh
Raster thông qua các chương trình số hoá
Công nghệ phần cứng cung cấp những thiết bị xử lý với tốc độ nhanh và
chất lượng cho cả đầu vào và ra nhưng lại chỉ hỗ trợ cho ảnh Raster.
Do vậy, những nghiên cứu về biểu diễn vectơ đều tập trung từ chuyển
đổi từ ảnh Raster.
8.2 OPENCV
8.2.1 Giới thiệu chung OpenCv là một thư viện trên máy tính với mã nguồn mở.Thư viện này được
viết bằg C và C++,chạy trên Linux, Windows và Mac OS X.Đã có những phát
triển tích cực trên giao diện cho Python, Ruby, Matlab, và những ngôn ngữ khác.
OpenCV được thiết kế để tăng hiệu quả tính toán và với một khả năng tập
trung vào những ứng dụng thời gian thực.OpenCV được viết bằng ngôn ngữ C tối
ưu và có thể tận dụng được khả năng của những bộ xử lí đa nhân.Nếu ta mong
muốn khả sự tối ưu tự động cao hơn nữa trên cấu trúc Intel,ta có thể mua bộ
Intel’s Integrated Performance Primitives (IPP) libraries,đây là thư viện bao gồm
những chương trình con tối ưu ở cấp thấp trong nhiều bộ phận giải thuật khác
nhau.OpenCV sử dụng môt cách tự động thư viện IPP thích hợp ở thời gian thực
thi nếu thư viện đó đã được cài đặt.
Một trong những mục đích của OpenCV là cung cấp một cấu trúc máy tính
đơn giản để sử dụng, điều này giúp chúng ta biên dịch chương trình phức tạp một
cách nhanh chóng.Thư viện OpenCV có hơn 500 hàm mà có liên quan trên nhiều
lĩnh vực trong sự nhìn, bao gồm kiểm định sản phẩm trong nhà máy,hình ảnh
trong y tế,an ninh,giao tiếp người dùng,cân chỉnh thiêt bị nghe nhìn, và robot.Bởi
vì sự nhìn máy tính và việc học của máy thường là diến ra “tay trong
tay”,OpenCV cũng chứa đựng một thư viện cho việc học của máy với mục đích
chung và đầy đủ.Thư viện cấp dưới này được tập trung vào các mẫu nhận dạng
tĩnh và gộp chúng lại.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 140
8.2.2 Build OpenCV cho ARM
* Đầu tiên là tải gói thư viện nguồn:
http://sourceforge.net/projects/opencvlibrary/
* Sau khi tải và giải nén ta tiến hành cấu hình lại theo các lệnh dưới đây:
-Chọn bộ dịch Arm compiler:
CXX=<path_gcc>/bin/arm-linux-g++
-Chọn mục tiêu là hệ thống nhúng:
--host=arm-linux --target=arm-linux –
-Chọn bỏ các thư viện mà hiện tại không có sẵn trong hệ thống nhúng của
mình:
--without-gtk --without-gthread --without-libjpeg --without-
zlib --without-libpng --without-libtiff --without-libjasper --without-
ffmpeg --without-raw1394 --without-v4l2 --without-python
-Chọn thư mục để các file đã được biên dịch sẽ được chép vào trong hệ
thống nhúng của ta khi ta thực hiện lệnh “make install”
--prefix=<path_image>/usr/
-Thực hiện build toàn bộ thư viện OpenCV để chuẩn bị cài đặt:
# make
(Sau khi thực hiện các lệnh trên thường là sẽ không có lỗi gì phát sinh trong quá
trình build)
8.2.3 Những file cần copy vào hệ thống file nguồn(root file system) của
hệ thống
Nếu việc cấu hình –prefix trong các bước trên không được làm thì sẽ là
cần thiết để chép toàn bộ các file sau đây và cũng cần tạo các đường link mềm.
-Tất cả các file trong thư mục /usr/include/opencv trên máy tính chủ cần
phải tương tự với thư mục cùng tên trên board hay trên hệ thống hướng tới
<path_image>/usr/include/opencv).
-Chép file ./opencv-1.0.0/cv/src/.libs/libcv.so.1.0.0 đến thư mục path>usr/lib
của thư mục trên hệ thống đích.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 141
-Chép file ./opencv-1.0.0/cxcore/src/.libs/libcxcore.so.1.0.0 đến thư mục
<path/usr/lib của hệ thống đích
-Chép file ./opencv-1.0.0/others/highgui/.libs/libhighgui.so.1.0.0 đến thư
mục <path_image>/usr/lib của hệ thống đích.
-Chép ./opencv-1.0.0/cvaux/src/.libs/libcvaux.so.1.0.0 đến thư mục
<path_image>/usr/lib của hệ thống đích.
-Chép file ./opencv-1.0.0/ml/src/.libs/libml.so.1.0.0 đến
<path_image>/usr/lib của hệ thống đích.
Với mỗi thư viện này,sẽ là cần thiết để tạo hai đường link dẫn với các lệnh
sau(trong cùng thư mục trên hệ thống đích <path_image>]/usr/lib):
#ln -s <library name>.so.1.0.0 <library name>.so.1
#ln -s <library name>.so.1 <library name>.so
8.2.4 Các thự viện phụ thuộc cho phần build ứng dụng
Bên cạnh các thư viện của OpenCV thì ta cũng cần các thư viện định dạng
cho ảnh thích hợp để tiến hành build ứng dụng
8.2.4.1 Thƣ viện libpng
-Download code nguồn http://www.libpng.org/pub/png/libpng.html.
-Sau khi giải nén ta vào thư mục đó và tiến hành cấu hình với các lệnh sau:
#./configure
Trong file đã mở ta thêm các lệnh sau(với mục đích giống như phần build
OpenCV đã được trình bày ở trên)
CC=<path_gcc>/bin/arm-linux-gcc
--prefix=<path_rootfs>/usr/ -- with --<path_gcc>/arm-linux/.
--host=arm-linux --target=arm-linux
-Tiếp tực thực hiện các lệnh sau theo thứ tự để cài đặt vào thư mục đã chọn:
#make #make install(để lệnh này thực hiện đúng ta nên tạo
một thư mục với đường link :<path_rootfs>/usr/man/man1)
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 142
8.2.4.2 Thƣ viện libjpeg
-Download code nguồn http://freshmeat.net/projects/libjpeg/
-Sau khi giải nén ta vào thư mục đó và tiến hành cấu hình với các lệnh sau:
#./configure
Trong file đã mở ta thêm các lệnh sau(với mục đích giống như phần build OpenCV
đã được trình bày ở trên)
CC=<path_gcc>/bin/arm-linux-gcc
--prefix=<path_rootfs>/usr/ --<path_gcc>/arm-linux/.
--host=arm-linux --target=arm-linux
--enable-shared ->để chọn version có thể chia sẻ thay vì version cố
định
-Tiếp tực thực hiện các lệnh sau theo thứ tự để cài đặt vào thư mục đã chọn:
#make
#make install(để lệnh này thực hiện đúng ta nên tạo một thư mục với
đường link :<path_rootfs>/usr/man/man1)
Chú ý: Trong trường hợp này chúng ta cần phải thay đổi ./configure để
biên dịch đúng với version có thể chia sẻ của thư viện: tại dòng 1562 ta nên thêm
vào cấu trúc đích là “arm-linux” rồi mới thực hiện lệnh make và make install
8.2.4.3 Thƣ viện libz
-Download code nguồn http://www.zlib.net/
-Sau khi giải nén ta vào thư mục đó và tiến hành cấu hình với các lệnh sau:
#./configure
Trong file đã mở ta thêm các lệnh sau(với mục đích giống như phần build OpenCV
đã được trình bày ở trên)
CC=<path_gcc>/bin/arm-linux-gcc
--prefix=<path_rootfs>/usr/ --<path_gcc>/arm-linux/.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 143
--host=arm-linux --target=arm-linux
--enable-shared ->để chọn version có thể chia sẻ thay vì version
cố định
-Tiếp tực thực hiện các lệnh sau theo thứ tự để cài đặt vào thư mục đã chọn:
#make
#make install(để lệnh này thực hiện đúng ta nên tạo một thư mục với
đường link :<path_rootfs>/usr/man/man1)
8.2.4.4 Thư viện libtiff
-Download code nguồn http://www.zlib.net/
-Sau khi giải nén ta vào thư mục đó và tiến hành cấu hình với các lệnh sau:
#./configure
Trong file đã mở ta thêm các lệnh sau(với mục đích giống như phần build OpenCV
đã được trình bày ở trên)
CC=<path_gcc>/bin/arm-linux-gcc
--prefix=<path_rootfs>/usr/ --<path_gcc>/arm-linux/.
--host=arm-linux --target=arm-linux
--enable-shared ->để chọn version có thể chia sẻ thay vì version
cố định
-Tiếp tực thực hiện các lệnh sau theo thứ tự để cài đặt vào thư mục đã chọn:
#make
#make install(để lệnh này thực hiện đúng ta nên tạo một thư mục với
đường link :<path_rootfs>/usr/man/man1)
8.2.4.5 Thƣ viện libjasper
-Download code nguồn http://packages.qa.debian.org/j/jasper.html
-Sau khi giải nén ta vào thư mục đó và tiến hành cấu hình với các lệnh sau:
#./configure
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 144
Trong file đã mở ta thêm các lệnh sau(với mục đích giống như phần build OpenCV
đã được trình bày ở trên)
CC=<path_gcc>/bin/arm-linux-gcc
--prefix=<path_rootfs>/usr/ --<path_gcc>/arm-linux/.
--host=arm-linux --target=arm-linux
--enable-shared ->để chọn version có thể chia sẻ thay vì version
cố định
-Tiếp tực thực hiện các lệnh sau theo thứ tự để cài đặt vào thư mục đã chọn:
#make
#make install(để lệnh này thực hiện đúng ta nên tạo một thư mục với
đường link :<path_rootfs>/usr/man/man1)
8.2.5 Một cách build khác
-Đầu tiên cần them đường dẫn vào thư mục download
Code:
nano /etc/apt/sources.list
Thêm dòng
deb http://ftp.de.debian.org/debian squeeze main
vào shell sources.list
-Kết nối cổng Ethernet với modem Internet
-Gõ các dòng lệnh sau để tải các tool cần thiết trước khi bắt đầu build
Code:
apt-get update
apt-get install build-essential
-Tải các thư viện cần dùng cho OpenCV bằng dòng lệnh sau
Code:
apt-get install libcv-dev
-Tải và cài đặt cmake:
Cmake là chương trình để tạo các makefile, bắt buộc phải có nếu dùng OpenCV từ
phiên bản 2.0.0 trở đi
apt-get install cmake
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 145
-Tải và cài đặt subversion:
Chương trình quản lý và kiểm tra các phiên bản mã nguồn trong quá trình phát
triển của phần mềm, được gọi sử dụng bằng lệnh svn
Code:
apt-get install subversion
-Tải openCV phiên bản mới nhất
svn co https://code.ros.org/svn/opencv/trunk
-Tạo makefile
cd /<đường dẫn>/opencv
mkdir release
cd release
cmake -D CMAKE_BUILD_TYPE=RELEASE -D
CMAKE_INSTALL_PREFIX=/usr/local -D BUILD_PYTHON_SUPPORT=ON -
D BUILD_EXAMPLES=ON ..
-Cài đặt OpenCV
Dùng lệnh make để tạo các file cần thiết cho việc cài đặt
make
Sau đó sẽ hiện ra dòng dưới đây
[ 1%] Building C object 3rdparty/lapack/CMakeFiles/ opencv_lapack.dir/dcopy.o
…
Sau khi make thành công, build được 100%, ta gõ lệnh make install để cài
OpenCV vào hệ thống
make install
-Kết thúc cài đặt, kiểm tra các thư viện và included file bằng 2 dòng lệnh
sau:
Code:
pkg-config opencv –cflags
pkg-config opencv –libs
Nếu thấy hiện ra tương tự như sau là ổn
/usr/local/include/opencv
/usr/local/lib
-Nếu không thấy, tải và cài đặt pkg-config bằng dòng lệnh
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 146
Code:
apt-get install pkg-config
hoặc
apt-get install bzip2 pkg-config
-Sau đó, biên dịch các demo bằng dòng lệnh
Code:
gcc –ggdb $(pkg-config –-cflags opencv) –o <tên demo> <tên demo>.c $(pkg-
config –libs opencv)
hoặc
g++ –ggdb $(pkg-config –-cflags opencv) –o <tên demo> <tên demo>.cpp $(pkg-
config –libs opencv)
8.3 Nhận Dạng Biển Số Xe
8.3.1 Giới thiệu các bƣớc chính
Quá trình nhận dạng biển số xe được chia làm ba bước chính:
Bƣớc 1: Trích biển số xe gắn máy ra khỏi ảnh lớn
Trong bước này, ta dựa vào một số đặc điểm cơ bản của biển số xe so với các vật
thể khác trong ảnh để tách nó ra khỏi ảnh lớn.
Bƣớc 2: Phân vùng biển số xe
Bước này sẽ tách riêng từng ký tự (chữ, số).Vậy từ ảnh biển số ban đầu ta sẽ phân
thành 8 ảnh nhỏ chứa 8 kí tự
Bƣớc 3: Nhận dạng các kí tự
Bước này có thể sử dụng 2 phương pháp: nhận dạng cổ điển với giải thuật so sánh
từng điểm , hoặc phương pháp dùng ứng dụng mang nơron vào ứng dụng kí tự
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 147
8..3.2 Trích biển số xe
Mục đích: Từ bức ảnh chụp được trong bước thu nhận ảnh, áp dụng các
thuật toán trích ra được vùng ảnh nhỏ nhất chứa biển số.
Các phƣơng pháp: có nhiều phương pháp khác nhau để thực hiện
nhiệm vụ này nhưng tất cả đều có thể qui về 3 phương pháp chính sau đây:
- Phương pháp dùng chuyển đổi Hough: dựa vào đặc trưng cạnh biên
trích được, áp dụng các phương pháp xác định đường thẳng như phép biến đổi
Hough để phát hiện các cặp đường thẳng gần song song ghép thành một ảnh biển
số.
- Phương pháp hình thái học: dựa vào đặc trưng hình thái của biển số xe như
màu sắc, độ sáng, sự đối xứng… để xác định và trích ra ảnh biển số.
- Phương pháp khớp mẫu: xem biển số là một đối tượng có khung nền riêng
và sử dụng các cửa sổ dò để trích từng đối tượng đưa qua mạng noron (neural
network), trí tuệ nhân tạo (artificial intelligence) chẳng hạn để phân loại có phải
là vùng biển số hay không.
Nghiên cứu này sẽ sử dụng kết hợp 2 phương pháp là Hình thái học và Chuyển
đổi Hough.
8.3.2.1 Phƣơng pháp hình thái học
Nội dung của phƣơng pháp: Dựa vào đặc trưng quan trọng là biển số xe
máy có độ sáng (tức mức xám khi chuyển bức ảnh về dạng xám) là tương đối khác
so với các vùng khác trong bức ảnh, cũng như sự phân bố mức xám là khá đồng
đều trên biển số và vì vậy khi được nhị phân hoá, vùng biển số là một đối
tƣợng có đặc thù hình thái, có thể phân biệt đƣợc với các vùng khác . Như
vậy các bước thực hiện ở đây là:
- Xác định ngưỡng xám. Thực chất là không có phương pháp nào chọn
cho đúng ngưỡng xám để thực hiện. Thay vào đó, ngưỡng xám sẽ được quét
trong một khoảng nào đó. Thông qua lược đồ xám ta nhận thấy vùng biển số
thường sẽ có độ sáng tương đối lớn (từ 130-200) vì vậy ta sẽ xác định lược đồ xám
lớn nhất trong khoảng này và ngưỡng xám cần chọn sẽ thuộc vùng này nhờ đó ta
sẽ giảm được thời gian lặp tìm ngưỡng xám.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 148
Hình 8.4: Ảnh xám đầu vào Hình 8.5: Lược đồ xám của bức ảnh xám
- Nhị phân hoá ảnh xám đầu vào với ngưỡng xám đã xác định.
- Lọc các nhiễu (salt and pepper noise) gây ảnh hưởng xấu tới đối tượng biển số.
- Gắn nhãn cho các đối tượng còn lại trong ảnh nhị phân thu được.
- Trích ra các đối tượng ứng viên biển số theo tiêu chí cụ thể của biển số xe về
chiều cao, chiều rộng, tỉ lệ các cạnh, diện tích, trọng tâm …Cụ thể nghiên cứu đã
chọn:
7000 pixel ≤ diện tích ≤ 150000 pixel
0,68 ≤ chiều cao/chiều rộng ≤ 0,8
Ưu điểm: - đơn giản
- chọn ra chính xác vùng biển số
Nhược điểm: - thời gian xử lý lớn
8.3.2.2. Phƣơng pháp chuyển đổi Hough
Nội dung của phương pháp: gồm các bước: - Dò đặc trưng biên ngang, dọc: làm nổi bật các viền bao của tất cả các đối
tượng trong ảnh trong đó có viền bao biển số. Phương pháp là sử dụng các bộ lọc gradient để trích được các đặc trưng cạnh biên này. Nghiên cứu này sử dụng bộ lọc Sobel để tiến hành dò.
- Dùng chuyển đổi Hough tìm các đoạn thẳng ngang dọc trên cở sở của ảnh
nhị phân biên cạnh thu được từ bước trên. Ở đây sẽ chọn các đường thẳng cách đều
nhau 5 pixel để dò đường, và loại bỏ các đoạn thẳng nhỏ hơn ngưỡng, cụ thể là có
ít hơn 30 pixel thuộc nó.
- Tách các đoạn thẳng ngang, dọc có thể là cạnh của biển số.
- Trích ứng viên biển số: thành lập các hình chữ nhật là ứng viên cho biển
số với tiêu chí cụ thể là: các bộ 4 đoạn thẳng thu được sẽ qua đánh giá về kích
thước:
80< chiều rộng <400
63< chiều cao <350
0.63< chiều cao/ chiều rộng <0.8
Ưu điểm: không phụ thuộc vào màu sắc của biển số xe
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 149
Nhược điểm: phụ thuộc rất lớn vào bước trích đặc trưng biên cạnh dẫn đến
là các đoạn thẳng ứng viên thu được thường ngắn hơn nhiều so với chiều dọc
cũng như chiều ngang của biển số.
8.3.3 Cách ly các ký tự
Mục đích: tách thành 8 ảnh đơn chứa các kí tự từ ảnh vùng biển số đã thu được.
Phƣơng pháp: cũng có nhiều phương pháp để thực hiện nhiệm vụ này. Có
thể kể ra ở đây như tách tĩnh, lượng tử hóa vecto (vector quantization), lược đồ
chiếu ngang và dọc (vertical and horizontal projection), mạng noron (neural
network), trí tuệ nhân tạo (AI), hình thái học (Morphology)...Nghiên cứu này đã
lựa chọn phương pháp Hình thái học để thực hiện.
Hình 8.6: Tách tĩnh Hình 8.7: Lược đồ chiếu ngang và dọc
của ký tự
Phƣơng pháp hình thái học: mỗi 1 ký tự trên biển số sẽ là 1 đối tượng
có đặc điểm hình thái học cụ thể như là chiều cao, chiều rộng, tỉ lệ 2 chiều…biến
đổi tương đối ít (nếu ảnh biển số được đưa về cùng một kích cỡ) mà dựa vào đó ta
có thể tách ra được cụ thể từng ký tự
một. Từ đó ta có thuật toán tách kí tự từ ảnh xám biển
số sau đây:
- Đưa ảnh xám biển số về cùng độ phân giải 160x210 sau đó thực hiện
xóa biên ảnh biển số.
- Xác định ngưỡng xám để nhị phân bức ảnh biển số. Khâu này rất quan
trọng quyết định tính chính xác của việc nhận dạng kí tự. Nghiên cứu đã chọn
ngưỡng xám theo các bước sau:
+Nâng cao tính tương phản của ảnh biển số bằng thuật toán cân
bằng hóa lược đồ xám(histogram equalization).
+Dùng thuật toán Otsu để xác định ngưỡng xám của bức ảnh mới này, đây là ngưỡng xám cần tìm.
- Lọc nhiễu để loại bỏ bớt các đối tượng và gán nhãn cho các đối tượng còn lại.
- Tách ra các ký tự thông qua đặc tính về hình thái học, cụ thể là:
8 pixel ≤ chiều rộng ≤ 45 pixel
45 pixel ≤ chiều cao ≤ 85 pixel
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 150
Ưu điểm: - Không phụ thuộc vào độ nghiêng của biển số.
- Không phụ thuộc vào nhiễu.
- Biển số có thể không làm sạch được nhưng vẫn nhận dạng chính xác.
Nhƣợc điểm: - Phụ thuộc vào độ chính xác của ảnh nhị phân có lấy hết được
ảnh ký tự từ ảnh xám.
8.3.4 Nhận dạng ký tự
Phƣơng pháp: phương pháp phổ biến nhất để nhận dạng ký tự là sử dụng mạng noron tức là huấn luyện cho máy tính để nhận dạng các ký tự. Tuy nhiên do số lượng ký tự trên biển số là không nhiều nên để đảm bảo tốc độ xử lý nghiên cứu đã sử dụng phương pháp Hình thái học để giải quyết khâu này bởi vì các ký tự đều có nhưng đặc điểm hình thái đặc biệt có thể phân biệt với nhau chẳng hạn như „0‟ có lỗ trống ở giữa, „8‟ có 2 lỗ trống hay „X‟ đối xứng 2 trục dọc và ngang…Đặc biệt khâu này được thực hiện trên cơ sở xây dựng cây nhị phân tối ưu của các đặc điểm hình thái nên đảm bảo tính khoa học và tính chính xác cao. Từ thực tế thực hiện, nghiên cứu đưa ra thuật toán của khâu này như sau:
- Quan sát chọn ra các đặc tính phân biệt ký tự để xây dựng ma trận đặc tính. - Xây dựng cây nhị phân tối ưu từ ma trận đặc tính và tập ký tự thu được từ
bước tách. -Quan sát cây nhị phân và kiểm tra xem số đặc tính như vậy đã đủ để nhận
dạng chưa.
-Tiến hành nhận dạng các kí tự trên cơ sở cây nhị phân tối ưu tìm được.
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 8: NHẬN DẠNG BIỂN SỐ XE GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 151
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 9: KẾT QUẢ & HƯỚNG PHÁT TRIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 151
CHƯƠNG 9
KẾT LUẬN VÀ HƯỚNG PHÁT TRIỂN
9.1. KẾT LUẬN
Luận văn được thực hiện trong khoảng thời gian cho phép (1học kì = 16
tuần) và hoàn thành các mục tiêu đặt ra ban đầu bao gồm:
Nhiệm vụ 1: Sử dụng board Mini2440 & hệ điều hành Embedded
Linux.
Nhiệm vụ 2: Thiết kế mô hình quản lí bãi giữ xe sử dụng board
mini2440.
1. Mini2440 & Embedded Linux
Hiện nay, với sự ra đời và phát triển của các ứng dụng nhúng thì board
FriendlyARM Mini2440 là một công cụ mạnh để thực hiện ý đồ này. Trong
đề tài này, chúng em đã nắm bắt được các khối chính của cấu trúc board từ bộ
xử lí trung tâm (processor), bộ nhớ (memory) đến các module giao tiếp như
USB, Ethernet, wifi, audio, SD card, AD Converter, PWM… đặc biệt camera,
GPIO cùng với các thanh ghi liên quan. Trong đó, việc sử dụng được module
cơ bản GPIO là bước quan trọng để phát triển điều khiển các đối tượng mong
muốn.
Bên cạnh phần cứng, hệ điều hành chính là một phần rất quan trọng. Với
mục tiêu cài đặt và sử dụng được một hệ điều hành nhúng trên board, chúng
em phải lựa chọn gắt gao thích hợp. Tuy ban đầu đã định hướng nhúng Linux
nhưng hệ điều hành Linux là một mã nguồn mở với rất nhiều phiên bản, tính
năng và hỗ trợ khác nhau. Ngay cả đối với hệ điều hành Qtopia 2.2.0 đi kèm
với board đã được nhà sản xuất xây dựng với một số ứng dụng cơ bản của giải
trí như nghe nhạc, xem phim... nhưng không phù hợp cho mục đích điều khiển
hệ thống. Và sau một thời gian tìm hiểu và sử dụng, Busy Box được chọn lựa
làm hệ điều hành chính với những đặc tính phù hợp, đồng thời làm nền tảng
cho chúng em phát triển các ứng dụng tiếp các phần sau.
Thêm vào đó, việc nắm được cấu trúc và cách viết một module drivers đã
tạo bước tiến trong xây dựng ứng dụng trên hệ điều hành nhúng. Nó cho phép
phát triển các ứng dụng trên nền driver mặc nhiên không quá quan tâm vào
phần cứng cụ thể. Các ứng dụng được tách riêng và chịu sự quản lí bởi hệ điều
hành dưới dạng các process. Quá trình phát triển từ các ứng dụng không giao
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 9: KẾT QUẢ & HƯỚNG PHÁT TRIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 152
diện (console application) cho phép hiển thị và điều khiển thông qua terminal.
Sau đó các ứng dụng GUI (Graphical User Interface), được tạo ra bằng phần
mềm Qt, cho phép điều khiển và hiển thị thân thiện hơn, đẹp hơn với người
dùng. Cuối cùng, các công cụ cần thiết như Toolchain, trình biên dịch,
software,… cũng được lựa chọn để thực hiện cài đặt, build và chạy từ hệ điều
hành, driver và các ứng dụng.
2. Hệ Thống Quản Lí Bãi Giữ Xe:
Chương trình được xây dựng như một ứng dụng nhúng, chạy trên nền
các module drivers và quản lí bởi hệ điều hành nhúng.
Khi hệ thống hoạt động, nó cho phép hiển thị hình ảnh xe vào trên màn
hình điều khiển của người quản lí và chụp hình xe để lưu cùng với số thẻ xe
đã nhập. Sau khi thực hiện xong thủ tục chụp ảnh, lưu ảnh và cấp cho chủ xe
một thẻ xe thì hệ thống tự động tiến hành mở cổng chắn cho xe vào. Thông
thường, tốc độ động cơ mở cổng là cố định nhưng chương trình cũng cho
phép thay đổi bằng cách cài đặt lại khi cần thiết. Tất cả các tác vụ điều khiển
đều được hiển thị trên màn hình giao diện người dùng.
Tổng kết lại, chương trình đã tương đối đầy đủ khi thể hiện được các tính
năng ưu việt của board như hệ điều hành, driver, touch screen...Việc kết hợp
giữa giao diện người dùng và phần điều khiển trên cùng 1 board làm cho hệ
thống trở nên đơn giản, thuận tiên hơn và cho thấy hoàn toàn có thể thay thế
PC trong công việc này. Đây như là một minh chứng cho việc sử dụng thành
công Mini2440 và hệ điều hành Embedded linux.
Tuy nhiên vì tính chất mới của đề tài và thời gian có hạn chương trình
vẫn chưa thực hiện việc nối mạng giữa các board để tối ưu hóa và nâng cao
tính bảo mật, an toàn cho hệ thống.
9.2. HƯỚNG PHÁT TRIỂN
Với sự thành công luận văn này, chúng ta đã thực hiện được các việc
điều khiển và kiểm soát phần cứng, viết các driver theo mong muốn. Nhưng
còn có vài thiếu sót trong quá trình thực hiện như chưa tối ưu được driver để
khai thác phần cứng triệt để hơn.
Ở đây chúng ta mới xây dựng một ứng dụng bãi quản lí giữ xe đơn giản.
Với các tiền đề đó, hệ thống còn có thể phát triển xa hơn theo nhiều hướng
www.robotgiaoduc.com www.clbrobot.com
CHƯƠNG 9: KẾT QUẢ & HƯỚNG PHÁT TRIỂN GVHD: HUỲNH VĂN KIỂM
SVTH: NGUYỄN ĐỨC THỌ & VŨ QUANG TRƯỜNG 153
khác nhau như dùng máy in vé, RFID, xử lí ảnh ... để hoàn thiện hệ thống bãi
giữ xe thông minh với khả năng tự động nhận dạng và bảo mật tốt hơn.
Thế giới ngày càng thu nhỏ với những ứng dụng hiện đại và các hệ thống
nhúng cũng là một cơ sở mới trong các hệ thống công nghiệp với kích thước
nhỏ hơn, khả năng tính toán chuyên nghiệp, điều khiển riêng cho một hệ
thống công nghiệp.
www.robotgiaoduc.com www.clbrobot.com