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

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.

pdf65 trang | Chia sẻ: lylyngoc | Lượt xem: 2896 | Lượt tải: 0download
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∗U1DLMU1DLL ∗ MulVal MulValDivAddVal 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:

  • pdfLUẬ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