API and HAL Fundamentals (Phần 1)

“Software is a great combination between artistry and engineering.”

—Bill Gates

1. The Wonderful World of HALs

Có nhiều công cụ mà các nhà phát triển phần mềm nhúng có thể sử dụng để phát triển phần mềm một cách nhất quán, nhưng công cụ tốt nhất hiện nay có thể cải thiện khả năng tái sử dụng (reuse) và tính di động (portability) của code là API và HAL. Thiết kế một HAL là bước đầu tiên tuyệt vời để phát triển firmware có thể tái sử dụng và độc lập với phần cứng (hardware). HAL hoặc Lớp Trừu Tượng Phần Cứng (Hardware Abstraction Layer), cung cấp cho nhà phát triển ứng dụng (application developer) một tập hàm tiêu chuẩn để truy cập các chức năng phần cứng mà không cần hiểu chi tiết về cách hoạt động của phần cứng bên dưới. HAL không phải là trí thông minh nhân tạo khét tiếng trong phim 2001: A Space Odyssey. HAL về cơ bản là các API được thiết kế để tương tác với phần cứng chứ không phải để cung cấp các khối chương trình cấp cao (high-level program block) giúp phát triển ứng dụng dễ dàng. Một HAL được thiết kế phù hợp cung cấp nhiều lợi ích cho các nhà phát triển, chẳng hạn như code có thể port, có thể tái sử dụng, chi phí thấp hơn, trừu tượng hóa và có ít lỗi tiềm ẩn hơn. Một HAL được thiết kế kém có thể dẫn đến tăng chi phí, lỗi phần mềm và có thể là cơn ác mộng của developer.

2. APIs Versus HALs

Trước đây, các embedded-software developer rất kém trong việc develop phần mềm mà có thể tái sử dụng và port dễ dàng. Nguyên nhân không hẳn là do lỗi của developer mà gốc rễ thực tế là phần cứng rất hạn chế về tài nguyên, code được biên dịch không hiệu quả, và áp lực từ dự án dẫn đến việc develop phần mềm một cách vội vàng. Vì những lý do này, hầu hết các dự án phần mềm nhúng đều bắt đầu với một phương tiện chặn sạch với ít mã được sử dụng lại.

Một rào cản lớn nhất đối với việc tạo ra phần mềm có thể tái sử dụng (reusable software) chính là công nghệ mà các developer đang sử dụng, cùng với bản thân bộ vi điều khiển (microcontroller) cũng là một thủ phạm lớn. Hai lí do chính bỏ qua API và HAL là vì chúng có thể làm tăng thêm một chút chi phí cho các lệnh gọi hàm (function call) và không gian mã (code space) bị tăng thêm một ít. Khi bộ nhớ flash còn đắt tiền, một đoạn code nhỏ cũng có thể khiến chi phí phần cứng tăng lên đáng kể. Developer cũng coi việc sử dụng HAL là một điều lãng phí vì sự thay đổi trong chức năng, bố cục thanh ghi cấp thấp và memory map làm cho việc tái sử dụng dường như rất khó khăn.

Nhu cầu phát triển phần mềm nhúng trong thế kỷ XXI đang thúc đẩy những thay đổi lớn đối với cách phát triển phần mềm. Năng lực phần cứng đã tăng lên ngoạn mục trong khi chi phí giảm đáng kể. Chi phí lớn của dự án không còn đặt nặng ở thiết kế và sản xuất phần cứng, thay vào đó là phát triển phần mềm. Những yếu tố này đang thúc đẩy nhu cầu tái sử dụng phần mềm nhúng.

Có thể dễ dàng phát triển phần mềm nhúng để tái sử dụng từ ứng dụng này sang ứng dụng khác và thậm chí từ vi điều khiển 8-bit sang vi điều khiển 32-bit. Các nhà khoa học máy tính đã giải quyết vấn đề port hoặc reuse phần mềm từ nhiều thập kỷ trước. Các lập trình viên máy tính để bàn (desktop programmer) đã tận dụng các framework và component kể từ buổi bình minh của máy tính cá nhân (nếu không muốn nói là sớm hơn). Một trong những công cụ quan trọng nhất mà các nhà phát triển hệ thống nhúng (embedded-system developer) có xu hướng bỏ qua là sử dụng API hoặc HAL.

API là Giao Diện Lập Trình Ứng Dụng (Application Programming Interface) định nghĩa một tập hợp các quy trình (routine), giao thức (protocol) và công cụ (tool) để tạo ứng dụng.1 Một API xác định giao diện cấp cao về hành vi và khả năng của component, các input và output của nó. Một API nên được tạo có tính chung (generic) và độc lập với việc triển khai. Điều này cho phép API sử dụng được trong nhiều ứng dụng và các thay đổi chỉ cần làm ở API chứ không phải đụng tới giao diện chung hoặc hành vi chung.

