Phỏt triển phần mềm cho HTN

Một phần của tài liệu Bài giảng Xây dựng các hệ thống nhúng: Phần 2 (Trang 109 - 115)

Chương 4 THIẾT KẾ VÀ CÀI ĐẶT CÁC HỆ THỐNG NHÚNG

4.2.4Phỏt triển phần mềm cho HTN

Cú nhiều cỏch để viết mó (coding) cho HTN, mà sự lựa chọn phụ thuộc và tớnh phức tạp của phần mềm nhỳng, và chi phớ. Vớ dụ như coding cho phần cứng đó được xõy dựng (mua bo mạch cú sẳn) thỡ dễ dàng hơn là cho một thiết kế độc lập, tự làm. Ngày nay cũng cú thể là theo cỏch sử dụng nhiều phần mềm mở (bao gồm mó nguồn dạng C, thư viện đi cựng và cụng cụ phỏt triển), tải xuống, gỡ rối (debugging code), sửa đổi cho phự hợp, biờn dịch … và nạp vào HTN. Cũn phỏt triển kiểu truyền thống lại tiếp cận theo hướng CPU đó chọn và phần mềm mụ phỏng (emulator). Bộ mụ phỏng cú thể dựng để gỡ rối phần cứng trờn bo của sản phẩm thử nghiệm (prototype hardware) trước khi giao cho giỳp kỉ sư phần mềm triển khai phần mềm nhỳng đớch. Bộ mụ phỏng được cài trờn một hệ khỏc, gọi là hệ phỏt triển (development system), vớ dụ trờn PC. Một số bo mạch thương mại thường cú kốm theo mó gỡ rối, là tiện ớch giỳp kỉ sư phần mềm chạy thử phần mềm viết ra. Sau đõy đề cập tới một số vấn đề cú thể phải đối mặt khi muốn sử dụng cỏc phần mềm cú sẳn cho HTN đớch được thiết kế.

ỹ Compiling code

Khi sử dụng cỏc ngụn ngữ bậc cao để lập trỡnh, ta khụng quan tõm tới cỏc bước quỏ trỡnh dịch để tạo ra mó thực thi. Việc biờn dịch cần chương trỡnh dịch thớch hợp, cần tới cả thư viện chạy liờn kết (run-time libraries) và cả trỡnh liờn kết để hợp nhất cỏc module thành tệp thực thi cuối cựng. Vấn đề ở đõy là sự hợp nhất với hệ thống dựng để phỏt triển (hệ phỏt triển-development system) phần mềm cho HTN, mà hệ này cú thể mụ phỏng được HTN đớch tương lai. Phương phỏp phỏt triển như vậy, gọi là biờn dịch chộo (cross-compilation+emulation), taị đú phần mềm cho một hệ đớch khỏc được phỏt triển toàn bộ trờn một hệ hoàn toàn khỏc. Vớ dụ dựng PC trờn đú cú cài phần mềm phỏt triển hướng cho loại HTN đớch, mà thụng thường cỏc hóng bỏn CPU cú thể cung cấp.

Hầu hết cỏc trỡnh dịch, cho C, hay PASCAL, …, đều chỉ phỏt sinh ra một tập cỏc tiện ớch, cỏc lệnh từ cỏc thành phần xõy dựng bờn trong (built-in routines) liờn kết với thư viện của ngụn

248

ngữ để cuối cựng tạo ra cỏc hàm chức năng. Quỏ trỡnh dẫn tới kết quả trải qua vài bước nhất định, được mụ tả như sau:

Hỡnh 4.14 Quỏ trỡnh biờn dịch thành mó maý tạo ra HĐH

Pre-processor: tiền xử lớ, thường gọi là biờn dịch, xử lớ mó nguồn, với chức năng kiểm tra cỳ phỏp, khai bỏo biến, hằng, bắt lỗi cỳ phỏp, phối hợp cỏc tệp include, define vào code nguồn.

Compiler: dịch từ ngụn ngữ lập trỡnh ra ngụn ngữ hợp ngữ - assembler source listing (*. list tệp kết quả từ mó nguồn *.asm). Quỏ trỡnh này đồng thời thực hiện tối ưu code để sau này chương trỡnh chạy nhanh hơn, sử dụng bộ nhớ hợp lớ hơn.

Assembler: dịch từ hợp ngữ ra mó đớch (của CPU đớch) nhị phõn (tệp kết quả: *.obj hay *.o)

