Việc gỡ lỗi giúp nâng cao chất lượng phần mềm, nhưng các phương pháp, các
công cụ chỉ là những thiết bị bổ trợ, cách hiệu quả nhất để giảm thiểu số lỗi trong phần
mềm là chính bản thân các kỹ sư lập trình cần viết chương trình sáng sủa, rõ ràng, và
kiểm soát các lỗi của họ. Điều này sẽ giúp cho công việc gỡ lỗi đỡ vất vả hơn rất
nhiều.
65 trang |
Chia sẻ: lylyngoc | Lượt xem: 2877 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Luận vă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, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
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) //Xác định assert
#else
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
Sử dụng các công cụ này, đòi hỏi chúng ta phải có kiến thức về phần cứng máy
tính, để có thể hiểu được các thông số mà các thiết bị đưa ra. Máy hiện sóng và bộ
phân tích logic có ích trong trường hợp gỡ lỗi cho các tương tác giữa bộ vi xử lý và
các chip khác trên mạch, vì chúng có thể hiển thị các tin hiệu giao tiếp giữa bộ vi xử lý
và các thiết bị, nhưng không điều khiển được phần mềm, nên chỉ giúp phát hiện lỗi mà
không giải quyết được. Bộ mô phỏng trong mạch giúp chúng ta có thể gỡ lỗi được tốt
hơn.
3.5.1. Máy hiện sóng
Máy hiện sóng (Oscilloscopes) là một thiết bị hiển thị đồ thị điện áp – thời gian.
Đồ thị của một máy hiện sóng như sau:
Hình 3.3. Đồ thị của một máy hiện sóng [11]
Ở đây, thời gian nằm ở trục hoành và được tính bằng nano giây (ns) còn điện áp
nằm ở trục tung và được tính bằng vôn (V). Máy hiện sóng là một thiết bị tương tự
(analog device), nó không chỉ đo được điện áp đang ở mức cao hay thấp mà còn đo
được chính xác điện áp.
Máy hiện sóng có một số ưu điểm như sau:
• Có thể hiển thị một hoặc hai tín hiệu đồng thời.
• Có thể điều chỉnh độ quét theo thời gian hay điện áp trên một dải rộng.
• Có thể điều chỉnh trục tung trên màn hình máy hiện sóng để hiển thị tình
trạng nối đất hay ở mức thấp.
• Có thể điều chỉnh khi máy hiện sóng bắt đầu vẽ thông qua việc dùng một ràng
22
buộc cơ học để chỉ cho máy hiện sóng biết rằng điều kiện để ghi lại tín hiệu là
gì. Ví dụ như, ta muốn máy hiện sóng bắt đầu ghi lại tín hiệu sau khi thiết bị
khởi động được 5 phút.
Máy hiện sóng là một công cụ tuyệt vời đối với các kỹ sư phần cứng, còn các kỹ
sư phần mềm dùng nó cho những mục đích sau:
• Ta có thể dùng máy hiện sóng như một vôn kế dùng để đo điện áp. Nếu điện
áp của một tín hiệu không thay đổi thì hình ảnh hiển thị trên máy hiện sóng sẽ
là một đường thẳng kéo dài trên màn hình, và tung độ của điểm xác định điện
áp của tín hiệu.
• Ta cũng có thể dùng máy hiện sóng để thấy rằng bản mạch đang hoạt động.
Nếu đường hiện thị trên màn hình máy hiện sóng thẳng, thì sau đó bộ vi xử lý
không thực hiện lệnh nào cả. Tương tự như khi đọc các địa chỉ hay tín hiệu
trên RAM, ta có thể xác định được chương trình của mình đang làm gì.
• Ta có thể dùng máy hiện sóng để thấy các tín hiệu đang thay đổi như thế nào.
Giả sử với các tín hiệu lặp đi lặp lại thì ta sẽ thấy trên màn hình của máy hiện
sóng các đường lặp đi lặp lại.
• Thường thì chúng ta sẽ tìm ra một lỗi phần cứng khi đo một tín hiệu số đã
chuyển từ trạng thái nối đất sang trạng thái vô cùng hay ngược lại trong vài
phần nghìn giây, điều đó cho thấy là đã có một lỗi xảy ra, hay một phần cứng
trong mạch không hoạt động tốt. Các kỹ sư phần cứng sẽ dựa vào đó để xác
định lỗi và sửa lại lỗi đó.
Các máy hiện sóng thông thường bắt sóng bằng việc quét các tin hiệu lặp lại, và
để đo được điện áp thì các tín hiệu cũng nên được phát lặp đi lặp lại thông qua một
ràng buộc cơ học.
Hình 3.4. mô tả cấu tạo của một máy hiện sóng.
23
Hình 3.4. Máy hiện sóng [14]
◦
Cấu tạo cơ bản của một máy hiện sóng bao gồm các phần:
• Màn hình để hiển thị đồ thị.
• Các nút điều chỉnh nguồn, điều chỉnh các ràng buộc cơ học.
• Một đầu dò (probe) và một dây nối đất.
Các máy hiện sóng kiểu cũ thường không phải là một thiết bị lưu trữ, các đồ thị
điện áp – thời gian được vẽ ra trên màn hình, và rất nhanh sau đó sẽ bị thay thế bằng
các đồ thị khác. Nhưng các máy hiện sóng hiện đại được thiết kế như một thiết bị lưu
trữ, giúp chúng ta lưu các thông tin, đồ thị, để từ đó có thể dễ dàng tìm ra lỗi.
Cách sử dụng máy hiện sóng đơn giản là ta chọc đầu dò vào phần thiết bị cần đo
điện áp, kẹp dây nối đất vào bản mạch và sau đó đo điện áp của thiết bị. Máy hiện
sóng là một thiết bị đo rất nhạy, nên để đo được chính xác điện áp của thiết bị ta luôn
luôn phải kiểm tra xem dây nối đất đã được nối đất chưa.
3.5.2. Bộ phân tích logic (Logic Analyzer)
Bộ phân tích logic là một công cụ khác dùng để bắt các tín hiệu và vẽ chúng trên
màn hình. Về chức năng, nó gần tương tự như máy hiện sóng, nhưng có vài điềm khác
24
biệt sau:
• Một bộ phân tích logic có thể dò được nhiều tín hiệu ngay lập tức. Điều đó phụ
thuộc vào ta muốn mua thiết bị đo được bao nhiêu tín hiệu, vì muốn đo được
bao nhiêu tín hiệu thì ta cần từng đó đầu dò để bắt tín hiệu.
• Một bộ phân tích logic chỉ biết hai mức điện áp là: mức cao (VCC) và mức thấp
- mức 0 – nối đất (ground). Với một mức điện áp nằm giữa mức cao và mức
thấp thì nó sẽ báo không chính xác, không như máy hiện sóng là sẽ hiện ra điện
áp chính xác của thiết bị.
• Tất cả các bộ phân tích logic đều là những thiết bị lưu trữ. Chúng bắt các tín
hiệu đầu tiên và sau đó hiển thị chúng. Các bộ phân tích logic thường phải được
đặt các ràng buộc cơ học và sau đó bắt các dữ liệu từ nguồn để giải quyết vấn
đề.
• Bộ phân tích logic có các ràng buộc cơ học phức tạp hơn máy hiện sóng. Ta có
thể thiết lập các ràng buộc như là chỉ bắt tín hiệu khi tín hiệu A ở mức cao, tín
hiệu B ở mức thấp và tín hiệu C ở mức cao khi tín hiệu E bắt đầu hoạt động
được 10 nano giây.
Hình 3.5 mô tả cấu tạo bên ngoài của bộ phân tích logic.
Hình 3.5. Bộ phân tích logic [13]
25
Các bộ phân tích logic sẽ làm việc theo hai chế độ: bộ phân tích logic theo chế độ
thời gian, và bộ phân tích logic theo chế độ trạng thái.
3.5.2.1. Bộ phân tích logic theo chế độ thời gian
Với bộ phân tích logic theo chế độ thời gian, ta sẽ giải quyết được một số việc
sau đây:
• Ta có thể tìm ra dấu vết nếu một sự kiện nào đó đã xảy ra thông qua những tín
hiệu mà bộ phân tích logic đã bắt được.
• Ta có thể đo được khoảng thời gian mà phần mềm đáp ứng lại yêu cầu. Ví dụ ta
nối đầu dò của bộ phân tích logic vào một nút ngắt tín hiệu chuông của thiết bị
theo dõi bể ngầm, khi nào ta nhấn nút ngắt để tắt chuông, thì bộ phân tích logic
sẽ cho ta biết thời gian từ khi nhấn nút đến khi hệ thống ngừng chuông.
• Ta có thể thấy nếu phần mềm gọi một tín hiệu thích hợp để điều khiển phần
cứng.
Hình 3.6. Màn hình hiển thị của bộ phân tích logic theo chế độ thời gian [13]
Bởi vì các bộ phân tích logic có thể bắt được nhiều tín hiệu đồng thời, nên có thể
gắn thêm các dây để chúng bắt các tín hiệu riêng của hệ thống. Cần lưu ý là với mỗi
đầu dò để đo một tín hiệu thì đều có dây nối đất, khi dò tín hiệu thì cần phải nối dây
nối đất cho các đầu dò để có thể đo tín hiệu một cách chính xác.
3.5.2.2. Bộ phân tích logic theo chế độ trạng thái
Trong chế độ thời gian, bộ phân tích logic tự động bắt các tín hiệu mà không liên
26
quan đến bất kỳ sự kiện nào của bản mạch. Còn trong chế độ trạng thái, bộ phân tích
logic là sẽ bắt các tín hiệu khi mà một sự kiện xảy ra trong hệ thống.
Khi dùng bộ phân tích logic ở chế độ trạng thái sẽ thấy các lệnh mà vi xử lý đã
nạp, những dữ liệu đã đọc và ghi từ bộ nhớ và các thiết bị xuất nhập. Để thấy các lệnh
mà vi xử lý đã nạp, ta nối đầu dò của bộ phân tích logic tới tất cả các tín hiệu địa chỉ
và dữ liệu trong hệ thống và tín hiệu RE/ trên ROM. Nếu ta thiết lập cho bộ phân tích
logic bắt tín hiệu khi tín hiệu RE/ được bật lên thì nó sẽ bắt các tín hiệu địa chỉ và dữ
liệu của RE/ khi RE/được bật. Hầu hết các bộ phân tích logic có thể thu được nhiều tín
hiệu đồng thời như thế. [4]
Bộ phân tích logic chế độ trạng thái thường hiển thị dạng dữ liệu văn bản lên
màn hình, với mỗi dòng là trạng thái của tất cả tín hiệu khi một sự kiện xảy ra. Hầu hết
các bộ phân tích logic cho phép chúng ta định dạng dữ liệu theo nhiều kiểu khác nhau.
Ví dụ, ta có thể định dạng cho dữ liệu ra là kiểu bát phân như hình 3.7.
Hình 3.7. Màn hình hiển thị của bộ phân tích logic theo chế độ trạng thái [12]
Ta thấy rằng các mã bát phân này khó đọc, vì thế bộ phân tích logic có thể hiển
thị các lệnh dưới dạng ngôn ngữ assembly, nó sẽ dễ hiểu hơn là dạng mã bát phân hay
nhị phân. Nhưng để làm được điều này thì bộ phân tích logic cần hiểu về vi xử lý mà
ta đang dùng, và yêu cầu đối với máy đích. Một vài bộ phân tích logic sẽ có ràng buộc
để bắt các lệnh từ mã nguồn, cho phép ta thấy một phần của phần mềm đang thực thi.
Bộ phân tích logic theo chế độ trạng thái là một công cụ hữu ích cho các kỹ sư
27
phần mềm:
• Ta có thể tạo các ràng buộc để nếu vi xử lý nạp các lệnh từ một địa chỉ không
được phép, và nếu gây ra lỗi thì ta có thể tìm được lỗi này.
• Ta có thể xây dựng các ràng buộc để nếu vi xử lý ghi các giá trị không hợp lệ
vào một vị trí cụ thể trên RAM gây ra lỗi thì ta có thể bắt được lỗi. Ví dụ như
hệ thống viết giá trị 5 vào giá trị trạng thái của một tập chỉ có 4 trạng thái, thì
sẽ gây ra lỗi.
• Ta có thể xây dựng các ràng buộc để bộ phân tích logic bắt các sự kiện khi vi
xử lý nạp lệnh đầu tiên hay khi các thường trình ngắt xảy ra, và thấy vi xử lý
thực thi các thường trình ngắt.
• Nếu có một lỗi rất hiếm gặp xảy ra, ta có thể để bộ phân tích logic chạy và
kiểm tra kết quả được in trên màn hình để biết dấu vết của lỗi.
• Hầu hết các bộ phân tích logic cho phép ta tạo một bộ lọc để giới hạn các kết
quả thu được.
Thông thường, các ràng buộc trong bộ phân tích logic là một tập các sự kiện mà
ta tin rằng ở đó có lỗi và sau đó ghi lại để kiểm tra các trạng thái của hệ thống để tìm
ra lỗi.
Tuy nhiên, bộ phân tích logic cũng tồn tại một vài nhược điểm:
• Mặc dù bộ phân tích logic cho ta thấy vi xử lý đang làm gì, nhưng ta không thể
dừng hệ thống bằng cách thiết lập các điểm ngắt để xem xét từng bước của quá
trình thực hiện, để có thể xem kết quả trên các thanh ghi, bộ nhớ,...
• Ta chỉ biết được trạng thái của bộ nhớ khi vi xử lý đang đọc hay ghi trên nó, và
trạng thái của các thanh ghi trong vi xử lý là ẩn.
• Nếu chương trình bị ngắt đột ngột thì ta sẽ không biết bất kỳ điều gì xảy ra với
hệ thống, từ bộ nhớ, thanh ghi hay vi xử lý, các thông tin không được ghi lại.
• Nếu vi xử lý có một bộ nhớ đệm lớn và thực thi các lệnh trong đó, và khi bị tràn
bộ nhớ đệm thì ta không thể biết được vi xử lý đang làm gì. Những gì mà bộ
phân tích logic ghi lại được chỉ là các lệnh đã được nạp.
3.5.3. Bộ mô phỏng trong mạch
Bộ mô phỏng trong mạch (ICE) thường được gọi là bộ mô phỏng (emulator), là
28
một thiết bị phần cứng thay thế cho vi xử lý trong mạch của máy đích: ta có thể tháo vi
xử lý trong bản mạch ra và thay bộ mô phỏng vào đó. Bộ mô phỏng sẽ thay thế cho vi
xử lý cua máy đích, nó chấp nhận kết nối tất cả các tín hiệu được gửi tới vi xử lý thật
và thực hiện như một vi xử lý thật. Bộ mô phỏng cung cấp cho ta khả năng gỡ lỗi
tương tự như các phần mềm gỡ lỗi chuẩn. Ta có thể đặt các điểm dừng, và sau đó khi
chương trình chạy ta có thể xem trạng thái của các thanh ghi, bộ nhớ, mã nguồn đang
được dịch và gỡ lỗi từng bước. Thậm chí nếu chương trình bị ngắt, bộ mô phỏng vẫn
có thể cho chúng ta thấy được các thông số của bộ nhớ và thanh ghi. Hầu hết các bộ
mô phỏng sẽ bắt các vết tương tự như khi ta bắt các vết với bộ phân tích logic ở chế độ
trạng thái, mặc dù chúng không linh hoạt bằng bộ phân tích trong trường hợp này.
Nhiều bộ mô phỏng có khả năng gọi các bộ nhớ nạp chồng (overlay memory). Ta
sẽ chỉ cho bộ mô phỏng biết những dải địa chỉ của bộ nhớ ROM và bộ nhớ RAM. Khi
vi xử lý được mô phỏng đọc và viết vào bất kỳ địa chỉ nào trong một dải đặc biệt, bộ
mô phỏng sẽ dùng bộ nhớ bị nạp chồng thay thế cho bộ nhớ của máy đích. Các phần
mềm hỗ trợ cho bộ mô phỏng chạy trên máy chủ đọc các tệp kết xuất định vị và tải
xuống bộ nhớ nạp chồng của phần mềm. Điều này giúp tải các phiên bản của phần
mềm vào hệ thống đích để gỡ lỗi dễ dàng và hiệu quả.[4]
Bộ mô phỏng là một công cụ hữu ích, nó có những ưu điểm như một trình gỡ lỗi
thông thường và cũng có khả năng của một bộ phân tích logic. Tuy nhiên, về nhiều
mặt, bộ phân tích logic có nhiều ưu điểm hơn bộ mô phỏng:
• Bộ phân tích logic có bộ lọc vết (trace) tốt hơn và có các ràng buộc cơ học phức
tạp hơn.
• Bộ phân tích logic có thể chạy được chế độ thời gian.
• Bộ phân tích logic có thể làm việc với mọi vi xử lý, còn bộ mô phỏng thì
thường chỉ làm việc với một số vi xử lý nhất định. Và giá thành của một bộ mô
phỏng không hề rẻ, mà mỗi khi ta làm việc với một vi xử lý mới thì ta có thể sẽ
cần một bộ mô phỏng mới.
• Với các bộ phân tích logic ta có thể nối một vài hay nhiều kết nối mà ta muốn.
Còn với bộ mô phỏng, ta phải kết nối tất cả các tín hiệu để nó có thể chạy được.
• Đối với bộ mô phỏng, đôi khi những lỗi cũ không xuất hiện nữa hay lỗi mới lại
xuất hiện khi vi xử lý bị thay thế bằng một bộ mô phỏng.
29
Hiện nay, nhiều công ty đã sản xuất các thiết bị lai giữa bộ phân tích logic và bộ
mô phỏng để cho ta có được những ưu điểm của cả hai thiết bị. Việc kiểm thử trong
các hệ thống nhúng khó khăn đã làm cho các nhà cung cấp đưa ra các sản phẩm sáng
tạo hơn.
30
CHƯƠNG 4: CÔNG CỤ GỠ LỖI
Như khóa luận đã trình bày ở trên, có rất nhiều kỹ thuật gỡ lỗi cho hệ thống
nhúng, mỗi kỹ thuật đều có ưu nhược điểm riêng. Sau đây khóa luận sẽ trình bày về
công cụ gỡ lỗi dùng kỹ thuật mô phỏng cho họ vi xử lý ARM là công cụ Keil µVision.
4.1. Lý do chọn họ vi xử lý ARM
ARM là một cấu trúc vi xử lý 32 bit kiểu RISC được sử dụng rộng rãi trong các
ứng dụng nhúng. Các thiết kế của nó hướng tới việc nâng cao hiệu năng, tiết kiệm
điện, giảm giá thành hệ thống và được phát triển thêm bởi các nhà phát triển thứ ba
làm cho các sản phẩm dựa trên nền tảng vi xử lý ARM ngày càng phổ biến.
Ngày nay, ta có thể thấy các sản phẩm, ứng dụng của vi xử lý ARM ở khắp mọi
nơi, từ những thiết bị điện tử công nghệ cao như smartphone, smartbook, netbook đến
các thiết bị nhúng như là thiết bị điều khiển ôtô tự động, mạng không dây, máy in, các
thiết bị mạng, thẻ từ, hộ chiếu điện tử,...
Các vi xử lý ARM có khả năng chạy trên nhiều hệ điều hành như Microsoft
Windows (CE/Embedded), Linux, Android/ Chrome, và Symbian.
Với hơn 15 tỷ vi xử lý đã được tạo ra và hơn 10 triệu vi xử lý được bán ra mỗi
ngày, ARM thực sự là kiến trúc phần cứng của kỷ nguyên số. [15]
ARM có một số đặc điểm sau:
• Cấu trúc nạp/ lưu trữ.
• Tập lệnh trực giao.
• Có 16 thanh ghi 32 bit.
• Chiều dài mã máy cố định là 32 bit.
• Hầu hết các lệnh đều thực hiện trong vòng một chu kỳ đơn.
• Hầu hết các lệnh đều cho phép thực thi có điều kiện, điều này làm giảm việc
phải viết các lệnh rẽ nhánh.
• Có kiểu định địa chỉ theo chỉ số rất mạnh.
• Có hệ thống con thực hiện ngắt hai mức ưu tiên đơn giản, nhưng rất nhanh,
kèm theo cho phép chuyển từng nhóm thanh ghi.
• Hỗ trợ mã lệnh Thumb 16 bit, giúp cho chương trình gọn hơn.
31
Với những đặc điểm về tính năng và sự phổ biến của họ vi xử lý ARM nên khóa
luận lựa chọn họ vi xử lý ARM để làm ứng dụng cho phần lý thuyết về các kỹ thuật gỡ
lỗi ở chương trước.
4.2. Giới thiệu công cụ µVision
µVision là một công cụ kết hợp giữa môi trường phát triển tích hợp (IDE -
Integrated Development Environment) và bộ gỡ lỗi (Debugger) được phát triển bởi
công ty Keil ARM.
Keil ARM là một công ty chuyên phát triển, sản xuất và phân phối các công cụ
phát triển phần mềm nhúng cho các họ vi điều khiển 8051, 251, ARM, XC16x/ C16x/
ST10 và các sản phầm phần cứng như các bộ mô phỏng trong mạch (Emulator) và các
bo mạch kiểm định (Evaluation Board).
Phiên bản mới nhất của công cụ là µVision phiên bản 4.11.
Keil cung cấp miễn phí các bản dùng thử cho người dùng. Để tải được các bản
dùng thử, người dùng chỉ cần điền vào một bảng thu thập thông tin có dạng như sau:
Hình 4.1. Mẫu đăng ký sử dụng bản dùng thử của Keil
Keil cũng cung cấp phần mềm có bản quyển cho người dùng có nhu cầu với mức
phí khoảng 4000 euro cho một phần mềm.
32
Công cụ µVision cung cấp trình soạn thảo và gỡ lỗi cho các ứng dụng với thiết
kế giao diện người dùng đồ họa đẹp và dễ sử dụng. Công cụ cho phép các kỹ sư lập
trình viết chương trình ứng dụng, gỡ lỗi và mô phỏng với nhiều loại máy đích khác
nhau.
Khóa luận tập trung đi vào nghiên cứu công cụ µVision phiên bản dùng thử chạy
cho họ vi xử lý ARM là MDK-ARM dùng cho các vi điều khiển ARM7, ARM9,
Cortex-M0, Cortex-M1 và Cortex-M3.
4.3. Các chức năng chính của công cụ µVision
4.3.1. Các chức năng của µVision IDE
µVision IDE là một nền phát triển phần mềm dựa trên giao diện cửa sổ kết hợp
giữa trình soạn thảo, quản lý dự án, và công cụ Make Utility. µVision hỗ trợ tất cả các
công cụ của Keil bao gồm C/C++ Compiler, Marco Assembler, Linker, Library
Manager, và Object-HEX Converter. Hình 4.2 minh họa giao diện của µVision IDE.
Hình 4.2. Giao diện của µVision IDE
33
Bảng 4.1 đưa ra một số tính năng chính mà µVision IDE cung cấp. [8]
Bảng 4.1. Các chức năng của µVision IDE [5]
STT Tên Mô tả chức năng Đường dẫn
1 Device Database Lựa chọn thiết bị và cấu hình cho
công cụ phát triển cụ thể cho vi
điều khiển đích.
File → Device
Database
2 Project Manager Tạo và chỉnh sửa dự án. Project
3 Make Utilities Chuyển thành hợp ngữ, biên dịch,
liên kết các ứng dụng nhúng.
4 Edit Có đầy đủ các chức năng của trình
soạn thảo mã lệnh.
Edit
5 Template Editor Chèn các chuỗi từ phổ biến hay các
đoạn mã header.
View → Template
Window
6 Source Browser Đưa ra các đối tượng của mã lệnh,
vị trí và phân tích dữ liệu trong ứng
dụng.
View → Source
Browser Window
7 Function Browser Chuyển giữa các hàm trong chương
trình.
View → Function
Browser Window
8 Function Outlining Điều khiển phạm vi tầm nhìn trong
một tập tin mã nguồn.
Edit → Outlining
9 Built-in Utilities Các tiện ích có sẵn như là Find in
Files và các chức năng cho phép
ghi chú hay không ghi chú ở mã
nguồn.
Edit → Advanced
11 Configuration
Wizard
Cung cấp trình soạn thảo cho mã
khởi động và tập tin cấu hình của
vi điều khiển.
Edit →
Configuration
12 Software Version
Control Systems
Giao diện để cấu hình Software
Version Control Systems và các tiện
SVCS → Configure
Software Version
34
STT Tên Mô tả chức năng Đường dẫn
ích của nhà cung cấp thứ ba. Control System
13 Flash Programming
Utilities
Tương tự như bộ chuyển đổi Keil
ULINK USB-JTAG .
Flash
14 Dialogs Điều chỉnh công cụ phát triển.
15 Help Liên kết tới các bảng số liệu kỹ
thuật của vi điều khiển và hướng
dẫn người sử dụng.
Help
4.3.2. Các chức năng của µVision Debugger
µVision Debugger được tích hợp cùng trong µVision IDE, chỉ khi chương trình
của chúng ta đã được biên dịch đúng thì ta mới có thể gỡ lỗi bằng µVision Debugger.
Nhấn vào nút Start/ Stop Debug Session (Ctrl + F5) để bắt đầu gỡ lỗi chương trình
trong máy chủ đã chọn, nhấn Run (F5) để chạy chương trình. Hình 4.3 minh họa cho
giao diện của µVision Debugger khi chương trình đang chạy.
Hình 4.3. Giao diện của µVision Debugger
35
µVision Debugger cung cấp các chức năng như sau [8]:
Bảng 4.2: Các chức năng của µVision Debugger [5]
STT Tên chức năng Mô tả Đường dẫn
1 Disassembly Tách mã nguồn C/C++ hay hợp
ngữ với chương trình thực thi trong
các stepping modes khác khau và
view modes khác nhau như là hợp
ngữ, kí tự hay cả hai.
View → Disassembly
Window
2 Breakpoint Tùy chọn nhiều điểm dừng bao
gồm các điểm dừng truy cập và
phức tạp.
Debug → Breakpoint
3 Bookmark Đánh dấu để dễ dàng tìm và xác
định được điểm mâu thuẫn.
Edit → Insert/ Remove
Bookmark
4 Review, modify Xem và sửa các giá trị của bộ nhớ,
biến, thanh ghi.
View → Memory
Window, Register
Window,
5 Program call
tree
Liệt kê cây chương trình gọi bao
gồm biến stack dưới dạng cây.
View → Call Stack
Window
6 Peripheral Xem tình trạng của các thiết bị
ngoại vi tích hợp trên vi điều khiển.
Peripherals
7 Command Chức năng gỡ lỗi bằng dòng lệnh
hay kịch bản giống C.
View → Command
Window
8 Execution
Profiling
Ghi và hiển thị thời gian thực thi
cũng như số chu kỳ cần cho mỗi
lệnh.
Debug → Execution
Profiling
9 Code Coverage Thống kê tỷ lệ các lệnh được thực
thi.
View → Analysis
Windows → Code
Coverage
10 Performance
Analyzer
Thống kê số lần gọi, thời gian gọi
hàm.
View → Analysis
Windows →
Performance Analyzer
11 Logic Analyzer Bắt, lưu và hiển thị các tín hiệu. View → Analysis
Windows → Logic
Analyzer
12 Instruction
Trace
Hiển thị lịch sử thực thi của các
lệnh.
View → Trace →
Instruction Trace
36
µVision Debugger cung cấp hai chế độ gỡ lỗi là dùng Simulator và Target Mode.
Chúng ta có thể lựa chọn chế độ gỡ lỗi bằng cách vào thẻ Project → Option for Target
“Target 1” rồi chọn thẻ Debug.
Simulator Mode là chế độ gỡ lỗi mô phỏng các tập lệnh và các thiết bị ngoại vi
tích hợp trên chip cho máy đích. Chế độ này dùng để kiểm thử, gỡ lỗi khi phần cứng
chưa sẵn sàng. Chức năng này của µVision Debugger giúp cho những người không có
phần cứng sẵn sàng cũng có thể nghiên cứu và làm việc được, nó giúp cho việc phát
triển các hệ thống nhúng không còn quá phụ thuộc vào phần cứng, và là tiền đề thúc
đẩy nhanh việc phát triển hệ thống.
Target Mode là chế độ gỡ lỗi khi phần mềm làm việc trực tiếp trên phần cứng.
Phiên bản µVision 4.10 cho phép việc gỡ lỗi trên các thiết bị phần cứng như là:
ULINK ARM Debugger, Signum Systems JTAGjet, J-LINK/ J-TRACE, ULINK Pro
ARM Debugger là các bộ công cụ được Keil hay các công ty thứ ba phát triển.
4.4. Ưu điểm của µVision
4.4.1. Ưu điểm của µVision IDE
µVision IDE có một số ưu điểm sau:[6]
• Device Database của µVision tự động cấu hình các công cụ phát triển cho vi
điều khiển đích: Các lỗi trong cài đặt công cụ thực sự được loại bỏ và thời gian
cấu hình cho công cụ là ngắn nhất.
• µVision IDE cho phép tích hợp thêm công cụ của nhà phát triển thứ ba. Điều
này cho phép chúng ta nhanh chóng truy cập tới tất cả các công cụ phát triển từ
một môi trường đơn. Tất cả các chi tiết cấu hình đều được lưu trong dự án
(project) của µVision.
• µVision tích hợp việc quản lý dự án, trình soạn thảo và bộ gỡ lỗi trong một môi
trường đơn nhằm tăng tốc cho việc phát triển các ứng dụng. Trong khi soạn
thảo, ta có thể cấu hình các chức năng của bộ gỡ lỗi. Trong khi gỡ lỗi, ta cũng
có thể sửa mã nguồn.
• Đồng nhất bộ gỡ lỗi với giao diện người dùng của bộ mô phỏng.
• Chức năng Code Coverage của bộ mô phỏng µVision phân tích, thống kê cho
việc thực thi các chương trình, cho phép xem và in ra các báo cáo.
37
• Bộ mô phỏng µVision là một bộ gỡ lỗi duy nhất mô phỏng đầy đủ tất cả các
thiết bị ngoại vi trong mạch của các thiết bị ARM như là Atmel, Philips, và thẻ
thông minh của Samsung. Ta có thể nghiên cứu sự khác nhau giữa việc cấu hình
phần cứng và tối ưu thiết kế phần cứng.
• µVision cũng cho phép mô phỏng nâng cao với giao diện mô phỏng nâng cao
(AGSI - Advanced Simulation Interface) đối với các hệ thống phức tạp có thể
được mô phỏng chính xác bằng việc thêm chính các trình điều khiển thiết bị
ngoại vi.
4.4.2. Ưu điểm của µVision Simulator
µVision Simulator có một số ưu điểm sau:[7]
• Cho phép thiết lập không hạn chế số lượng điểm dừng.
• Mô phỏng các thiết bị ngoại vi đồng bộ với chương trình thực thi.
• Có khả năng mô phỏng cả những tình huống bị dừng hay ngắt điện đột ngột của
phần cứng như là: trạng thái ngắt điện và chạy không tải.
• Các chức năng Code Coverage, Trace, Timing Profile, Logic Analyzer cho phép
phân tích các vết và thời gian.
• Cho phép nhập các tín hiệu vào từ một ngôn ngữ kịch bản và đồng bộ với
chương trình.
• Mô phỏng chính xác thời gian trong mối tương quan với các thiết bị ngoại vi.
4.5. Một số hạn chế của µVision phiên bản dùng thử
Keil hỗ trợ cho những người dùng mới, hay những người dùng có nhu cầu làm
việc với các dự án nhỏ phiên bản dùng thử của µVision. Các phiên bản này được tải
xuống trực tiếp từ hệ thống máy chủ của công ty. Tuy nhiên, vì đây là phiên bản dùng
thử nên nó có một số hạn chế như sau:[9]
• Nếu chương trình có dung lượng lớn hơn 32 KB thì dữ liệu sẽ không được biên
dịch, hợp ngữ hóa hay liên kết, và vì thế cũng sẽ không được gỡ lỗi.
• Bộ biên dịch thường không tạo ra danh sách tách rời của mã máy. Các tùy chọn
biên dịch dòng lệnh --S, --asm và --interleave bị vô hiệu hóa.
• Bộ hợp dịch và kết nối tạo ra các đối tượng định dạng xuất ký hiệu (Symbolic
38
Output Format) không liên kết với những tiện ích của nhà phát triển thứ ba.
Công cụ có bản quyền sẽ tạo ra những tập tin ELF/DWARF chuẩn để người sử
dụng có thể dùng được các tiện ích của nhà phát triển thứ ba.
• Bộ liên kết không chấp nhận các tệp mô tả sự tải phân tán cho các sơ đồ bộ nhớ
phức tạp. Lệnh --scatter thường bị vô hiệu hóa.
• Địa chỉ tham chiếu cho mã lệnh và hằng trong bộ nhớ phải là 0x000080000,
0x000100000, 0x000200000, 0x000300000, 0x000400000, 0x010400000,
0xXX000000, hay 0xXX800000 ( với XX là mã thập lục phân từ 00-FF). Địa
chỉ tham chiếu 0x0 là nơi bộ liên kết đặt mã khởi động của bộ nhớ Flash trên
chip của hầu hết các vi điều khiển cơ bản của vi xử lý ARM.
Mặc dù có một số hạn chế như trên, nhưng với đối tượng là sinh viên, những
người nghiên cứu và làm việc với các dự án nhỏ thì bản dùng thử này đã cung cấp
những tính năng cần thiết và hoàn toàn miễn phí cho họ.
4.6. Cài đặt
Trước khi cài đặt phần mềm, ta cần kiểm tra xem hệ thống của ta có thỏa mãn
một số yêu cầu sau đây không:
• Hệ điều hành của máy chủ là từ Windows 2000 trở lên.
• Có chuột hoặc những thiết bị tương tự chuột.
• Không gian ổ đĩa cứng phải còn tối thiểu là 300MB.
• RAM tối thiểu là 512 MB.
• Máy tính dòng Pentium trở lên.
Các sản phẩm của Keil có thể tải xuống trực tiếp từ trang chủ của công ty:
hoặc dùng các đĩa CD-ROM của công ty. Trên trang chủ của Keil
luôn cập nhật những phiên bản mới nhất các sản phẩm của công ty.
Công cụ có thể được cài đặt theo một trong hai cách sau đây:
• Cài đặt thông qua mạng internet:
- Ta điền vào bảng thu thập thông tin của công ty, sau đó tải tập tin mdk410.exe
xuống.
- Thực hiện việc cài đặt tập tin mdk410.exe như với các phần mềm thông
39
thường.
• Cài đặt từ đĩa CD-ROM:
- Chèn đĩa CD vào ổ, phần mềm sẽ tự động khởi động việc cài đặt. Nếu không
được thì ta có thể chạy tập tin setup.exe.
- Chọn Install Products & Updates từ thanh thực đơn của đĩa.
- Cài đặt từng bước theo hướng dẫn.
Đối với các phần mềm có bản quyền, chúng ta có thể liên hệ trực tiếp với công ty
Keil hoặc các công ty đại diện cho Keil tại khu vực chúng ta sống để có thể biết chi
tiết giá thành phần mềm.
Tại Việt Nam, công ty Vijasemi (trang chủ đặt tại: là
đại diện và nhà phân phối độc quyền các sản phẩm phát triển trên nền tảng chíp ARM
và các công cụ phát triển của ARM/Keil. Chúng ta có thể liên hệ với công ty để biết
thêm thông tin về các sản phẩm, công cụ có bản quyền và để được hỗ trợ kỹ thuật.
Việc sử dụng sản phẩm có bản quyền sẽ cung cấp cho chúng ta nhiều tiện ích hơn
so với các bản dùng thử của công ty.
40
CHƯƠNG 5: ỨNG DỤNG CÔNG CỤ µVISION VÀO VIỆC GỠ LỖI
Ở chương 4, khóa luận đã chỉ ra những ưu điểm của việc dùng công cụ µVision
vào việc gỡ lỗi. Chương này, khóa luận sẽ trình bày ứng dụng của công cụ vào việc gỡ
lỗi cho một số chương trình dưới đây.
5.1. Vi điều khiển LPC2148
Các chương trình viết trong chương này đều được viết cho vi điều khiển
LPC2148 của công ty NXP (trang chủ đặt tại: được phát triển
dựa trên nhân của họ vi xử lý ARM và được µVision hỗ trợ gỡ lỗi, mô phỏng.
Đối với các kỹ sư lập trình, kỹ sư kiểm thử, gỡ lỗi cho phần mềm nhúng thì họ
không chỉ phải hiểu các ngôn ngữ lập trình, hiểu phần mềm, mà còn phải hiểu cả phần
cứng của thiết bị mà mình lập trình hay gỡ lỗi. Đây là một khác biệt khá lớn trong
công việc lập trình giữa phần mềm nhúng và phần mềm ứng dụng thông thường.
LPC2148 cũng như các sản phẩm cùng họ ARM7TDMI-S được ứng dụng trong
nhiều lĩnh vực khác nhau. Chi tiết các thông số kỹ thuật của vi điều khiển sẽ được
trình bày ở phần phụ lục “Các thông số kỹ thuật của vi điều khiển LPC2148. ”
5.2. Chương trình “Đèn led nhấp nháy”
Mỗi kỹ sư lập trình khi bắt đầu một ngôn ngữ lập trình, một công cụ mới thì
Hello world luôn là chương trình đầu tiên được viết ra. Chương trình hiển thị dòng chữ
“Hello world” trên màn hình như một sự khởi đầu mới, là lời chào thân ái khi chúng ta
bắt đầu tiếp cận với một ngôn ngữ lập trình mới.
Đối với các kỹ sư lập trình phần mềm nhúng thì chương trình Hello world chính
là lập trình cho các đèn led nhấp nháy để báo hiệu rằng hệ thống của ta đang làm việc.
Mục đích của chương trình nhấp nháy led dưới đây là lập trình để các đèn led ở
các chân cắm 0, 2, 4, 6 trên GPIO Port 0 nhấp nháy:
Bảng 5.1: Mã lệnh của chương trình Led.c
/* Chuong trinh Led.c
** Muc dich: nhay cac led 0, 2, 4, 6 tren Port0 trong thoi gian 600000 micro giay
** Kiem tra cac led co hoat dong khong?
*/
#include"lpc214x.h"
/* Khai bao prototype ham lam tre thoi gian*/
41
void delay(unsigned long int);
/* Ham main co nhiem vu thuc thi cac chuong trinh chinh*/
int main()
{
IODIR0 = 0x00000055; // Dat GPIO pin 0, 2, 4, 6 = Output
IOSET0 = 0x00000055; // Set GPIO-1[24] Output Pin(OFF LED)
while(1)
{
IOCLR0 = 0x00000055; // Xoa Output GPIO1[24] Pin (ON LED)
delay(600000); // Delay
IOSET0 = 0x00000055; // Set Output GPIO1[24] Pin (OFF LED)
delay(600000); // Delay
}
}
/* Ham tre voi khoang thoi gian cho truoc time*/
void delay(unsigned long time)
{
while(time > 0)
{
time--;
}
}
Ý nghĩa của các giá trị, phép gán, hàm:
• IODIR0: bật các chân cắm 0, 2, 4, 6 của cổng Port 0, thiết lập trạng thái của các
chân cắm là trạng thái xuất (giá trị nhị phân tại các chân cắm là 1 – chân cắm ở
trạng thái xuất).
• IOSET0: đưa các chân cắm tương ứng bit = 1 trong thanh ghi lên mức cao khi
đã thiết lập trạng thái xuất.
• IOCLR0: đưa các chân cắm tương ứng bit = 1 trong thanh ghi xuống mức thấp
khi đã thiết lập trạng thái xuất.
• Hàm delay: hàm làm trễ thời gian giữa 2 lần nhấp nháy led với một khoảng thời
gian cho trước.
42
• Giá trị: 0x00000055 là giá trị theo cơ số 16, tương đương với giá trị
00000000000000000000000101010101 các giá trị tại bit 0, 2, 4, 6 là 1.
Thực hiện Translate (nhấn Ctrl + F7) để biên dịch chương trình, kiểm tra xem
chương trình có lỗi hay không? Sau đó Build (nhấn F7) để chương trình được biên
dịch lại, kết nối và tạo ra tập tin thực thi .hex. Nếu chương trình không có lỗi biên dịch
– các lỗi ngữ nghĩa (compiler error) thì chương trình mới có thể được gỡ lỗi, mô
phỏng.
Thực hiện gỡ lỗi cho chương trình bằng Debug (nhấn Ctrl + F5) để bắt đầu quá
trình gỡ lỗi và chạy chương trình mô phỏng bằng Run (F5).
Thông thường thì chương trình sẽ gọi ra ngay màn hình hiển thị của GPIO để cho
chúng ta thấy led đang nhấp nháy, nếu không thấy ta có thể vào thẻ Peripherals - GPIO
– Fast GPIO – Port 0 để bật hiển thị GPIO.
Sau khi chạy chương trình và gỡ lỗi, ta được kết quả như sau:
Hình 5.1. Kết quả thực thi chương trình Led.c
Chương trình đã mô phỏng cho sự nhấp nháy của led bằng việc nhấp nháy các
chân cắm 0, 2, 4, 6 của thanh ghi GPIO. Chương trình cũng cho thấy tốc độ nhấp nháy
của led nhanh hay chậm phụ thuộc vào thời gian làm trễ mà ta đã viết.
5.3. Chương trình Hello world
Ở chương trình trên, ta mô phỏng sự hoạt động của các các chân cắm trên cổng
để đèn led nhấp nháy. Chương trình tiếp theo là để minh họa cho việc sử dụng cổng
nối tiếp UART để ghi ra các chuỗi kí tự.
Chương trình thực hiện việc ghi ra cổng nối tiếp UART dòng chữ “Hello world”
và lặp lại 5 lần dòng chữ: “This is my embedded programming. ”:
43
Bảng 5.2: Mã lệnh Hello.c
/* Chuong trinh Hello.c thuc hien viec in ra man hinh cac dong chu Hello world.
* va 5 lan dong chu “This is my embedded programming. ”
*/
#include
#include /* Thu vien LPC214x.h */
/* Ham main thuc hien chuong trinh chinh */
int main () {
int count = 5; // Khai bao gia tri cua bien dem count = 5
// Cac khai bao cho cac chan cam, cong
PINSEL0 = 0x00050000; // Bat RXD1 và TXD1
U1LCR = 0x83; // Bat DLAB = 1, 8 bit. 1 stop bit
U1DLL = 97; // 9600 Baud Rate @ 15MHz VPB Clock
U1LCR = 0x03; // DLAB = 0
printf ("Hello World\n"); // In ra “Hello world”
// Ham in ra 5 lan dong chu “This is my embedded programming. ”
while (count > 0) {
printf("This is my embedded programming. \n");
count --;
}
// Ham lap vo han de dung chuong trinh
while (1) {;}
}
Ý nghĩa của các hàm, giá trị, phép gán:
• PINSEL0 có giá trị 0x00050000 tương đương với mã nhị phân có các bit 16 và
18 có giá trị bằng 1. Bit 16 trong PINSEL0 có giá trị bằng 1 tức là mở cổng
truyền dữ liệu TXD1 của UART1. Bit 18 trong PINSEL0 có giá trị bằng 1 là
mở cổng nhận dữ liệu RXD1 của UART1.
• Ở đây U1LCR có giá trị là 0x83 tương đương với mã nhị phân 1000 0011.
Trong đó bit 7 bằng 1 là bật DLAB lên, bit 2 bằng 0 là có 1 stop bit, bit 0 và 1
là 11 nên trạng thái là truy cập với độ dài 8 bit ký tự.
44
• U1DLL truy cập vào bộ khóa chia (Divisor Latch Access) của UART1. Giá trị
97 là để tính toán tốc độ baud của thiết bị.
• Giá trị của U1LCR là 0x03 là tắt DLAB (bit 7 đại diện cho DLAB chuyển về
mức 0).
• Vòng lặp while (count > 0) để chương trình in ra 5 lần dòng chữ “This is my
embedded programming. ”
• Vòng lặp while (1) là vòng lặp vô hạn, để chương trình dừng lại, không tiếp tục
thực hiện lại hàm main.
Để thực hiện việc in các ký tự ra cổng nối tiếp thì ta còn cần phải viết các hàm
phụ để thực hiện việc truyền nhận dữ liệu từ chương trình đến cổng nối tiếp UART1.
Sau khi biên dịch và thực hiện chương trình ta được kết quả như sau:
Hình 5.2. Kết quả thực thi chương trình Hello world
Chương trình của ta lập trình cho việc ghi ra cổng nối tiếp UART1, nhưng trong
hình thì cổng xuất ra các ký tự lại là cổng UART1. Điều này được giải thích như sau:
trong bộ gỡ lỗi của µVision các cổng nối tiếp UART được đánh số từ UART1, UART2
chứ không đánh số như trong thiết kế của LPC2148 là UART0, UART1. Vì vậy,
UART2 tương ứng với UART1 mà ta đã khai báo trong chương trình.
5.4. Nhận xét
Chương trình đèn led nhấp nháy và truyền các dữ liệu ra cổng nối tiếp UART là
hai chương trình đơn giản được viết bằng KeilC và được biên dịch, chạy, gỡ lỗi và mô
phỏng trong µVision.
Qua hai chương trình nhỏ này, chúng ta thấy µVision là một công cụ trực quan,
45
giúp cho người lập trình, ngay cả khi không có các thiết bị phần cứng thích hợp vẫn có
thể viết các ứng dụng của mình trực tiếp trên µVision IDE và sau đó chạy trên các thiết
bị phần cứng đã được mô phỏng và thực hiện các chức năng tương tự như với các vi
điều khiển thật sự.
Tuy nhiên, µVision chỉ là một công cụ mô phỏng, công cụ sẽ khó tránh khỏi việc
có một vài sai khác so với việc chạy trên các vi điều khiển thật, nhưng sai khác này
không quá lớn và ta vẫn có thể chấp nhận được.
46
CHƯƠNG 6: KẾT LUẬN
Các hệ thống nhúng được ứng dụng rộng rãi trong đời sống của chúng ta, và
chúng ngày càng phát triển vượt bậc cả về số lượng lẫn chất lượng. Việc gỡ lỗi cho các
hệ thống nhúng ngày càng trở lên quan trọng hơn do số lượng các hệ thống nhiều lên,
đòi hỏi của người dùng với sản phẩm cũng cao hơn, sản phẩm cần có được độ ổn định,
an toàn và chất lượng tốt.
Đáp ứng mục tiêu gỡ lỗi cho các hệ thống nhúng, sau một thời gian nghiên cứu
và học hỏi, khóa luận đã đạt được các kết quả sau:
• Khóa luận đã mang đến một cái nhìn tổng quát về hệ thống nhúng, trình bày
những đặc điểm của một hệ thống nhúng thông thường. Khóa luận cũng đã đưa
ra một số thông tin về các ngôn ngữ lập trình để các kỹ sư lập trình có thể lựa
chọn cho mình được ngôn ngữ lập trình thích hợp với hệ thống của mình.
• Khóa luận cũng đã đưa ra lý thuyết về các kỹ thuật gỡ lỗi cho hệ thống nhúng
bằng nhiều phương pháp khác nhau, từ kiểm thử cho máy chủ, đến sử dụng các
công cụ phần mềm, hay phần cứng để gỡ lỗi.
• Khóa luận giới thiệu công cụ mô phỏng µVision của công ty Keil là một công
cụ mô phỏng cho các họ vi xử lý ARM – một họ vi xử lý lớn, được ứng dụng
rộng rãi trong các thiết bị điện tử ngày nay.
• Phần ứng dụng kiểm thử cũng đã trình bày việc gỡ lỗi cho các chương trình viết
cho vi điều khiển LPC2148 phát triển trên nền tảng ARM của công ty Philips để
minh họa cho việc sử dụng công cụ µVision vào việc mô phỏng các vi điều
khiển.
Tuy nhiên do quỹ thời gian nghiên cứu hạn hẹp cũng như điều kiện kĩ thuật bị
giới hạn, khóa luận không tránh khỏi các hạn chế sau:
• Khóa luận chỉ mới dừng lại ở việc giới thiệu về hệ thống và các kỹ thuật gỡ lỗi
cho hệ thống và đưa ra được một công cụ mà theo chủ quan của chúng tôi là
một lựa chọn tốt cho các kỹ sư lập trình cho các thiết bị dựa trên nền tảng vi xử
lý ARM lập trình và gỡ lỗi cho các phần mềm khi mà phần cứng của thiết bị
chưa sẵn sàng hay không có sẵn.
• Các ứng dụng kiểm thử trong khóa luận là những chương trình đơn giản và
chưa thực sự khai thác được hết những ưu điểm của bộ công cụ µVision.
47
Gỡ lỗi và kiểm thử là một công việc hết sức thú vị, chúng tôi mong rằng sau này
mình có thể làm việc nhiều hơn với các hệ thống nhúng, để có thể ứng dụng nhiều hơn
những kiến thức đã học hỏi vào thực tế.
Việc gỡ lỗi giúp nâng cao chất lượng phần mềm, nhưng các phương pháp, các
công cụ chỉ là những thiết bị bổ trợ, cách hiệu quả nhất để giảm thiểu số lỗi trong phần
mềm là chính bản thân các kỹ sư lập trình cần viết chương trình sáng sủa, rõ ràng, và
kiểm soát các lỗi của họ. Điều này sẽ giúp cho công việc gỡ lỗi đỡ vất vả hơn rất
nhiều.
48
TÀI LIỆU THAM KHẢO
[1] Micheal Barr, Anthony Massa, Programming Embedded Systems: with C and GNU
Development tools, 2nd Edition, O'Reilly Media, October 1, 2006 (2nd Edition).
[2] Jack Ganssle, Micheal Barr, Embedded System Dictionary, CMP Books, 2003.
[3] Tammy Noergaard, Embedded System Architecture: A Comprehensive Guide for
Engineers and Programmers, Newnes, February 24, 2005, page 129.
[4] David .E Simon, An Embedded Software Primer, Addison – Wesley Professional,
August 15, 1999, chapter 1, 10.
[5] Keil ARM, µVision IDE Overview, 2010.
[6] Keil ARM, Advantages of the µVision IDE for ARM,
2010.
[7] Keil ARM, Advantages of the µVision Simulator for ARM,
2010.
[8] Keil ARM, Getting Started Creating Applications with µVision 4, 2010.
[9] Keil ARM, Limitions, 2010.
[10] Wikipedia, ARM Architechture,
2010.
[11] AWRCorp, Example: Downconverter,
https://awrcorp.com/download/faq/english/examples/Downconverter.aspx, 2009.
[12] Link Instruments, IO-3200 Logic Analyzer Pattern Generator,
2010.
[13] Agilent, Logic Analyzer,
2010.
[14] Wikipedia, Oscilloscope, 2010.
[15] ARM, Processors, 2010.
.
49
PHỤ LỤC
CÁC THÔNG SỐ KỸ THUẬT CỦA VI ĐIỀU KHIỂN LPC2148
1. Một số đặc điểm chính của vi điều khiển LPC2148
LPC2148 là vi điều khiển 16/32 bit, dựa trên cấu trúc ARM7TDMI-S.
Bộ nhớ SRAM trên chip là 8 – 40 kB, bộ nhớ chương trình flash là từ 32 – 512
KB.
Có 64 chân cắm, 45 chân GPIO.
Tích hợp USB 2.0, hỗ trợ USB RAM tới 2 KB.
Có 14 kênh ADC 10 - bit, và 1 kênh DAC 10 – bit. Có 2 bộ timer 32 – bit, 6
ngõ điều xung.
Đồng hồ thời gian thực với tần số ngõ vào 32 kHz.
Khả năng thiết lập độ ưu tiên, định địa chỉ cho ngắt.
Có nhiều giao diện cổng nối tiếp gồm: 2 cổng nối tiếp UART, 2 bus Fast I2C
(400 kbit/s), SPI và SSP.
Trạng thái tiết kiệm điện: chế độ không tải và ngắt nguồn.
Có 9 chân ngắt ngoài.
CPU clock đạt tối đa 60 MHz thông qua bộ PLL lập trình được.
Xung PLCK hoạt động độc lập.
2. Đặc điểm một số thanh ghi
2.1. Các cổng nhập/ xuất thông thường (GPIO)
LPC2148 có 2 cổng là Port0 và Port1:
Port0 (GPIO0): PO.0 – PO.23, PO.25, PO.28 – PO.30: là các chân nhập/ xuất
thông thường. PO.31 là chân chỉ xuất. Các chân PO.24, PO.26, PO.27 không
được xét.
Port1 (GPIO1): P1.16 – P1.31 là các chân nhập/ xuất thông thường, các chân
còn lại không được xét.
Có thể truy cập các cổng theo hai cách: “slow” GPIO và “fast” GPIO. Việc truy
50
cập này được khai báo thông qua thanh ghi SCS (System Control and Status
flag register – Thanh ghi cờ điều khiển hệ thống và trạng thái).
Bảng 1 : Các giá trị của thanh ghi SCS
Bit Ký hiệu Ý nghĩa Giá trị sau khi reset
0 GPIO0M Bit chọn mode port 0
0: slow 1: fast
0
1 GPIO1M Bit chọn mode port 1
0: slow 1: fast
0
31:02 - Không hỗ trợ Không xác định
Các thanh ghi chức năng của GPIO:
Bảng 2: Bảng giá trị các thanh ghi GPIO
ST
T
Tên thanh
ghi
Bit Ý nghĩa Truy
cập
Giá trị sau
khi reset
1 IODIR 31:01 Bit 0 tương ứng với P0.0...
0: chân tương ứng là nhập
1: chân tương ứng là xuất
Đọc/ Ghi 0x00000000
2 IOSET 31:01 Bit 0: không xảy ra hiệu ứng
Bit 1: chân tương ứng được set
bằng 1
Đọc/ Ghi 0x00000000
3 IOCLR 31:01 Bit 0: không xảy ra hiệu ứng
Bit 1: chân tương ứng được set
bằng 0
Chỉ đọc 0x00000000
4 IOPIN 31:01 Trạng thái của port 0 luôn được
đọc trong thanh ghi này, việc ghi
vào IO0PIN sẽ ảnh hưởng tới toàn
bộ port 0
Đọc/ Ghi Không xác
định
5 FIODIR 31:01 Bit 0 tương ứng với P0.0...
0: chân tương ứng là nhập
1: chân tương ứng là xuất
Đọc/ Ghi 0x00000000
6 FIOMASK 31:01 Quản lý các chân theo tập hợp các
bit có giá trị 0 trong FIOMASK.
Đọc/ Ghi 0x00000000
7 FIOPIN 31:01 Tương tự IOPIN, nhưng chỉ có tác
dụng với các chân được định nghĩa
trong FIOMASK.
Đọc/ Ghi 0x00000000
8 FIOSET 31:01 Tương tự IOSET, nhưng chỉ có tác Đọc/ Ghi 0x00000000
51
ST
T
Tên thanh
ghi
Bit Ý nghĩa Truy
cập
Giá trị sau
khi reset
dụng với các chân được định nghĩa
trong FIOMASK.
9 FIOCLR 31:01 Tương tự IOCLR, nhưng chỉ có tác
dụng với các chân được định nghĩa
trong FIOMASK.
Đọc/ Ghi 0x00000000
2.2 Khối kết nối giữa các chân (Pin Connect Block)
Mục đích chính của khối kết nối giữa các chân là để cấu hình cho các chân của
vi điều khiển để thực hiện một mục đích cụ thể.
LPC2148 có 3 thanh ghi PINSEL (Pin function Select register) để cấu hình cho
các chân cắm là: PINSEL0, PINSEL1, PINSEL2.
Bảng 3: Bảng các giá trị bit của thanh ghi PINSEL0
Bit Ký hiệu Giá trị Chức năng Giá trị sau
khi reset
1:0 P0.0 00 GPIO Port 0.0 0
01 TXD (UART0)
10 PWM1
11
3:2 P0.1 00 GPIO Port 0.1 0
01 RXD (UART0)
10 PWM3
11 EINT0
5:4 P0.2 00 GPIO Port 0.2 0
01 SCL0 (I2 C0)
10 Capture 0.0 (Timer 0)
11
7:6 P0.3 00 GPIO Port 0.3 0
01 SDA0 (I2 C0)
10 Match 0.0 (Timer 0)
11 EINT1
52
Bit Ký hiệu Giá trị Chức năng Giá trị sau
khi reset
9:8 P0.4 00 GPIO Port 0.4 0
01 SCK0 (SPI0)
10 Capture 0.1 (Timer 0)
11 AD0.6
11:10 P0.5 00 GPIO Port 0.5 0
01 MISO0 (SPI0)
10 Match 0.1 (Timer 0)
11 AD0.7
13:12 P0.6 00 GPIO Port 0.6 0
01 MOSI0 (SPI0)
10 Capture 0.2 ( Timer 0)
11 AD1.0
15:14 P0.7 00 GPIO Port 0.7 0
01 SSEL0 (SPIO)
10 PWM2
11 EINT2
17:16 P0.8 00 GPIO Port 0.8 0
01 TXD (UART1)
10 PWM4
11 AD1.1
19:18 P0.9 00 GPIO Port 0.9 0
01 RXD (UART1)
10 PWM6
11 EINT3
21:20 P0.10 00 GPIO Port0.10 0
01 RST (UART1)
10 Capture 1.0 (Timer 1)
11 AD1.2
23:22 P0.11 00 GPIO Port 0.11 0
01 CTS (UART1)
53
Bit Ký hiệu Giá trị Chức năng Giá trị sau
khi reset
10 Capture 1.1 (Timer 1)
11 SCL1 (I2C1)
25:24 P0.12 00 GPIO 0.12 0
01 DSR (UART1)
10 Match 1.0 (Timer 1)
11 AD1.3
27:26 P0.13 00 GPIO Port 0.13 0
01 DTR (UART1)
10 Match 1.1 (Timer1)
11 AD1.4
29:28 P0.14 00 GPIO Port 0.14 0
01 DCD (UART1)
10 EINT1
11 SDA1(I2C1)
31:30 P0.15 00 GPIO Port 0.15 0
01 RI (UART1)
10 EINT2
11 AD1.5
Trên đây là bảng các giá trị bit của thanh ghi PINSEL0, với các thanh ghi
PINSEL1, và PINSEL2 cũng tương tự, chỉ có một vài khác biệt mà ta không xét
tới ở đây.
2.3 Bộ nhận truyền bất đối xứng (UART – Universal Assynchronous Receiver/
Transmitter)
LPC2148 hỗ trợ 2 bộ UART là UART0 và UART1. Các thanh ghi này có chức
năng: nhận và truyền nối tiếp 16 byte; nhận các điểm ràng buộc FIFO ở byte thứ 1, 4,
8, và 14; tạo ra tốc độ baud với khả tăng tạo baud tự động; cài đặt để điều khiển các
luồng.
UART có các chân cắm là :
• RXDx: nhận dữ liệu trên cổng nối tiếp.
54
• TXDx: truyền dữ liệu trên cổng nối tiếp.
Bảng các thanh ghi của UART1:
Ở đây ta quan tâm tới hai thanh ghi là U1LCR và U1DLL.
• U1LCR (Line control Register – Thanh ghi điều khiển dòng) quyết định dạng
ký tự của dữ liệu được truyền hay nhận:
Bảng 4: Bảng giá trị bit của U1LCR
Bit Kí hiệu Giá
trị
Ý nghĩa Giá trị sau
khi reset
1:0 Lựa chọn độ
dài từ
00
01
10
11
Độ dài của ký tự là 5 bit.
Độ dài ký tự là 6 bit.
Độ dài ký tự là 7 bit.
Độ dài ký tự là 8 bit.
0
2 Lựa chọn bit
dừng
0
1
1 bit dừng.
2 bit dừng (bằng 1,5 nếu U1LCR[1:0] = 00).
0
3 Có chẵn lẻ 0
1
Không kiểm tra tính chẵn lẻ.
Kiểm tra tính chẵn lẻ.
0
5:4 Lựa chọn
kiểm tra chăn
lẽ
00
01
10
11
Bù lẻ. Số bit 1 trên đường truyền phải là lẻ.
Bù chẵn.Số bit 1 trên đường truyển phải
chẵn.
Thêm 1.
Thêm 0.
0
6 Điều khiển
dừng
0
1
Không cho phép dừng.
Cho phép dừng.
0
7 Bit truy cập
tới bộ phân
chia DLAB
0
1
Không được phép truy cập tới bộ phân chia.
Được phép truy cập.
0
U1DLL là để chứa dữ liệu 8 bit khi mà DLAB của thanh ghi U1LCR được
bật lên, cùng với U1DLM nó sẽ quyết định tốc độ baud của UART1.
Công thức tính tốc độ baud của UART1 là:
UART1baudrate=
PCLK
16∗256∗U1DLMU1DLL
∗ MulVal
MulValDivAddVal
Trong đó:
UART1baudrate : Tốc độ baud của UART1.
55
U1DLM, U1DLL đã cho.
PCLK (peripheral clock - tốc độ của ngoại vi) đã cho.
DIVADDVAL và MULVAL là tỷ số baud đặc trưng của thiết bị, nó thường được
cho trước.
Thanh ghi UART0 cũng có các chức năng tương tự thanh ghi UART1.
3. Nhận xét
Vì điều kiện thời gian không cho phép, nên khóa luận không trình bày hết tất
các thông số kỹ thuật của vi điều khiển LPC2148 mà khóa luận chỉ tập trung
đưa ra những thông số kỹ thuật cần thiết, liên quan đến phần ứng dụng của khóa
luận. Tất cả các thông số kỹ thuật của vi điều khiển LPC2148 có thể được tìm
thấy trong trang chủ của nhà sản xuất NXP (Philips).
56
Các file đính kèm theo tài liệu này:
- LUẬN VĂ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.pdf