HAL là một Lớp Trừu Tượng Phần Cứng (Hardware Abstraction Layer) xác định một tập hợp các routine, protocol và tool để tương tác với phần cứng. Một HAL tập trung vào việc tạo ra các hàm trừu tượng, cấp cao, được sử dụng để phần cứng thực hiện một việc gì đó mà không yêu cầu phải có kiến thức chi tiết về cách phần cứng đó vận hành như thế nào. HAL có thể cực kỳ hữu ích cho developer nào làm việc với nhiều loại phần cứng vi điều khiển và cần port các ứng dụng từ platform này sang platform tiếp theo.

API và HAL đều liên quan với nhau. Có thể lập luận rằng chúng làm việc gần giống nhau. Chỗ khác biệt là API được thiết kế để cho phần mềm ứng dụng (application software) dễ xài hơn, trong khi HAL được thiết kế để cho việc tương tác với phần cứng cấp thấp (low-level hardware) đơn giản hơn. Một hệ thống nhúng được thiết kế tốt sẽ gồm có một HAL để tương tác với phần cứng cấp thấp và một API tương tác với HAL, để tạo ra một tập các API giúp đơn giản hóa việc phát triển ứng dụng.

3. The API and HAL Landscape

Khi năng lực bộ vi xử lý tăng lên trong những năm gần đây thì những kỹ thuật chuyên môn cần thiết, thời gian để tìm hiểu và chạy bộ vi điều khiển cũng tăng lên nhanh chóng. Cài đặt một UART đơn giản có thể tốn nhiều ngày vì người ta cần phải đọc qua hàng nghìn trang tài liệu kỹ thuật để tìm ra chính xác thanh ghi (register) và bit nào cần được thao tác để thiết lập giao tiếp nối tiếp (serial communication) cơ bản với một hệ thống nhúng. Cung cấp HAL và API tạo nên một lợi thế khổng lồ cho các nhóm phát triển đang chịu nhiều áp lực từ việc phải ra mắt sản phẩm nhanh hơn với chi phí thấp hơn.

Gần như mọi nhà sản xuất vi điều khiển hiện nay đều có một bộ API đi kèm với vi điều khiển của họ. Ngoài các API của nhà sản xuất vi điều khiển (trong nhiều trường hợp, thuật ngữ API và HAL được sử dụng tương đương nhau), còn tồn tại một số API khác mà embedded-systems developer có thể tận dụng. Một số API thậm chí đang trở thành tiêu chuẩn công nghiệp. Trong nhiều trường hợp API, HAL, component và framework được gọi là platform.


THUẬT NGỮ CHUYÊN NGÀNH

Platform là tập hợp các API, HAL, module, component, library và framework được thiết kế để làm việc cùng nhau nhằm tăng tốc độ phát triển phần mềm nhúng và giảm chi phí dự án.


Đầu tiên, và có lẽ là nổi tiếng nhất, là các Arduino API.2 Mỗi board Arduino hoặc bất kỳ board nào dựa trên Arduino đều có thể sử dụng các software component chung và các lệnh gọi hàm từ thư viện phần mềm của Arduino. Arduino cung cấp sự linh hoạt khổng lồ trong việc sử dụng phần cứng và hầu hết các developer sử dụng Arduino đều rất ít hoặc không biết gì về vi điều khiển và đôi khi thậm chí là lập trình. Những thư viện này cung cấp cho những người không-phải-lập-trình-máy-tính một cách tuyệt vời để tạo ra các ứng dụng chức năng (functional application). Vấn đề là các API này nhắm mục tiêu tới việc tạo prototype nhanh, cộng đồng chế tạo (maker community), và thiếu cách tiếp cận chuyên nghiệp để dễ sử dụng trong môi trường phát triển chuyên nghiệp.

Một ví dụ API nổi tiếng khác là nền tảng (platform) mbed của ARM. Mbed giống Arduino ở chỗ nó cung cấp một tập hợp các tính năng (feature) và hàm (function) phần mềm chung được sử dụng để phát triển phần mềm một cách nhanh chóng mà không cần biết nhiều về phần cứng bên dưới. Tuy nhiên, các developer chuyên nghiệp một lần nữa sẽ phải vật lộn với thực tế là platform này không được thiết kế cho mục đích sản xuất (production-intent) vì thiếu các tính năng quan trọng như xử lý lỗi cơ bản và phân tích phần mềm. Việc thiếu những công cụ và năng lực quan trọng này một lần nữa khiến mbed trở thành một nền tảng tạo mẫu (prototyping platform) tuyệt vời nhưng không phải là một hệ thống dành cho mục đích sản xuất. (Đã có những nỗ lực lớn đang được tiến hành để lấp đầy khoảng cách này và khiến mbed hoàn toàn trở thành một platform dành cho mục đích sản xuất bao gồm RTOS).3