Linker/Loader: cỏc tệp *.obj chưa thể chạy được, mà cần cú linker/loader để kết hợp cỏc mó hàm gọi, từ thư viện, liờn kết nhiều module, liờn kết cỏc hàm cú sẳn trong thư viện, tạo ra tệp thực thi phự hợp cho từng loại Hệ điều hành đớch, gọi là tệp cú định dạng kiểu ELF (Executable and

249

Linkable Format) vớ dụ HĐH Microsoft: *.com hay *.exe, HĐH Linux cú kiểu FatELF khả thi với thuộc tớnh r-x r-x r-x.

Mụ hỡnh của tệp elf như sau:

Hỡnh 4.15 Định dạng một tệp thực thi ELF

Trong đú khối ELF header cho biết khụng gian địa chỉ sử dụng của CPU là 32 hay 64 bit. Khi kết hợp với Program header table tạo chung thành khối PSP (Program Segment Prefix) trong mụi trường HĐH Microsoft, cho đặc tả về trạng thỏi hoạt động của một chương trỡnh khi chạy.

Cỏc khối khỏc .text (hay .code) chứa code thực thi, .data chứa dữ liệu (gồm cỏc biến, cỏc hằng, bảng …), .rodata (hay .stack) là vựng ngăn xếp.

ỹ Thư viện cỏc hàm chức năng chạy khi kớch hoạt (Run-time libraries)

Vấn đề đầu tiờn cho việc thiết kế HTN là cú thư viện cỏc chức năng mà chương trỡnh

dịch sử dụng để kớch hoạt một số cỏc thực thi khi hệ chạy ứng dụng. Việc thực hiện lời gọi thư viện (system call) bằng API (Application Programming Interface), tỏc động tới sự liờn lạc giữa ứng dụng và phần mềm hệ thống đang chạy (runtime system), trong đú liờn quan nhiều tới cơ chế vào ra (input/output) và quản lớ bộ nhớ của mỏy tớnh. Núi đơn giản run- time library chớnh là một phần của cỏch xử lớ hay sự phản ứng của mỏy tớnh, tức là một phần code của phần mềm hệ thống. Như vậy thư viện cho ta hầu như tất cả cỏc chức năng mà qua ngụn ngữ lập trỡnh ta cú để sử dụng. Tất nhiờn thư viện bao gồm nhiều kiểu chức năng, phụ thuộc vào phần cứng của HTN. Điều này thỡ khụng cú sẳn khi thiết kế HTN (cả phần cứng và phần mềm ), cho nờn phải biến đổi để làm cho cỏc chức năng đú chạy được trờn HTN đớch. Cỏc trỡnh điều khiển thiết bị là một vớ dụ.

250

Sự phụ thuộc vào bộ xử lớ (Processor dependent)

Sử dụng cỏc thư viện từ ngụn ngữ lập trỡnh bậc cao thụng thường sẽ cú đũi hỏi chạy cỏc hàm toỏn học, cỏc xử lớ xõu kớ tự … mà cỏc xử lớ đú hoàn toàn sử dụng CPU, khụng cú liờn lạc với thiết bị, vỡ vậy thư viện cỏc chức năng này khụng cần cú sửa đổi. Tuy nhiờn với cỏc phộp tớnh dấu phẩy động thỡ khỏc, bởi cần vi mạch chuyờn về cỏc phộp tớnh này. Cỏc vi mạch như vậy thường là tựy chọn với loại CPU, vớ như CPU Intel 80386 trước đõy cú 80387 là bộ số học dấu phẩy động. Núi vậy để thấy khi chọn CPU cho HTN cũng phải lưu ý cần hay khụng cần bộ số học loại này. Điều này sẽ phụ thuộc vào ứng dụng trờn HTN.

Phụ thuộc vào cỏc thao tỏc vào/ra dữ liệu (I/O dependent)

Nếu chương trỡnh khụng cú cỏc thao tỏc vào/ra dữ liệu, thỡ phần mềm cú thể dựng trờn cỏc hệ đớch mà hầu như khụng cú cỏc trục trặc. Tuy nhiờn nếu cú vào/ra, thỡ phải cú định nghĩa phần cứng để phần mềm truy nhập. Núi vaajty tức phải viết lại trỡnh điều khiển thiết bị cho hệ đớch.

Gọi hệ thống (System calls)

Cỏc thủ tục gọi chức năng cũng cần sửa đổi để phự hợp với hệ đớch, sao cho phự hợp với cơ chế xử lớ cỏc semaphore, cỏch phõn phỏt bộ nhớ, cỏch xử lớ tỏc vụ, cỏc lệnh điều khiển.

