Khóa luận Các kỹ thuật gỡ lỗi trong việc phát triển hệ thống nhúng với ngôn ngữ C

ĐẠI HỌC QUỐC GIA HÀ NỘI  
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ  
Ngô Thị Nga  
CÁC KỸ THUẬT GỠ LỖI TRONG VIỆC PHÁT  
TRIỂN HỆ THỐNG NHÚNG VỚI NGÔN NGỮ C  
KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY  
Ngành: Công nghệ thông tin  
HÀ NỘI - 2010  
ĐẠI HỌC QUỐC GIA HÀ NỘI  
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ  
Ngô Thị Nga  
CÁC KỸ THUẬT GỠ LỖI TRONG VIỆC PHÁT  
TRIỂN HỆ THỐNG NHÚNG VỚI NGÔN NGỮ C  
KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY  
Ngành: Công nghệ thông tin  
Cán bộ hướng dẫn: TS. Đặng Văn Hưng  
Cán bộ đồng hướng dẫn: ThS. Vũ Quang Dũng  
HÀ NỘI - 2010  
LỜI CẢM ƠN  
Em xin chân thành cảm ơn Bộ môn Công nghệ phần mềm, Khoa Công nghệ  
thông tin, Trường Đại học Công nghệ, Đại học Quốc gia Hà Nội đã tạo điều kiện  
thuận lợi cho em trong quá trình học tập, rèn luyện và thực hiện đề tài khóa luận tốt  
nghiệp. Em xin gửi lời cảm ơn chân thành đến tất cả thầy cô trong trường đã giúp  
đỡ, dìu dắt em từ những ngày đầu tiên nhập trường.  
Em xin gửi lời cảm ơn sâu sắc nhất đến TS. Đặng Văn Hưng, TS. Trần Thị  
Minh Châu, ThS. Vũ Quang Dũng, những thầy cô đã cho em định hướng, tận tình  
chỉ bảo, hướng dẫn và giúp đỡ em trong quá trình tìm hiểu về hệ thống nhúng, cùng  
các kiến thức cần thiết khác để em hoàn thành khóa luận.  
Em xin gửi những lời cảm ơn, những tình cảm thương yêu tới gia đình, và  
người thân. Những người luôn bên em, động viên em cả về tinh thần và vật chất  
trong thời gian qua.  
Trong quá trình thực hiện khóa luận, em cũng đã nhận được nhiều sự chia  
sẻ, giúp đỡ, động viên của các thành viên lớp Công nghệ phần mềm K51, và của  
những thành viên trong diễn đàn sinh viên Đại học Công nghệ. Tôi xin gửi tới các  
bạn sự biết ơn sâu sắc.  
Đề tài “Các kỹ thuật gỡ lỗi trong việc phát triển hệ thống nhúng với ngôn  
ngữ C ” là một đề tài khá khó, lại được hoàn thành trong quỹ thời gian hạn hẹp nên  
khó tránh khỏi những khiếm khuyết. Em mong nhận được những góp ý chân thành  
từ thầy cô giáo và các bạn để đề tài có thể mở rộng và nghiên cứu kỹ hơn, đưa vào  
trong thực tiễn ngành công nghệ thông tin hiện nay.  
Hà Nội, ngày 15 tháng 05 năm 2010  
Sinh viên  
Ngô Thị Nga  
i
TÓM TẮT KHÓA LUẬN  
Khóa luận tập trung trình bày tổng quan về hệ thống nhúng, định nghĩa, đặc  
trưng của hệ thống, những khó khăn trong việc tìm hiểu một hệ thống nhúng. Sau  
đó, khóa luận đưa ra những kỹ thuật gỡ lỗi thường được áp dụng trên hệ thống  
nhúng, trong đó bao gồm cả các kỹ thuật gỡ lỗi dựa trên các công cụ phần mềm và  
công cụ phần cứng. Từ đó, khóa luận lựa chọn trình bày công cụ gỡ lỗi µVision của  
công ty Keil ARM, đây là một công cụ mạnh về gỡ lỗi theo kỹ thuật mô phỏng –  
một kỹ thuật được các kỹ sư lập trình áp dụng rất nhiều trong thực tế.  
Để minh họa cho việc áp dụng kỹ thuật gỡ lỗi và sử dụng công cụ gỡ lỗi, khóa  
luận xây dựng các chương trình phần mềm ứng dụng nhỏ là Đèn led nhấp nháy và  
Hello World – truyền các chuỗi ký tự ra cổng nối tiếp. Khóa luận áp dụng kỹ thuật  
và công cụ gỡ lỗi trên hai chương trình đó.  
ii  
MỤC LỤC  
CHƯƠNG 1: MỞ ĐẦU.............................................................................................1  
1.1. Đặt vấn đề......................................................................................................1  
1.2. Đề tài, đối tượng nghiên cứu và phương pháp nghiên cứu.............................1  
1.3. Mục tiêu của khóa luận..................................................................................2  
1.4. Cấu trúc của khóa luận...................................................................................2  
CHƯƠNG 2: TỔNG QUAN.....................................................................................3  
2.1. Hệ thống nhúng..............................................................................................3  
2.1.1. Hệ thống nhúng là gì? ............................................................................3  
2.1.2. Các thiết bị phần cứng thông thường......................................................3  
2.1.3. Đặc trưng của hệ thống nhúng................................................................6  
2.1.4. Ví dụ về hệ thống nhúng ........................................................................8  
2.2. Sự lựa chọn ngôn ngữ lập trình cho hệ thống nhúng......................................8  
CHƯƠNG 3: CÁC KỸ THUẬT GỠ LỖI ..............................................................10  
3.1. Gỡ lỗi...........................................................................................................10  
3.1.1. Gỡ lỗi trong quá trình phát triển hệ thống nhúng..................................10  
3.1.2. Định nghĩa gỡ lỗi ..................................................................................11  
3.1.3. Tầm quan trọng của việc gỡ lỗi.............................................................12  
3.1.4. Mục đích của quá trình gỡ lỗi ..............................................................12  
3.2. Kiểm thử trên máy chủ ................................................................................13  
3.2.1. Kỹ thuật cơ bản ....................................................................................13  
3.2.2. Gọi các thường trình ngắt .....................................................................15  
3.2.3. Gọi thường trình ngắt định thời ............................................................15  
3.2.4. Các tệp kịch bản và tệp kết xuất ...........................................................15  
3.2.5. Những phản đối, hạn chế và nhược điểm..............................................16  
3.3. Bộ mô phỏng ...............................................................................................17  
3.4. Sử dụng macro assert ..................................................................................20  
3.5. Sử dụng các công cụ trong phòng thí nghiệm ..............................................21  
3.5.1. Máy hiện sóng ......................................................................................22  
3.5.2. Bộ phân tích logic (Logic Analyzer) ....................................................24  
3.5.2.1. Bộ phân tích logic theo chế độ thời gian .......................................26  
3.5.2.2. Bộ phân tích logic theo chế độ trạng thái ......................................26  
3.5.3. Bộ mô phỏng trong mạch .....................................................................28  
CHƯƠNG 4: CÔNG CỤ GỠ LỖI...........................................................................31  
4.1. Lý do chọn họ vi xử lý ARM........................................................................31  
4.2. Giới thiệu công cụ µVision...........................................................................32  
4.3. Các chức năng chính của công cụ µVision ..................................................33  
4.3.1. Các chức năng của µVision IDE...........................................................33  
4.3.2. Các chức năng của µVision Debugger..................................................35  
4.4. Ưu điểm của µVision ...................................................................................37  
4.4.1. Ưu điểm của µVision IDE.....................................................................37  
4.4.2. Ưu điểm của µVision Simulator...........................................................38  
iii  
4.5. Một số hạn chế của µVision phiên bản dùng thử .........................................38  
4.6. Cài đặt..........................................................................................................39  
CHƯƠNG 5: ỨNG DỤNG CÔNG CỤ µVISION VÀO VIỆC GỠ LỖI...............41  
5.1. Vi điều khiển LPC2148................................................................................41  
5.2. Chương trình “Đèn led nhấp nháy”..............................................................41  
5.3. Chương trình Hello world............................................................................43  
5.4. Nhận xét.......................................................................................................45  
CHƯƠNG 6: KẾT LUẬN.......................................................................................47  
TÀI LIỆU THAM KHẢO.........................................................................................49  
PHỤ LỤC: CÁC THÔNG SỐ KỸ THUẬT CỦA VI ĐIỀU KHIỂN LPC2148......50  
iv  
DANH MỤC HÌNH ẢNH  
Hinh 2.1. Hệ thống nhúng thông thường  
Hình 3.1. Quá trình phát triển phần mềm nhúng  
Hình 3.2. Hệ thống kiểm thử  
Hình 3.3. Đồ thị máy hiện sóng  
Hình 3.4. Máy hiện sóng  
Hình 3.5. Bộ phân tích logic  
Hình 3.6. Chế độ thời gian của bộ phân tích logic  
Hình 3.7. Chế độ trạng thái của bộ phân tích logic  
Hình 4.1. Mẫu đăng ký sử dụng phần mềm Keil  
Hình 4.2. Giao diện IDE  
Hình 4.3. Giao diện của Debugger  
Hình 5.1. Kết quả chạy chương trình Led  
Hình 5.2. Kết quả chạy chương trình Hello world  
DANH MỤC BẢNG BIỂU  
Bảng 2.1. Họ vi xử lý ARM  
Bảng 3.1. Hàm NDEBUG  
Bảng 4.1. Các chức năng của MicroVision IDE  
Bảng 4.2. Các chức năng của MicroVision Debugger  
Bảng 5.1. Chương trình Led.c  
Bảng 5.2. Chương trình Hello.c  
v
DANH SÁCH CÁC THUẬT NGỮ VÀ KHÁI NIỆM  
Thuật ngữ  
Khái niệm  
AGSI  
Advanced Simulation Interface – Giao diện mô phỏng nâng cao.  
Advanced RISC Machine – Máy có bộ lệnh RISC mở rộng.  
Đây là cấu trúc RISC 8 – bit của công ty Atmel.  
ARM  
AVR  
Big - Endian  
Bộ nhớ lưu các ký tự quan trọng nhất ở các bit địa chỉ thấp nhất.  
Cross–compiler Biên dịch chéo.  
Debugger  
DWARF  
Bộ gỡ lỗi.  
Đây là một định dạng tập tin gỡ lỗi được dùng trong nhiều trình  
biên dịch.  
ELF  
Executable and Linkable Format hay Extensible Linking Format –  
Tệp tin lưu dưới dạng thực thi và liên kết.  
Ground  
ICE  
Điện áp bằng 0, tình trạng nối đất.  
In – circuit Emulator – Bộ mô phỏng trong mạch.  
IDE  
Intergrated Development Environment – Môi trường phát triển  
tích hợp.  
ISS  
Instruction Set Simulator – Bộ mô phỏng tập lệnh.  
Light Emitting Diode – Đèn hai cực quang phát xạ.  
LED  
Linker/ Locator Bộ liên kết/ Định vị.  
Little - endian Bộ nhớ lưu các ký tự quan trọng nhất ở các bit địa chỉ cao nhất.  
MIPS  
Million Intruction Per Second – Số triệu dòng lệnh thực hiện  
trong một giây,  
Overlay  
memory  
Bộ nhớ nạp chồng.  
RAM  
RE  
Random Access Memory – Bộ nhớ truy cập ngẫu nhiên.  
Read Enable signal – Tín hiệu cho phép đọc từ ROM.  
RISC  
Reduced Instruction Set Computing – Máy tính dùng tập lệnh rút  
gọn.  
ROM  
Read Only Memory – Bộ nhớ chỉ đọc.  
vi  
Thuật ngữ  
RTOS  
Khái niệm  
Real Time Operating System – Hệ điều hành thời gian thực.  
Định dạng kết xuất ký hiệu.  
Symbolic  
Output Format  
VCC  
Voltage Connected to Collector – Điệp áp kết nối bộ gom – VCC  
thường đại diện cho điện áp ở mức cao (High).  
vii  
CHƯƠNG 1: MỞ ĐẦU  
1.1. Đặt vấn đề  
Ngày nay, chúng ta có thể nhìn thấy các thiết bị nhúng ở khắp mọi nơi xung  
quanh ta từ những vật dụng đơn giản như chiếc đồng hồ điện tử, lò vi sóng, tủ lạnh,  
máy điện thoại di dộng, máy in, máy ảnh kỹ thuật số... đến những hệ thống lớn như  
các hệ thống điều khiển các dây chuyền sản xuất trong công nghiệp, điều khiển các  
hoạt động trong lò phản ứng hạt nhân... Chúng ta khó mà có thể tìm được một thiết bị  
điện tử mà bên trong nó không có một vài vi xử lý, vi điều khiển. Đặc biệt là các họ vi  
xử lý ARM đã được ứng dụng rất nhiều trong các thiết bị nhúng.  
Các hệ thống nhúng ngày càng phát triển, các phần mềm để điều khiển cho các  
thiết bị cũng ngày càng đa dạng. Vì vậy, các nhà sản xuất cần đảm bảo cho các thiết bị  
của mình đến được tay người dùng với độ ổn định, hiệu quả và ít lỗi nhất có thể. Quá  
trình gỡ lỗi sẽ đảm bảo cho sản phẩm có chất lượng tốt nhất.  
Hiện nay, có rất nhiều công cụ gỡ lỗi cho hệ thống nhúng, các kỹ sư lập trình cần  
phải chọn cho mình được một công cụ gỡ lỗi phù hợp với thiết bị của mình để đạt hiệu  
quả gỡ lỗi cao nhất.  
1.2. Đề tài, đối tượng nghiên cứu và phương pháp nghiên cứu  
Đề tài của khóa luận là “Các kỹ thuật gỡ lỗi trong việc phát triển hệ thống nhúng  
với ngôn ngữ C”. Khóa luận mong muốn cung cấp cho các kỹ sư lập trình phần mềm  
nhúng một cái nhìn tổng quát về hệ thống, các kỹ thuật gỡ lỗi, công cụ gỡ lỗi.  
Đối tượng nghiên cứu chính trong đề tài là vi điều khiển LPC2148 của công ty  
Philips. Đây là một vi điều khiển được thiết kế dựa trên cấu trúc của vi xử lý ARM đã  
được sử dụng rộng rãi trong nhiều thiết bị, sản phẩm.  
Khóa luận tập trung tìm hiểu về lý thuyết hệ thống nhúng, các kỹ thuật gỡ lỗi,  
sau đó áp dụng các kiến thức đó vào thực hiện việc gỡ lỗi cho phần mềm nhúng. Khóa  
luận tập trung nghiên cứu kỹ thuật gỡ lỗi bằng phương pháp mô phỏng. Phương pháp  
này có ưu điểm là phổ biến, có nhiều công cụ, dễ sử dụng, được sự hỗ trợ lớn về mặt  
kiến thức và chuyên môn từ các nhà sản xuất và cộng đồng người sử dụng, có thể áp  
dụng phương pháp mô phỏng này khi phần cứng còn đang được phát triển, hay phần  
cứng không có sẵn.  
1
1.3. Mục tiêu của khóa luận  
Để đạt được các vấn đề đã nêu ra, khoá luận sẽ lần lượt trình bày những kiến  
thức cần thiết để giải quyết yêu cầu trên.  
Khóa luận sẽ tập trung vào một số các vấn đề sau:  
Tìm hiểu khái quát về hệ thống nhúng, các đặc điểm của hệ thống và việc lựa  
chọn các ngôn ngữ lập trình cho hệ thống.  
Tìm hiểu các kỹ thuật gỡ lỗi cơ bản cho hệ thống nhúng.  
Tìm hiểu công cụ gỡ lỗi µVision, các chức năng, ưu nhược điểm của chương  
trình.  
Xây dựng chương trình, ứng dụng công cụ gỡ lỗi vào việc gỡ lỗi cho chương  
trình để thấy được những ưu nhược điểm của công cụ.  
1.4. Cấu trúc của khóa luận  
Khóa luận được trình bày theo cấu trúc như sau:  
Chương mở đầu: Giới thiệu về đề tài, mục tiêu của khóa luận và cấu trúc khóa  
luận.  
Chương hai: Giới thiệu tổng quan về hệ thống nhúng, định nghĩa hệ thống  
nhúng, các đặc trưng của hệ thống và việc chọn lựa một ngôn ngữ lập trình phù hợp  
với hệ thống nhúng.  
Chương ba: Tiếp cận với các kỹ thuật gỡ lỗi thường dùng trong hệ thống nhúng:  
kiểm thử trên máy chủ, kiểm thử sử dụng bộ mô phỏng, macro assert và gỡ lỗi dùng  
các thiết bị phần cứng.  
Chương bốn: Tiếp cận tìm hiểu công cụ gỡ lỗi µVision của công ty Keil ARM,  
là một công cụ hỗ trợ việc gỡ lỗi rất hiệu quả cho các vi xử lý thuộc họ ARM, giới  
thiệu các chức năng, ưu nhược điểm của công cụ.  
Chương năm: Xây dựng ví dụ minh họa và áp dụng công cụ để gỡ lỗi cho các  
chương trình “Đèn led nhấp nháy” và “Hello world” bằng kỹ thuật mô phỏng để thực  
hiện mục tiêu của khóa luận.  
Chương sáu: Đánh giá kết quả khóa luận đã đạt được và nêu ra hướng phát triển  
trong tương lai của đề tài.  
2
CHƯƠNG 2: TỔNG QUAN  
Chương 2 giới thiệu tổng quan về: hệ thống nhúng: định nghĩa hệ thống nhúng,  
đặc trưng của hệ thống, ví dụ về hệ thống. Và sự lựa chọn ngôn ngữ lập trình cho hệ  
thống nhúng.  
2.1. Hệ thống nhúng  
2.1.1. Hệ thống nhúng là gì?  
Thuật ngữ hệ thống nhúng thường được dùng để chỉ bất kỳ hệ thống máy tính  
nào ẩn chứa bên trong các thiết bị, hệ thống [4]. Bên cạnh đó còn có nhiều định nghĩa  
khác cho khái niệm hệ thống nhúng. Dưới đây là một khái niệm được đưa ra trong từ  
điển Các hệ thống nhúng:  
“Hệ thống nhúng là một sự kết hợp giữa phần cứng và phần mềm của máy tính  
và có thể có thêm các thiết bị cơ khí hay các bộ phận khác, nó được thiết kế để thực  
hiện một chức năng cụ thể”. [2]  
Trong vài trường hợp, hệ thống nhúng có thể chỉ là một phần nhỏ trong một hệ  
thống lớn như trong các thiết bị điều khiển xe hơi. Bởi những thiết kế của hệ thống  
nhúng là để phục vụ cho một vài chức năng cụ thể đã được định trước như là bộ phận  
hẹn giờ trong lò vi sóng, hệ thống điều khiển đèn giao thông,... nên nó khác với các  
máy tính cá nhân thông thường – hệ thống có thể thực hiện nhiều nhiệm vụ khác nhau  
do người dùng cài đặt. [1]  
2.1.2. Các thiết bị phần cứng thông thường  
Bất kỳ một hệ thống thông thường nào cũng đều có các thành phần cấu thành nên  
nó. Một hệ thống nhúng thông thường sẽ gồm có một số thành phần như hình 2.1 sau:  
Hình 2.1. Hệ thống nhúng thông thường  
3
Mỗi hệ thống đều cần có vi xử lý để điều khiển các thông tin và dữ liệu trong hệ  
thống. Trong các thiết bị gia dụng như lò vi sóng, nồi cơm điện, hay chiếc điện thoại  
cũng có ít nhất một bộ vi xử lý. Các vi xử lý được chia làm hai loại: bộ vi xử lý chính  
dùng để điều khiển các thiết bị trung tâm, và các vi xử lý phụ được thêm vào để mở  
rộng các tập lệnh của vi xử lý chính, quản lý bộ nhớ, các đường truyền, và các thiết bị  
nhập xuất. Trong các thiết bị nhúng, vi xử lý chính thường là các vi điều khiển, để phù  
hợp với các phần mềm, các chương trình rất nhỏ ẩn chứa bên trong những thiết bị. Các  
vi xử lý giống như bộ não của con người, nếu không có nó thì các thiết bị không thể  
hoạt động được. Chính vì thế, vi xử lý đóng vai trò trung tâm, quan trọng nhất trong  
thiết bị.  
Thiết bị nhúng được ứng dụng rộng rãi trong nhiều lĩnh vưc, nó cũng tiêu thụ  
nhiều nhất số vi xử lý được sản xuất ra hàng năm. Các họ vi xử lý được phát triển và  
ứng dụng rộng rãi là 8051 của Intel, họ AVR của Atmel, họ ARM của công ty ARM,...  
trong các họ này thì các thiết bị được xây dựng trên nền tảng thiết kế của ARM là phổ  
biến nhất. Bảng 2.1 sẽ đưa ra một số vi xử lý của họ ARM và ứng dụng của chúng  
trong các thiết bị điện tử.  
4
Bảng 2.1. Một số họ vi xử lý ARM và ứng dụng của nó [10]  
MIPS điển hình/  
Họ  
Lõi  
Đặc tính  
Ứng dụng  
MHz  
ARM7T ARM7TDMI  
DMI (-S)  
15 MIPS/ 16.8  
MHz  
Game Boy Advance,  
Nintendo DS, iPod  
3-tầng pipeline  
Nintendo DS, Nokia  
N-Gage, Conexant  
802.11 chip  
ARM946E-S  
ST Micro STR91xF,  
gồm cạc Ethernet  
ARM966E-S  
ARM9E  
Điện thoại di động:  
Sony Ericsson (K, W  
series),Siemens và  
Benq (đời x65 và đời  
mới hơn)  
ARM926EJ-  
S
220 MIPS/ 200  
MHz  
Jazelle DBX  
NEON, Jazelle  
RCT, Thumb-2  
Texas Instruments  
OMAP3  
Cortex-A8  
Cortex Cortex-R4  
Cortex-M3  
Broadcom là một hãng  
sử dụng  
600 DMIPS  
120 DMIPS/  
100MHz  
Họ vi điều khiển  
Luminary Micro  
800 MIPS/ 624  
MHz  
HTC Universal,  
Zaurus SL-C1000  
PXA27x  
XScale PXA900  
Blackberry 8700  
IXP460/IXP  
465  
Một hệ thống nhúng cần sử dụng bộ nhớ cho hai mục đích: để lưu trữ chương  
trình và lưu trữ dữ liệu. Không giống như một hệ thống máy tính cá nhân – các chương  
trình và dữ liệu đuợc lưu trong những phần bộ nhớ giống nhau, hệ thống nhúng dùng  
các bộ nhớ khác nhau cho các mục đích khác nhau. Bởi vì thông thường một hệ thống  
nhúng không có ổ đĩa cứng để nạp chương trình, chương trình phải được lưu trong bộ  
nhớ, thậm chí ngay cả khi tắt nguồn. Bộ nhớ của hệ thống nhúng thường là: bộ nhớ chỉ  
đọc (ROM), bộ nhớ truy cập ngẫu nhiên (RAM) và có thể là cả bộ nhớ mở rộng với  
các hệ thống lớn. [4]  
5
Các hệ thống nhúng cũng có thể chứa các thiết bị đầu vào và thiết bị đầu ra. Ví  
dụ như trong các máy điện thoại di động, thiết bị đầu vào là các nút bấm trên bề mặt  
điện thoại, và thiết bị đầu ra là màn hình điện thoại và loa. Các thiết bị đầu vào của hệ  
thống nhúng thường ở dưới dạng các thiết bị cảm biến, đầu dò, tín hiệu, hay các nút  
bấm. Các thiết bị đầu ra của hệ thống thường là màn hình và các tín hiệu.  
Hệ thống nhúng không giống các máy vi tính thông thường, có một số thành  
phần của máy vi tính có thể sẽ không có trong hệ thống nhúng. Các thành phần đó là:  
Bàn phím: Một số hệ thống có thể có vài nút bấm để người dùng nhập dữ liệu  
đầu vào, như là máy in, nhưng cũng có những hệ thống không có bàn phím như  
là máy điện báo.  
Chuột: Đối với những máy tính thông thường thì chuột máy tính sẽ làm cho  
việc sử dụng máy tính được dễ dàng, thuận lợi hơn. Nhưng trong hầu hết các hệ  
thống nhúng thì chuột đều không xuất hiện. Các tác vụ mà chúng ta thực hiện  
với hệ thống thường được kích hoạt qua các nút bấm, các cảm biến điện tử.  
Màn hình: Nhiều hệ thống sẽ có một màn hình tinh thể lỏng hiển thị vài chức  
năng đặc trưng, ví dụ như máy giặt thì có một màn hình hiển thị chế độ đang  
giặt. Hay một số hệ thống chỉ có điốt phát quang để báo hiệu thiết bị đang ở chế  
độ nào, ví dụ như máy in có đèn nháy để biết rằng máy đang ở chế độ in hay  
chế độ chờ.  
Ổ đĩa cứng: Do thiết kế nhỏ gọn, nên các hệ thống nhúng thường không có ổ  
đĩa cứng gắn rời bên ngoài mà các chương trình và dữ liệu của hệ thống nhúng  
thì thường được lưu trữ ở bộ nhớ trong của máy tính (RAM và ROM).  
Đĩa quang, loa, tai nghe: hầu hết các hệ thống nhúng không cần tới những thiết  
bị này.  
Ngoài ra thì hệ thống nhúng còn có thể có thêm các bộ phận như là: các cổng nối  
tiếp, các cổng kết nối mạng internet, các phần cứng tương tác với bộ cảm biến,...  
2.1.3. Đặc trưng của hệ thống nhúng  
Mỗi hệ thống nhúng đều có những đặc trưng khác nhau, để thỏa mãn được những  
yêu cầu khác nhau. Vì các hệ thống nhúng thường nhỏ và chỉ có một số thiết bị cần  
thiết - nó không giống như các máy vi tính thông thường, nên khi làm việc với các hệ  
thống nhúng ta gặp rất nhiều khó khăn:  
6
Công suất: Hệ thống cần điều khiển được một lượng lớn dữ liệu trong một  
khoảng thời gian rất ngắn.  
Tính đáp ứng: Hệ thống cần lặp lại các sự kiện một cách nhanh chóng. Ví dụ:  
việc nhấp nháy của các điôt phát quang là trong một chu kỳ ngắn, lặp lại liên  
tục.  
Khả năng kiểm thử: Kiểm thử cho một hệ thống nhúng có thể là một việc rất  
khó khăn.  
Khả năng gỡ lỗi: Làm thế nào để ta tìm ra các lỗi trong chương trình của hệ  
thống nhúng với thiết kế đặc trưng là không bàn phím, không màn hình? Làm  
sao để biết được một phần mềm nào đó đang làm gì trong thiết bị nhúng quả là  
một việc không dễ dàng gì. Ở đây chúng ta cần đến các thiết bị, các chương  
trình phần mềm riêng biệt để gỡ lỗi cho nó.  
Độ tin cậy: Hệ thống nhúng phải có thể tự điều khiển được trong bất kỳ tình  
huống nào mà không có sự can thiệp của con người. Với các hệ thống lái xe tự  
động, hệ thống cần quyết định tất cả những việc cần làm, như chạy ở tốc độ bao  
nhiêu, đi hướng nào. Hệ thống gần như phải chạy tốt trong mọi trường hợp có  
thể tính toán trước của nhà sản xuất với độ ổn định cao.  
Không gian bộ nhớ: Bộ nhớ của hệ thống nhúng thường bị giới hạn, chúng ta  
cần phải làm cho các phần mềm và dữ liệu chứa vừa vặn trong không gian nhớ  
đó. Các thanh ghi địa chỉ thường chỉ là loại 8 bit, hay 16 bit, nên việc cung cấp  
không gian nhớ là rất hạn chế. Vì vậy một nhiệm vụ khó khăn đặt ra cho các kỹ  
sư lập trình là phải tối ưu mã làm sao cho với số dòng lệnh ít nhất, chương trình  
nhỏ nhất mà vẫn có thể thực hiện đuợc các tác vụ yêu cầu.  
Cài đặt chương trình: Thông thường ta sẽ cần một công cụ đặc biệt để nạp các  
chương trình vào trong hệ thống.  
Điện năng tiêu thụ: Các hệ thống nhúng thường ở trong các thiết bị nhỏ, nên  
điện năng tiêu thụ cũng ít. Thông thường mức tiêu thụ điện năng trên các thiết  
bị này đuợc tính bằng mW/ MIPS (miliwatts/ MIPS, MIPS – số triệu dòng lệnh  
thực hiện được trong một giây), giá trị này càng nhỏ thì điện năng tiêu thụ càng  
ít. Mức tiêu thụ điện năng nhỏ cũng làm cho thiết bị sử dụng các pin nhỏ hơn,  
nhẹ hơn, thiết kế của thiết bị cũng nhỏ gọn hơn.  
7
Tốc độ tính toán: Tốc độ tính toán của một thiết bị thường được đo bằng  
MIPS. Nếu các thiết bị có chỉ số MIPS càng cao thì làm việc càng hiệu quả,  
Ngày nay các thiết bị có độ rộng các thanh ghi là từ 8 – 64 bit, với các thiết bị  
nhúng thì thường dùng các vi xử lý có độ rộng thanh ghi là 8 - 16 bit, các thanh  
ghi 32 - 64 bit cho phép nạp đuợc nhiều chương trình, dữ liệu vào thiết bị hơn.  
[1]  
Giá thành phát triển: Với các hệ thống nhúng trong các thiết bị hàng ngày, các  
thiết bị nhỏ, thì giá thành phát triển của một sản phẩm có thể cũng sẽ nhỏ,  
nhưng khi áp dụng để sản xuất hàng loạt các sản phẩm đó thì công ty vẫn có lãi.  
Với các thiết bị chuyên biệt, giá thành sản phẩm đến hàng triệu đôla, thì giá  
thành phát triển của nó cũng tương đối lớn.  
Giá thành sản phẩm: Với các thiết bị thông thường, giá thành sản phẩm của nó  
có thể chỉ nhỏ hơn 10 đôla, điều đó ảnh hưởng rất lớn đến các thiết kế của sản  
phẩm.  
2.1.4. Ví dụ về hệ thống nhúng  
Với sự phát triển mạnh mẽ của các hệ thống nhúng, ta có thể bắt gặp chúng ở  
khắp mọi nơi. Ví dụ điển hình của một hế thống nhúng mà ta có thể bắt gặp hàng ngày  
đó là chiếc điện thoại di động.  
Thiết kế của chiếc điện thoại di động ngày nay nhỏ gọn, thường có các nút bấm  
hay có khả năng điều khiển bằng màn hình chạm (touch-screen) dùng để nhập liệu,  
màn hình để hiển thị các thông tin, bộ nhớ trong từ vài KB đến vài trăm MB, có thể hỗ  
trợ bộ nhớ mở rộng, và tiêu thụ ít điện năng, các máy điện thoại thường dùng pin sạc.  
Hầu hết các máy điện thoại di động đều thực hiện được các chức năng thông  
thường như là nghe, gọi, nhắn tin, tra danh bạ, báo thức, ghi chú, hiển thị ngày tháng,  
chơi các chương trình điện tử đơn giản. Với những máy điện thoại di động cao cấp, ta  
còn có thể nghe nhạc, truy cập mạng internet, quay phim, chụp ảnh, đọc sách, và thậm  
chí có các các hệ điều hành hỗ trợ cho người sử dụng thực hiện các tác vụ yêu cầu.  
Giá thành một chiếc điện thoại cũng không quá cao, mà độ tin cậy và độ ổn định  
của điện thoại di động là khá cao.  
2.2. Sự lựa chọn ngôn ngữ lập trình cho hệ thống nhúng  
Đối với một dự án phần mềm nhúng việc chọn ngôn ngữ lập trình cho nó là rất  
8
quan trọng. Ngôn ngữ lập trình này phải đáp ứng được cho việc thiết kế các hệ thống  
với chỉ vài byte, KB đến vài trăm MB bộ nhớ, và hỗ trợ tốt cho nhóm phát triển với số  
lượng nhà lập trình từ một vài người đến hàng trăm người. Ngôn ngữ này cũng phải  
được dịch ra các mã máy để nạp vào thiết bị một cách dễ dàng.  
Hiện nay, ngôn ngữ được sử dụng phổ biến nhất là C. Ngôn ngữ C có rất nhiều  
ưu điểm hỗ trợ cho việc phát triển các hệ thống nhúng. Nó là một ngôn ngữ dễ học, dễ  
dùng, khả chuyển và có thể chạy trên hầu hết các hệ điều hành. Các đoạn mã viết bằng  
ngôn ngữ C cũng nhỏ, gọn, dễ biên dịch và gỡ lỗi hơn.  
Một trong những tính năng nổi bật để làm cho C trở thành một ngôn ngữ thích  
hợp cho việc lập trình: C là “ngôn ngữ trung gian”. Nó vừa hỗ trợ cho người lập trình  
có thể can thiệp sâu vào phần cứng máy tính, cũng vừa là một ngôn ngữ lập trình bậc  
cao với cấu trúc và các tập lệnh dễ hiểu.  
Ngoài ngôn ngữ C, chúng ta có thể lập trình cho hệ thống nhúng bằng một số  
ngôn ngữ như Assembly, Ada, C++, Java,... Nhưng việc lập trình trên các ngôn ngữ  
này gặp một số khó khăn. Assembly có ưu điểm là can thiệp sâu vào phần cứng, mã  
lệnh viết ra có thể thực thi trực tiếp, nhược điểm của nó là khó học, khó sử dụng. C++  
là một ngôn ngữ lập trình bậc cao, hướng đối tượng nên cũng khó cho người lập trình  
tác động nhiều đến phần cứng. Ngôn ngữ Java với công nghệ JavaME cũng là một  
ngôn ngữ mới cho phép người lập trình viết các ứng dụng chạy trên nền các thiết bị  
phần cứng nhỏ như chip, thẻ thông minh, điện thoại...  
9
CHƯƠNG 3: CÁC KỸ THUẬT GỠ LỖI  
Trong chương này, khóa luận sẽ đưa ra khái niệm về gỡ lỗi và các kỹ thuật gỡ lỗi  
cho các phần mềm của hệ thống nhúng. Các kỹ sư lập trình có thể áp dụng một hoặc  
kết hợp một vài phương pháp gỡ lỗi để cho kết quả tốt nhất.  
3.1. Gỡ lỗi  
3.1.1. Gỡ lỗi trong quá trình phát triển hệ thống nhúng  
Quá trình phát triển hệ thống nhúng và phần mềm ứng dụng thông thường đều  
gồm những bước giống nhau. Hình 3.1 là biểu đồ những giai đoạn cơ bản của một quá  
trình phát triển phần mềm nhúng.  
Hình 3.1. Quá trình phát triển phần mềm nhúng  
Quá trình phát triển phần mềm nhúng thường bắt đầu bằng giai đoạn thiết kế, và  
cài đặt. Sau đó là giai đoạn sinh mã, nạp mã, gỡ lỗi và sửa lỗi, đây là một quá trình lặp  
đi lặp lại và tiêu tốn thời gian, công sức của các kỹ sư lập trình nhất. Ngoài ra còn một  
số giai đoạn khác nữa như là kiểm thử, tối ưu mã, tích hợp hay sau khi sản phẩm được  
đưa tới người tiêu dùng thì chúng ta còn cần phải tiến hành bảo trì cho sản phẩm.  
Trong giai đoạn thiết kế, các kỹ sư lập trình sử dụng các công cụ, ngôn ngữ đặc  
tả mô hình hóa các chức năng của hệ thống, để từ đó có thể cài đặt đúng các chức năng  
10  
mà hệ thống yêu cầu.  
Giai đoạn cài đặt, các kỹ sư lập trình viết các chương trình của mình bằng các  
ngôn ngữ lập trình như Assembly, C/C++, Java... Các ngôn ngữ lập trình này thường  
dễ học, dễ sử dụng, khả chuyển giúp cho các kỹ sư lập trình trong một đội có thể hiểu  
được chương trình của nhau.  
Giai đoạn tiếp theo là sinh mã. Các hệ thống nhúng của chúng ta không hiểu các  
lệnh, các chương trình được viết bằng những ngôn ngữ bậc cao, chúng chỉ hiểu được  
mã máy - dạng các chuỗi bit 0, 1. Vì vậy sau khi cài đặt, chúng ta cần biên dịch, liên  
kết, định địa chỉ bộ nhớ cho các tệp tin chương trình thành một tệp tin thực thi dạng  
mã nhị phân để hệ thống có thể hiểu được, quá trình này gọi là sinh mã. Các máy đích  
có kiến trúc khác nhau thì chương trình thực thi trong nó sẽ khác nhau, vì vậy các tệp  
tin thực thi dạng mã nhị phân này thường phải tuân theo một số định dạng nhất định  
như là hex hay elf… là những định dạng phổ biến mà nhiều hệ thống hiểu được.  
Giai đoạn nạp mã và gỡ lỗi là giai đoạn mà chúng ta nạp tệp tin thực thi đã được  
sinh ra ở trên vào trong máy đích, và tìm các lỗi có trong chương trình. Thời gian này  
là để chúng ta tìm các lỗi khi chương trình chạy trên phần cứng, các lỗi này có thể là  
những lỗi do không tương thích giữa phần cứng và phần mềm, hay những lỗi thời gian  
phản ứng chậm hơn so với quy định,... Đây là một giai đoạn quan trọng trong quá trình  
phát triển phần mềm vì nó giúp đảm bảo chất lượng cho phần mềm. Phần sau của khóa  
luận sẽ trình bày cụ thể về công việc gỡ lỗi cho hệ thống nhúng.  
Sau khi tìm ra được lỗi thì các kỹ sư lập trình bắt đầu sửa các lỗi trong chương  
trình của mình, để đảm bảo cho chương trình của mình chạy tốt.  
Quá trình sinh mã, nạp mã, gỡ lỗi và sửa lỗi được tiến hành lặp đi lặp lại, để đảm  
bảo cho sản phẩm khi đi tới người tiêu dùng là ít lỗi nhất, và ổn định nhất có thể.  
3.1.2. Định nghĩa gỡ lỗi  
Không có một hệ thống nào hoàn hảo cả, hầu như các hệ thống đều có lỗi, chỉ  
khác nhau ở tỷ lệ lỗi nhiều hay ít. Việc kiểm thử và gỡ lỗi giúp chúng ta giảm thiểu  
được các lỗi, để có thể đưa tới cho khách hàng những sản phẩm ít lỗi hơn.  
Gỡ lỗi là quá trình loại bỏ các lỗi ra khỏi chương trình, các lỗi từ bản đặc tả tới  
lỗi trong khi phát triển mã lệnh. Gỡ lỗi là hành động sửa lại các lỗi sau khi viết và bắt  
đầu kiểm thử hệ thống. Gỡ lỗi thường là phần tốn công sức nhất trong quá trình phát  
triển hệ thống. [2]  
11  
3.1.3. Tầm quan trọng của việc gỡ lỗi  
Việc gỡ lỗi cho phần mềm nói chung và phần mềm nhúng nói riêng là một khâu  
quan trọng nhằm đảm bảo chất lượng của phần mềm vì những lý do sau:  
Thứ nhất, việc gỡ lỗi thường gặp khó khăn và tốn thời gian hơn so với các phần  
mềm ứng dụng thông thường. Bởi đôi khi phần cứng và phần mềm của hệ thống nhúng  
đang được phát triển song song, nên chưa có phần cứng ổn định để kiểm thử hoặc giá  
thành của phần cứng cao nên ta cần phải áp dụng nhiều phương pháp gỡ lỗi và kiểm  
thử không trực tiếp trên phần cứng. Việc gỡ lỗi cũng khó khăn hơn với so với các hệ  
thống khác vì những đặc trưng cấu tạo của hệ thống là thường không có các thiết bị  
nhập xuất thông thường như bàn phím, màn hình để có thể theo dõi được. [4]  
Thứ hai là các lỗi của các phần mềm nhúng rất khó được người dùng chấp nhận,  
bởi khi một chương trình đã được nạp vào phần cứng, đưa vào dây chuyền sản xuất  
hàng loạt, và phân phối ra thị trường mà mới phát hiện ra một lỗi nào đó thì sự việc  
này có thể gây hậu quả nghiêm trọng cho người dùng, ảnh hưởng rất lớn tới uy tín và  
lợi nhuận của công ty sản xuất.  
3.1.4. Mục đích của quá trình gỡ lỗi  
Mục đích của quá trình gỡ lỗi thông thường là:  
Tìm lỗi sớm trong quá trình phát triển: Việc tìm ra lỗi sớm trong quá trình kiểm  
thử giúp chúng ta tiết kiệm thời gian và tiền bạc. Và nó cũng cho ta ý tưởng về  
các lỗi dễ mắc phải trong quá trình phát triển phần mềm, để có những cách sửa  
lỗi hay tránh lỗi.  
Nhưng: hệ thống đích không phải lúc nào cũng có ngay từ đầu trong quá trình  
phát triển, hệ thống này có thể đang được phát triển song hành với các phần  
mềm ứng dụng trên nó. Hoặc hệ thống đích đã có nhưng chưa được ổn định,  
còn gặp lỗi nên việc gỡ lỗi cho các phần mềm gặp nhiều khó khăn.  
Thực thi tất cả các lệnh: Việc chạy tất cả các lệnh, tức là chạy tất cả các trường  
hợp từ các trường hợp tổng quát đến các trường hợp đơn lẻ, các ngoại lệ, các  
trường hợp mà ta không mong muốn xảy ra.  
Nhưng: Thực hiện các tất cả các lệnh trên máy chủ là rất khó khăn, vì những  
tình huống xảy ra trên thực tế, đôi khi lại khó có thể mô phỏng, thực hiện được  
trên máy đích.  
12  
Phát triển dùng lại, kiểm thử nhắc lại: Khi một lỗi xảy ra rất nhanh chỉ trong  
vài giây, chúng ta hy vọng rằng nó sẽ xảy ra các lần sau nữa để có thể kiểm soát  
lỗi, và thực hiện việc gỡ lỗi. Nhưng lỗi này không xảy ra lần nữa, việc tìm ra lỗi  
và kiểm thử nó trở lên khó khăn hơn. Với các phần mềm được phát triển lặp lại,  
từ phiên bản 1, phiên bản 2, đến phiên bản 3,... có những lỗi mà chúng ta đã  
phát hiện, đã sửa được từ phiên bản 1, và không thấy xuất hiện ở phiên bản 2,  
nhưng đến phiên bản 3 ta lại thấy. Vì vậy, việc kiểm thử nhắc lại trong quá trình  
phát triển dùng lại là rất quan trọng. Nó đảm bảo chất lượng của sản phẩm khi  
đưa tới khách hàng.  
Nhưng: Tương tự với những khó khăn khi thực thi tất cả mã lệnh, thường thì  
việc thiết kế các ca kiểm thử nhắc lại trên môi trường đích là khó khăn.  
Giữ lại “biên bản kiểm tra” các kết quả kiểm thử: Chúng ta thường khó biết  
được các hệ thống của chúng ta làm việc như thế nào, chúng gửi nhận dữ liệu,  
tín hiệu ra sao. Các biên bản kiểm tra sẽ cho chúng ta thấy chúng thật sự làm  
việc như thế nào.  
Nhưng: Các hệ thống nhúng hầu như không có ổ đĩa cứng để lưu lại dấu vết  
kiểm tra, cùng các thông tin, nên việc giữ lại các dấu vết kiểm tra là khó khăn.  
3.2. Kiểm thử trên máy chủ  
Đối với các phần mềm nhúng, có nhiều lý do để phát triển phần mềm trên một hệ  
thống máy chủ và sau đó mới đưa phần mềm vào hệ thống đích để chạy. Các hệ thống  
chúng ta sản xuất có thể giống như một chiếc máy điện báo, không có màn hình,  
không có bàn phím, không có ổ đĩa, hay thậm chí không có đèn để chúng ta biết rằng  
nó đang hoạt động. Vậy giải pháp ở đây là phát triển phần mềm trên một hệ thống máy  
- nơi có các công cụ để viết lệnh, biên dịch, gỡ lỗi - máy chủ, và sau đó nạp nó vào hệ  
thống máy đích để nó có thể thực hiện được các chức năng yêu cầu.  
3.2.1. Kỹ thuật cơ bản  
Hình 3.1 mô phỏng cho chúng ta thấy phương pháp cơ bản để kiểm thử phần  
mềm nhúng trên máy chủ:  
13  
Hình 3.2. Hệ thống kiểm thử  
Phần bên trái của hình vẽ tương ứng với hệ thống đích, nó được chia thành ba  
thành phần: các mã độc lập với phần cứng, các mã phụ thuộc phần cứng và phần cứng.  
Phần bên phải của hình vẽ tương ứng với hệ thống kiểm thử, hệ thống này gồm  
hai thành phần chính là: các mã độc lập phần cứng và mã nền kiểm thử (test scaffold  
code).  
Nền kiểm thử là thay thế cho các mã phụ thuộc phần cứng và phần cứng, trong  
đó nó cung cấp bàn phím, màn hình và ổ đĩa để phục vụ cho việc viết mã lệnh, biên  
dịch, kết nối, gỡ lỗi cho các phần mềm.  
Mã nền kiểm thử dùng để:  
Cung cấp các điểm tiếp nhận giống như các đoạn mã phụ thuộc phần cứng trên  
hệ thống đích.  
Gọi các chức năng tương tự như các mã phụ thuộc phần cứng gọi đến phần mã  
không phụ thuộc phần cứng.  
Đọc các lệnh từ bàn phím hay từ các tệp tin.  
Hiển thị thông tin lên màn hình hay ghi ra tệp tin.  
Kỹ thuật này yêu cầu chúng ta có một thiết kế giao diện rõ ràng giữa phần mã  
độc lập phần cứng và phần còn lại. Thậm chí nó còn đòi hỏi chia các đoạn mã của  
phần mềm thành các đoạn mã độc lập phần cứng và các phần còn lại một cách dễ  
14  
dàng. Và điều này không phải lúc nào cũng thực hiện được.  
3.2.2. Gọi các thường trình ngắt  
Hầu hết các hệ thống nhúng thực hiện các chức năng khi các ngắt (interrupt) xảy  
ra và thường trình ngắt (interrupt routine) được thực thi. Trong môi trường kiểm thử,  
để hệ thống thực hiện các lệnh thì mã nền kiểm thử cũng cần thực thi các thường trình  
ngắt.  
Các thường trình ngắt chia thành hai loại: một loại dùng để gọi đến phần cứng và  
một loại dùng để gọi đến phần còn lại của hệ thống. Để kiểm thử thì các thường trình  
ngắt cần được thiết lập để cho phần mã phụ thuộc phần cứng gọi đến phần mã không  
phụ thuộc phần cứng. Các mã lệnh viết bằng ngôn ngữ C giúp chúng ta thực hiện việc  
này một cách dễ dàng.[4]  
3.2.3. Gọi thường trình ngắt định thời  
Trong hầu hết các phần mềm hệ thống nhúng, các thường trình ngắt định thời  
(timer interrupt routine) thường được gọi một cách tự động sau khi máy chủ đã thực  
hiện xong một số lệnh. Nếu mã nền kiểm thử bị mất quyền kiểm soát việc gọi các  
thường trình ngắt định thời thì sẽ gây ra các lỗi gián đoạn.  
Vì vậy, mã nền kiểm thử nên gọi thường trình ngắt định thời một cách trực tiếp.  
Điều này sẽ giúp cho chúng ta có thể nhìn thấy các hoạt động của hệ thống từng giây,  
từng phút, nó có thể sẽ gây ra một số phiền phức, nhưng bù lại chúng ta có thể tránh  
được các lỗi nghiêm trọng. Nó cũng cho phép chúng ta kiểm thử các đoạn mã mà sẽ  
chỉ được gọi sau các lệnh khác bằng cách gọi các thường trình ngắt định thời. [4]  
3.2.4. Các tệp kịch bản và tệp kết xuất  
Chúng ta thường phải viết các lệnh để gọi các thường trình ngắt lặp lại liên tục  
khi thực hiện việc kiểm thử. Nhưng có một cách dễ dàng hơn để làm việc này, đó là  
viết các tệp kịch bản (script file), nền kiểm thử chỉ cần đọc tệp kịch bản, thực thi các  
lệnh trong tệp và ghi kết quả thực hiện ra các tệp tin. Các tệp kịch bản này thường  
được viết ngắn gọn, đơn giản.  
Khi viết các tệp kịch bản, ta cần lưu ý một số điểm sau [4]:  
Các lệnh nên được viết đơn giản với các đoạn mã lệnh ngắn. Một bộ phân tích  
cú pháp cho các tệp kịch bản được viết khá dễ dàng với ngôn ngữ C.  
Các kỹ sư lập trình nên sử dụng các ghi chú, để cho cấu trúc tệp tin được rõ  
15  
ràng, dễ hiểu, và chúng ta có thể biết rằng tệp kịch bản thực thi những lệnh nào,  
các phần nào đang được kiểm thử. Việc viết các tệp tin và các ghi chú cũng nên  
tuân theo các chuẩn chung để tất cả mọi người làm việc trong dự án có thể hiểu  
và thực hiện nó. Các ghi chú thường được bắt đầu bằng ký hiệu #.  
Dữ liệu nhập vào có thể là ở dạng mã ASCII hoặc ở các định dạng khác. Nhiều  
hệ thống nhúng nhận các dữ liệu dạng nhị phân, hệ thống cần có cách để có thể  
đọc được các dữ liệu, định dạng và hiển thị được các dữ liệu kiểu nhị phân.  
Việc đọc các tệp kịch bản và kết xuất thông tin ra các tệp tin làm cho công việc  
kiểm thử lặp lại được thực hiện dễ dàng hơn.  
3.2.5. Những phản đối, hạn chế và nhược điểm  
Các kỹ sư phần mềm thường phản đối việc kiểm thử các đoạn mã hệ thống nhúng  
trên máy chủ vì một số lý do sau đây:  
Thứ nhất, họ cho rằng, các đoạn mã của hệ thống nhúng là “rất phụ thuộc phần  
cứng”. Đúng là có một số hệ thống nhúng, các mã lệnh của họ hoàn toàn phụ thuộc  
phần cứng và các hệ thống nhúng thì chắc chắn là sẽ phải có các mã lệnh phụ thuộc  
phần cứng, nhưng trên thực tế thì các hệ thống nhúng không trực tiếp làm việc với  
phần cứng, nó tương tác qua các vi xử lý và số lượng các mã lệnh phụ thuộc phần  
cứng là ít hơn nhiều so với các mã lệnh không phụ thuộc phần cứng.  
Thứ hai, họ cho rằng việc xây dựng các mã nền kiểm thử là phức tạp hơn nhiều  
so với giá trị mà nó mang lại. Có hai lý do cho sự phản đối này là: việc tìm các lỗi  
trong phòng thí nghiệm trên mã nền kiểm thử là tốn thời gian, mà sau đó chỉ tìm ra  
một vài lỗi và thêm nữa là mã nền kiểm thử đôi khi còn làm việc không được tốt... Các  
kỹ sư lập trình cho rằng thật tốn thời gian để viết mã nền kiểm thử và các tệp kịch bản.  
Nhưng hiệu quả rất lớn của việc viết nền kiểm thử, các tệp kịch bản và các tệp kết xuất  
mang lại cho họ là họ có thể thực hiện việc kiểm thử lặp đi lặp lại, và các thông tin kết  
xuất được sắp xếp một cách hợp lý, khoa học. Điều này sẽ giúp tiết kiệm thời gian hơn  
rất nhiều.  
Thứ ba, để dùng kỹ thuật này, chúng ta cần phải có một phiên bản của hệ điều  
hành thời gian thực (RTOS - Real Time Operating System) chạy trên hệ thống máy  
chủ. Lý do này thiếu sức thuyết phục vì các nhà cung cấp RTOS đã cung cấp các phiên  
bản hệ điều hành của họ có thể chạy trên các hệ điều hành Windows, DOS hay Unix,  
các kỹ sư lập trình chỉ cần chọn một RTOS phù hợp với hệ điều hành mà máy chủ của  
16  
họ đang sử dụng để dùng.  
Thứ tư, kỹ thuật kiểm thử trên máy chủ không thể kiểm thử được một số đặc  
trưng quan trọng của phần mềm trên máy chủ, bao gồm một số đặc trưng sau:  
Phần mềm tương tác với phần cứng: Ví dụ, nếu phần mềm viết dữ liệu vào  
UART sai địa chỉ, chúng ta sẽ không thể kiểm thử được đặc tính này trên mã  
nền kiểm thử.  
Tính đáp ứng và công suất: Khi các mã lệnh được biên dịch với các bộ biên  
dịch ngôn ngữ C khác nhau và chạy trên các vi xử lý khác với tốc độ khác nhau  
và đặc trưng về độ trễ ngắt khác nhau, thì tính đáp ứng và công suất của thiết bị  
sẽ khác nhau.  
Vấn đề chia sẻ dữ liệu: Vấn đề này phát sinh khi một ngắt đột ngột xảy ra,  
chúng ta không biết điều gì đã xảy ra, các cờ giải quyết tranh chấp có thể chưa  
được bật lên. Những lỗi như thế này khó mà tìm ra trong khi kiểm thử trên máy  
chủ.  
Vấn đề về tính khả chuyển: Hệ thống máy chủ và máy đích có thể khác nhau. Ví  
dụ, nếu hệ thống máy chủ là big - endian và hệ thống máy đích là little –  
endian, có những vấn đề có thể xuất hiện ở máy đích mà không xuất hiện ở máy  
chủ.  
Tóm lại, chúng ta không thể kiểm thử mọi trường hợp trên máy chủ. Tuy nhiên,  
thực hiện kiểm thử trên máy chủ giúp chúng ta kiểm thử được với một lượng lớn mã  
lệnh lặp lại và việc kiểm thử sớm trong quá trình phát triển phần mềm đã giảm được  
nhiều lỗi.  
3.3. Bộ mô phỏng  
Mô phỏng là một kỹ thuật đã được sử dụng trong khoa học kỹ thuật, công nghệ,  
giáo dục và y tế từ lâu. Ngày nay, chúng ta có thể thấy rất nhiều sản phẩm được mô  
phỏng, như các trò chơi được mô phỏng trên máy tính, các lớp học ảo, các thiết bị thực  
hành, các phần mềm giả lập để phục vụ cho việc nghiên cứu. Đối với ngành công nghệ  
thông tin, việc mô phỏng các máy tính, các chương trình trên một máy tính giúp cho  
việc phát triển phần mềm, phần cứng ngày càng dễ dàng hơn.  
Bộ mô phỏng (Simulator) hay bộ mô phỏng tập lệnh (ISS) là một phần mềm chạy  
trên máy chủ và cho phép chúng ta giả lập vi xử lý và bộ nhớ trên máy đích. Ta có thể  
17  
thấy rất nhiều phần mềm mô phỏng chạy trên nhiều hệ điều hành, cung cấp những tiện  
ích cho người dùng như là Virtual Box của Oracle, VMWare của công ty VMWare,  
µVision của Keil, QEMU, Crosswork và Yagarto của công ty Rowley ...  
Bộ mô phỏng đã khắc phục được một số nhược điểm của kỹ thuật gỡ lỗi trên máy  
chủ. Sử dụng bộ mô phỏng, chúng ta phải biên dịch và liên kết, tạo ra các tệp tin thực  
thi chạy được trên các máy đích, sau đó nạp tệp thực thi này vào bộ mô phỏng. Ta cần  
phải biết chắc rằng bộ mô phỏng có thể hiểu được định dạng kết xuất của bộ liên kết/  
định vị (Linker/ Locator). Chúng ta thường phải biên dịch ra các tệp tin có định  
dạng .hex hay .elf để nạp vào bộ mô phỏng, đây thực chất là các tệp tin dưới dạng mã  
máy, để máy đích có thể chạy trực tiếp được nó.  
Bộ mô phỏng cũng cần hiểu được kiến trúc vi xử lý của máy đích và các tập lệnh  
của nó, cũng như là có thể đọc các lệnh từ bộ nhớ (được mô phỏng) và thay đổi các giá  
trị trong RAM (được mô phỏng) và các thanh ghi trong vi xử lý làm việc như thế nào.  
Thông thường, chúng ta nên sử dụng các bộ mô phỏng được xây dựng riêng cho các  
họ vi xử lý khác nhau, như cho họ vi xử lý của 8051, ARV, ARM...  
Giao diện người dùng của các bộ mô phỏng cũng gần tương tự như giao diện của  
các bộ gỡ lỗi, nó cho phép chúng ta biên dịch, chạy chương trình, gỡ lỗi, thiết lập các  
điểm dừng, xem các trạng thái của bộ nhớ, thanh ghi. Nhiều bộ mô phỏng còn hỗ trợ  
ngôn ngữ macro, cho phép thiết lập các kịch bản gỡ lỗi để thực thi mã lệnh.  
Bộ mô phỏng có các ưu điểm sau:  
Xác định được sự đáp ứng và công suất: Mặc dù các bộ mô phỏng không chạy  
cùng tốc độ với hệ thống đích, nhưng hầu hết chúng thống kê thời gian thực thi  
các lệnh cụ thể. Ví dụ, bộ mô phỏng có thể ghi lại số lệnh vi xử lý đích đã thực  
hiện hay số vòng của bus máy đích đã quay. Bằng việc tính thời gian hệ thống  
đích thực hiện một lệnh hay thời gian bus quay được một vòng có thể tính được  
cụ thể thời gian thực hiện.  
Kiểm thử các mã lệnh assembly: Các bộ mô phỏng sử dụng tập lệnh của hệ  
thống máy đích, các mã lệnh được viết bằng assembly sẽ được thực hiện một  
cách dễ dàng. Chúng ta thực thi các mã lệnh thông qua trình biên dịch trung  
gian chéo (cross – assembler), bộ liên kết/ định vị và sau đó tải chương trình  
vào bộ mô phỏng. Chúng ta có thể kiểm thử các mã lệnh như trên máy đích, các  
mã khởi động (startup code) và thường trình ngắt.  
18  
Giải quyết vấn đề tính khả chuyển: Bởi vì chúng ta dùng cùng một bộ công cụ  
để phát triển mã lệnh cho bộ mô phỏng và máy đích, nên chúng ta sẽ có ít sự  
khác biệt khi chuyển các mã lệnh từ bộ mô phỏng sang máy đích hơn là khi  
chuyển từ máy chủ sang máy đích.  
Kiểm thử mã lệnh với các thiết bị bên trong vi xử lý: Hầu hết các bộ mô phỏng  
sẽ mô phỏng các thiết bị bên trong vi xử lý của hệ thống đích. Nếu phần mềm  
có làm việc với một bộ định thời (timer) gắn liền bên trong, thì bộ mô phỏng sẽ  
mô phỏng bộ định thời, và khi đếm hết vòng lặp thì bộ mô phỏng cũng sẽ thực  
thi một thường trình ngắt, tức là một thường trình ngắt định thời đã được gọi  
lên.  
Các bộ mô phỏng giúp cho các kỹ sư lập trình học tập, làm việc, nghiên cứu  
ngay cả khi chưa có phần cứng vẫn có thể thực thi, kiểm thử các mã lệnh. Về  
mặt tài chính, thì việc sử dụng các bộ mô phỏng để làm việc là tiết kiệm và hiệu  
quả trong rất nhiều trường hợp. Nó mở ra khả năng nghiên cứu tại nhà mà  
không cần những phòng thí nghiệm hiện đại, các công cụ đắt tiền, dễ hỏng hóc.  
Tuy nhiên bộ mô phỏng cũng có một số nhược điểm sau:  
Lỗi chia sẻ dữ liệu: Lỗi này thường xảy ra khi các ngắt xảy ra ở một thời điểm  
không định trước. Bộ mô phỏng có thể mô phỏng các ngắt xảy ra trong quá  
trình kiểm thử, trừ khi chúng ta có nhiều thời gian để xem xét từng ngắt tại các  
thời điểm khác nhau để biết lỗi thực sự ở ngắt nào, nếu không thì việc mô  
phỏng và thực thi các ngắt này là liên tục nên sẽ khó bắt được lỗi.  
Với các thiết bị phần cứng khác: Bộ mô phỏng sẽ mô phỏng được vi xử lý,  
RAM, ROM, và các thiết bị gắn bên trong vi xử lý, nhưng với các thiết bị phần  
cứng mở rộng khác như loa, tai nghe, bộ cảm biến,… thì bộ mô phỏng không  
thể làm được gì.  
Bộ mô phỏng có thể làm cho các kỹ thuật kiểm thử với máy chủ ở trên trở lên  
khó khăn. Với kỹ thuật kiểm thử trên máy chủ, thì tại một thời điểm, chúng ta có thể  
thực thi nhiều tệp tin và bắt được các tệp tin kết xuất. Còn với kỹ thuật kiểm thử dùng  
bộ mô phỏng, thì tại thời điểm thực thi mã lệnh và mô phỏng thì chương trình chỉ có  
thể thực hiện được một nhiệm vụ đó, và việc truy cập vào phần mềm bằng bàn phím,  
hay chuột là vô ích. Để dùng được những kỹ thuật kiểm thử trên máy chủ thì bộ mô  
phỏng của ta cần phải đọc các tệp kịch bản vào môi trường mô phỏng và lấy kết quả  
19  
ra.  
Ta có thể sử dụng các kỹ thuật trong phần 3.2 để kiểm thử cho các ca kiểm thử  
thông thường và sau đó dùng bộ mô phỏng để thực hiện các ca kiểm thử khác để mang  
lại hiệu quả kiểm thử tốt.  
3.4. Sử dụng macro assert  
Macro assert là một công cụ rất hữu ích đối với các kỹ sư lập trình. Macro là một  
tập các phát biểu của hợp ngữ hay ngôn ngữ bậc cao mà có thể được gọi ra bằng các từ  
đơn hay các cụm từ trong mã nguồn, macro làm giảm các bước gõ lệnh và tăng tính dễ  
hiểu bởi ý tưởng thay các cụm từ phổ biến thường dùng bằng một phát biểu đơn [2].  
Macro có thể tự động thực hiện thao tác và làm giảm các bước cũng như thời gian  
hoàn thành công việc.  
Macro assert là một biểu thức đơn: nếu biểu thức trả lại giá trị true thì hàm  
assert không làm gì cả; nếu biểu thức trả về giá trị false thì hàm assert làm cho chương  
trình bị ngừng lại và đưa ra một số thông báo hữu ích.  
Chúng ta dùng hàm assert cho chương trình kiểm tra những thứ mà ta chắc chắn  
là phải đúng, hay nói cách khác là kiểm tra các lệnh trong chương trình của chúng ta  
có đúng không. Việc sử dụng assert một cách hợp lý sẽ làm cho chương trình dừng lại  
đúng cách, tránh cho chương trình phải dừng lại sau khoàng 100.000 lệnh.  
Các macro assert giúp tìm kiếm các lỗi một cách sớm nhất có thể để chúng ta có  
cách giải quyết với chúng. Điều này rất có ích khi chúng ta kiểm thử trên máy chủ.  
Tuy nhiên, trên máy đích hầu hết các hệ thống nhúng không có một thiết bị hiển thị  
thích hợp để hiển thị các thông báo của hàm assert. Hơn nữa, trong các chương trình  
ứng dụng, hàm assert sẽ gọi ra các hàm exit hay abort để dừng chương trình lại, nhưng  
trong các hệ thống nhúng thì thường không tồn tại các hàm đó. [4]  
Việc định nghĩa các marco có thể khác nhau giữa các trình biên dịch, nhưng  
thường chúng được viết trong tệp assert.h và có dạng như sau:  
Bảng 3.1 Mã lệnh của hàm NDEBUG  
#ifdef NDEBUG  
#define assert(bool_expression)  
#else  
//Xác định assert  
20  
#define assert(bool_expression)  
if(bool_expression) ;  
else  
bad_assertion(_FILE_, _LINE_, #bool_expression);  
#endif  
Các hàm macro thường được biên dịch không có lệnh như NDEBUG, nó thường  
là các biểu thức logic trả về cho chương trình giá trị true hay false. Việc định nghĩa các  
hàm assert một cách chính xác rất quan trọng, vì nó sẽ làm ảnh hưởng đến hệ thống  
của chúng ta, có thể làm giảm hiệu suất của hệ thống.  
Hàm bad_assertion sẽ giúp chúng ta phát hiện được các lỗi của chương trình  
sớm khi biên dịch. Các hàm bad_assertion được viết để thực hiện các công việc sau:  
Vô hiệu hóa các ngắt hay các vòng lặp vô hạn, giúp cho chương trình dừng lại  
đúng cách và ta có thể biết được chương trình của chúng ta đang làm gì.  
Bật một số đèn led hay các âm thanh đặc trưng để chúng ta biết được rằng hệ  
thống đang có vấn đề.  
Ghi ra giá trị của các biểu thức vào các vị trí nhớ đặc trưng, mà chúng ta có thể  
bắt được các kết xuất đó bằng bộ phân tích logic.  
Ghi ra vị trí các lệnh mà nó gọi từ các vị trí nhớ đặc trưng.  
Thực thi một lệnh không hợp lý hay làm bất kỳ điều gì cần thiết để dừng hệ  
thống mà không làm tổn hại đến chương trình.  
3.5. Sử dụng các công cụ trong phòng thí nghiệm  
Phần mềm nhúng thường được phát triển trên các phần cứng đặc trưng của nó.  
Vì vậy mà việc kiểm thử cho các phần mềm nhúng thì bao gồm cả việc kiểm thử dựa  
trên các phần cứng, và kiểm thử bằng các công cụ trong phòng thí nghiệm là một phần  
không thể thiếu.  
Các công cụ kiểm thử trong phòng thí nghiệm:  
- Máy hiện sóng (Oscilloscope).  
- Bộ phân tích logic ( Logic analyzer).  
- Bộ mô phỏng trong mạch (Emulator).  
21  

Tải về để xem bản đầy đủ

pdf 65 trang yennguyen 12/05/2025 160
Bạn đang xem 30 trang mẫu của tài liệu "Khóa luận Các kỹ thuật gỡ lỗi trong việc phát triển hệ thống nhúng với ngôn ngữ C", để tải tài liệu gốc về máy hãy click vào nút Download ở trên.

File đính kèm:

  • pdfkhoa_luan_cac_ky_thuat_go_loi_trong_viec_phat_trien_he_thong.pdf