Bên cạnh Arduino và mbed, còn có các tiêu chuẩn (standard) dành cho mục đích sản xuất chuyên nghiệp mà các developer có thể tận dụng để phát triển phần mềm nhúng của họ và cải thiện khả năng tái sử dụng cũng như khả năng port của nó. Một ví dụ nổi tiếng là AUTOSAR, được sử dụng trong ngành công nghiệp xe hơi (automotive industry). AUTOSAR cung cấp một HAL tuyệt vời để tương tác với phần cứng cấp thấp. Vấn đề là AUTOSAR hơi phức tạp và tốn tiền sử dụng khi công suất xử lý tăng và không hoạt động tốt trên các hệ thống vi điều khiển hạn chế tài nguyên chạy dưới 200 MHz.

Thật không may, một tiêu chuẩn chung và được chấp nhận rộng rãi trong công nghiệp lại không tồn tại cho các hệ thống dựa trên vi điều khiển. ARM đã cố gắng tạo ra các tiêu chuẩn thông qua các hỗ trợ CMSIS và mbed của họ, nhưng trong hầu hết trường hợp, những tiêu chuẩn này chỉ có thể đưa ra một phương pháp để tương tác với lõi vi điều khiển (microcontroller core) chứ không phải với toàn bộ vi điều khiển. Mỗi nhà sản xuất vi điều khiển vẫn có các thiết bị ngoại vi (peripheral) và tài sản trí tuệ (intellectual property) khác của riêng họ được thiết kế để trở thành nét đặc trưng và khác biệt với sản phẩm của đối thủ cạnh tranh.

Vì lý do này mà trong nhiều trường hợp các “tiêu chuẩn công nghiệp” (industry standard) thất bại, và mỗi công ty sẽ sản xuất tiêu chuẩn độc nhất và tùy chỉnh của riêng họ.

4. The Good, Bad, and Ugly

Khả năng biết tận dụng API hoặc HAL của nhà cung cấp vi điều khiển có thể mang lại cho bạn nhiều lợi thế. Nhà sản xuất là chuyên gia trong cách hoạt động sản phẩm của họ, cho nên họ có kiến ​​thức cần thiết để tạo ra những phần mềm sử dụng đầy đủ và tương thích với vi điều khiển và với chi phí nhỏ nhất. Gần như mọi nhà sản xuất vi điều khiển đều có API riêng của họ. Một vài ví dụ để bạn lựa chọn và khám phá như Renesas Synergy™ Platform, Microchip Harmony, và ST Microelectronics STM32CubeMX toolchain.

Nhiều lợi ích mà developer có thể trải nghiệm bằng cách sử dụng HAL đã được sản xuất bởi nhà cung cấp vi điều khiển. Thứ nhất, nếu nhà cung cấp đã đưa toàn bộ sự hiểu biết của họ vào trong phần cứng, thì các developer sẽ mong đợi những giao diện chạy nhanh và tận dụng thủ thuật khả dĩ cho chính vi điều khiển đó. Thứ hai, một development team không muốn mất hàng tháng trời để develop API và HAL giao tiếp với vi điều khiển. Họ có thể lập trình cho vi điều khiển hoạt động dễ dàng ngay sau khi mở hộp. Khả năng chỉ sử dụng một API và HAL có sẵn là một lợi ích to lớn đối với các developer, đó là lý do tại sao mà các nhà cung cấp vi điều khiển đã bắt đầu cung cấp chúng. Các team có thể ngay lập tức bắt đầu develop code ứng dụng của họ thay vì phải dành hàng tháng trời để đào sâu vào những datasheet kỹ thuật cao nhằm cố gắng hiểu cách thức hoạt động của vi điều khiển.

Một lợi ích khác dành cho các developer là trong nhiều trường hợp, các API và HAL đã được tích hợp vào các công cụ phát triển (development tool) dễ xài. Các công cụ này bao gồm những trình cấu hình (configurator) để giúp giảm bớt gánh nặng develop. Kỹ sư có thể chọn những component rồi include vào trong một application và chỉ định cách những component đó nên được cấu hình như thế nào từ Giao Diện Người Dùng Đồ Họa (Graphical User Interfaces – GUI) đơn giản. Tuy nhiên, những công cụ này có chất lượng phần mềm (software quality) thay đổi đáng kể so với phần mềm được tạo ra từ toolchain.

5. Potential Issues and the Boogeyman

(Còn tiếp)

6. Characteristics Every HAL Should Exhibit

7. Evaluating HAL Characteristics

8. To Build or Not to Build

9. A First Look at a HAL

10. The API Scope

11. API Characteristics to Look For

12. Designing Your Own APIs

13. A First Look at an API

14. Wrapping APIs

15. Why Design Your Own APIs and HALs?

16. Comparing APIs and HALs

17. Going Further

1http://www.webopedia.com/TERM/A/API.html

2https://www.arduino.cc/

3https://www.mbed.com/en/

Icons made by Freepik from www.flaticon.com