Thoỏt ra từ chu trỡnh, thủ tục (Exit routines):viết đoạn code thoỏt

Cỏc phần mềm tải về sử dụng, sau khi dịch thành tệp thực thi khụng dễ dàng nạp và chạy trong bộ nhớ. Đú là vỡ cũn cú cỏc tệp chứa cỏc module khỏc, như cỏc tệp kốm theo (modulr header) mà hệ điều hành trờn HTN sẽ sử dụng để nạp tệp thực thi vào đỳng địa chỉ, khởi động chớnh xỏc cỏc thanh ghi của CPU, ngăn xếp chạy trỡnh …Tất cả cỏc việc này cần sửa đổi và chạy mụ phỏng trước khi chạy trờn HTN đớch. Cỏc thủ tục (start-up routine, end routine) thỡ thường viết mó (nằm) trong cỏc module. Kết thỳc thực thi cỏc chu trỡnh thường dựng lệnh exit(). Code của lệnh này sẽ thực hiện thu hồi bộ nhớ trả lại cho HĐH, cho nờn cũng cần phải viết lại, cú điều mó này lại thường nằm trong thư viện động.

Tạo thư viện

Làm thế nào tạo ra cỏc tệp thư viện phự hợp với CPU đớch trờn HTN thiết kế thay thế cỏc tệp thư viện từ mó nguồn tải về ? Cú hai giải phỏp: thứ nhất là thay thiết kế trong phần cứng sao cho phần cứng phự hợp với code trong thư viện. Cú thể đơn giản là thay đổi ỏnh xạ địa chỉ cho cỏc hàm thư viện hay cổng (port) sao cho cỏc địa chỉ hướng vào là trựng với cỏc địa chỉ trong code của thư viện. nếu cú dựng cơ chế I/O, thỡ địa chỉ mà I/O sử dụng phải giống như đó định nghĩa trong thư viện sao cho phần mềm truy cập đỳng. Cỏch thứ hai là phải sửa code thư viện sao cho hợp với phần cứng của thiết kế. Điều này cú nghĩa sẽ thay đổi cỏch phõn bố sử dụng bộ nhớ, cổng I/O và cụ thể là sẽ sử cả TĐKTB (device driver) nếu cú thiết bị mới khỏc biệt mà HTN sử dụng, đụi khi cả cho CPU khỏc biệt. cỏch này phụ thuộc nhiều vào thư viện đi kốm, cú thể là trong dạng hợp ngữ, hay C và dễ dàng để biến đổi và liờn kết thành thư viện mới. Thường cỏc code này bao gồm: (adsbygoogle = window.adsbygoogle || []).push({});

251

đầu vào, cho phộp truyền dữ liệu vào thủ tục xử lớ và đầu ra chuyển sang thủ tục khỏc. Trường hợp phức tạp là khi thư viện ở dạng đó dịch thành nhị phõn (*.obj) .

Tạo thư viện (Creating a library): Cần cú kinh nhiệm lập trỡnh khi viết cỏc mó dạng như TĐKTB (thường gọi là lập trỡnh hệ thống). Viết code cho TĐKTB tạo thư viện chạy thường khụng cú hạn chế nào cho HĐH, cũng như để thay thế cỏc chức năng I/O. Kỉ thuật này sử dụng để viết code cho một thiết bị ảo (theo cỏch phõn loại ở chương TĐKTB) hổ trợ cỏc ngụn ngữ cấp cao truy nhập vào phần cứng cấp thấp mà khụng cần chốn đoạn code hợp ngữ đặc biệt. Khi chuyển sang hệ đớch khỏc, thiết bị ảo thay đổi, chỉ cần biện dịch lại và liờn kết (link) vào mó cho hệ đớch mới.

Nhiều nhà cung cấp bo mạch thường cung cấp thụng tin về cấu trỳc phần cứng, và chương trỡnh gỡ rối (debuger) với cỏc lệnh I/O đi kốm, giỳp tham khảo phần cứng bằng cỏch chạy debug. Việc này rất bổ ớch để viết lại thư viện cho hệ đớch.

Khi đó viết xong thư viện, cụng việc tiếp theo là đưa vào chương trỡnh ứng dụng. Việc này thụng qua tiện ớch liờn kết (linker): Chương trỡnh và cỏc thủ tục dạng hợp ngữ được dịch, hợp vào thành cỏc module OBJ và sau đú được liờn kết lại bởi linker để tạo ra mó thực thi cuối cựng. Thư viện mới được tớch hợp bởi cỏc kỉ thuật: liờn kết thờm thư viện (gồm thư viện chuẩn và thư viện mới), hay liờn kết bằng thay thư viện mới, bỏ thu viện trựng như khụng cũn sử dụng ở hệ đớch.

Vấn đề với hệ điều hành

Trong nhiều trường hợp, HĐH là khụng cú sẳn cho bo mạch HTN đó thiết kế, mờm cần phải “tạo” HĐH theo yờu cầu. Cú một số giải phỏp sau đõy:

- Nếu mua bo mạch HTN, cú thể mua luụn phần mềm hệ thống đó được cấu hỡnh cho bo đú. Trờn thị trường cú nhiều bo mạch HTN phổ biến và đi kốm là danh sỏch cỏc HĐH, phần mềm đó được chuyển tải vào bo. Trong trường hợp này chi phớ cho dự ỏn HTN sẽ giảm đi vỡ rằng cỏc phần cứng và phần mềm đó được thử nghiệm.

- Tạo ra nhõn HĐH mới cho cấu hỡnh (HW) mới: Khi khụng thể dựng cỏc HĐH chuẩn trờn thị trường và cần nhiều thay đổi cho hợp với cấu hỡnh thiết kế, thỡ cần tạo mới HĐH (rebuilding the operating system or kernel). Thụng thường từ mó nguồn, chọn cỏc module (đó cú thay đổi code), và biệ dịch, liờn kết lại để tạo ra nhõn với phiờn bản HĐH mới. Một trong cỏc HĐH dễ thực hiện sẳn cú là HĐH Linux, vớ dụ với RED HAT 9.0 cài trờn mỏy đầy đủ với mó HĐH, sau đú dựng tiện ớch make xconfig đi kốm chọn cỏc module phự hợp, biện dịch lại nhõn, tạo và chạy với phiờn bản mới, trước khi nạp cho HTN thiết kế. (Xem

http://redhat.activeventure.com/9/customizationguide/s1-custom-kernel- modularized.html).

(Building a Custom Kernel from Linux RED HAT source code)

The instructions in this section apply to building a custom modularized kernel. To build a monolithic kernel instead, see Section A.3 Building a

252

Monolithic Kernel for an explanation of the different aspects of building and installing a monolithic kernel.

Note

This example uses 2.4.20-2.47.1 as the kernel version (the kernel version might differ). To determine the kernel version, type the command uname -r and replace 2.4.20-2.47.1 with the kernel version that is returned.

To build a custom kernel for the x86 architecture (perform all these steps as root):

1. Open a shell prompt and change to the directory /usr/src/linux-2.4/. All commands from this point forward must be executed from this directory. 2. It is important that kernel build starts with the source tree in a known condition. Therefore, it is recommended that the command make mrproper is issued first to remove any configuration files along with the remains of any previous builds that may be scattered around the source tree. If an existing configuration file already exists as the file /usr/src/linux-2.4/.config, back it up to a different directory before running this command and copy it back afterward.

3. It is recommended that the configuration of the default Red Hat Linux kernel be used as a starting point. To do this, copy the configuration file for the system's architecture from the /usr/src/linux-2.4/configs/ directory to /usr/src/linux-2.4/.config. If the system has more than four gigabytes of memory, copy the file that contains the keyword bigmem.

4. Next, customize the settings. If the X Window System is available, the recommended method is to use the command make xconfig to run the Linux

Kernel Configuration. Note

To use the graphical tool started with the

# make xconfig

command, the tk package, which provides the wish command, must be installed. For more information on installing RPM packages, refer to Part

253

5. As shown in windows, select a category to configure by clicking on it. Within each category are components. Select y (yes), m (module), or n (no) beside the component to compile it into the kernel, compile it as a kernel module, or not compile it. To learn more about the component, click the Help button beside it.

6. Click Main Menu to return to the categories list.

7. After finishing the configuration, click the Save and Exit button in the main menu window to create the configuration file /usr/src/linux-2.4/.config and exit the Linux Kernel Configuration program.

8. Even if no changes were made to any of the settings, running the make xconfig command (or one of the other methods for kernel configuration) is required before continuing.

(adsbygoogle = window.adsbygoogle || []).push({});

Một phần của tài liệu Bài giảng Xây dựng các hệ thống nhúng: Phần 2 (Trang 109 - 115)