• Thứ Tư, 07/01/2004 17:23 (GMT+7)

    Bob - Ngôn ngữ lập DVD và set-top box dùng công nghệ NUON

    NUON là nền tảng hệ thống phần cứng/phần mềm cho đầu đọc DVD và set-top box. phần cứng là hệ thống xử lý đa phương tiện mạnh với bốn bộ xử lý đa năng, và phần chuyên dụng hỗ trợ việc giải mã chương trình DVD gồm video MPEG-2 và AC-3 audio. Một trong những ưu điểm của bộ xử lý NUON là khả năng hỗ trợ linh động các chuẩn mới nhờ có thể lập trình được. Phần mềm gồm các trình điều khiển hỗ trợ DVD, CD audio, MP3 audio, và VCD, cùng với trình Virtual Light Machine khá phức tạp có thể thay đổi được theo các chương trình nghe nhạc đặc biệt. Một tính năng đặc biệt đó là hỗ trợ khả năng xem phim và chơi game theo công nghệ NUON. Ba sản phẩm dùng công nghệ NUON đã xuất hiện trên thị trường vào tháng 11/2001: SD-2300 của Toshiba, Extiva N-2000 và DVD-N501 của Samsung.

    Bob hiện được dùng như là ngôn ngữ kịch bản (script) cho hệ thống DVD theo công nghệ NUON. Bob là ngôn ngữ lập trình hướng đối tượng động có cú pháp tương tự C/C++, Java và JavaScript. Giống như Java và JavaScript, môi trường thực thi Bob tự quản lý bộ nhớ. Cơ chế thu dọn bộ nhớ của Bob thu hồi lại bất kỳ vùng nhớ nào mà chương trình không còn tham chiếu tới nữa.

    Bảng 1 là một ví dụ đơn giản tạo đối tượng trong Bob. Dòng Hazard = new Object(); tạo một đối tượng mới và gán làm giá trị của biến Hazard. Dòng define Hazard.initialize(cave) định nghĩa phương thức initialize dùng để khởi tạo các đối tượng đã được tạo với toán tử new. Biểu thức new object hay new object(arguments) tạo một đối tượng mới kế thừa object. Đối tượng mới lập tức được gửi một thông điệp initialize để khởi tạo trạng thái của nó.

    Bảng 1 cũng có tham chiếu biến this. Giống như C++ hay Java, biến this trong một phương thức tham chiếu tới đối tượng nhận thông điệp kích hoạt phương thức (method). Phương thức initialize phải trả về giá trị this bởi vì giá trị trả về này là được dùng để tạo đối tượng mới.

     

    Nhúng Bob vào trong ứng dụng

    Để dùng trong ứng dụng nhúng, trước hết bạn phải tạo môi trường thông dịch Bob; xem bảng 2. Lệnh gọi tới BobMakeInterpreter khởi tạo môi trường thông dịch. Bạn truyền con trỏ môi trường thông dịch này tới đa phần các hàm API của Bob.Lệnh gọi BobEnterLibrarySymbols thêm các hàm và đối tượng Bob chuẩn vào môi trường thông dịch, trong số này có một số hàm thông dụng như LoadObjectFile.Lệnh gọi BobUserEval là tùy chọn, lệnh này cho phép gọi các hàm Load, Eval, và CompileFile. Tất cả hàm này đều yêu cầu trình biên dịch Bob dịch mã nguồn Bob thành mã thực thi. Do Bob có một trình biên dịch độc lập dùng để dịch mã nguồn Bob thành mã thực thi có thể được gọi lúc thực thi với hàm LoadObjectFile, vì vậy không cần có trình biên dịch lúc thực thi. Lý do duy nhất để kèm theo cả trình biên dịch là nhằm cho phép nhập vào mã lệnh để kiểm tra đánh giá lúc thực thi. Điều này chỉ có ích cho việc bẫy lỗi, nhưng nói chung không cần thiết đối với chương trình thành phẩm.

    Vùng errorHandler của môi trường thông dịch chỉ tới hàm thiết kế riêng dùng để kiểm soát lỗi thực thi của Bob. Việc ứng dụng có thể kiểm soát khi lỗi xảy ra cho phép ứng dụng có thể thực hiện chủ động xử lý lỗi.

    Vùng protectHandler chỉ tới hàm thiết kế riêng dùng để bảo vệ các giá trị Bob không bị mất khi thu dọn bộ nhớ. Khả năng lưu các giá trị Bob vào các cấu trúc dữ liệu thiết kế riêng rất hữu ích nhằm tránh không bị xóa mất bởi cơ chế thu dọn bộ nhớ tự động của Bob.

    Các vùng standardInput, standardOutput, và standardError chỉ tới các luồng xuất nhập chuyên biệt. Luồng (stream) là cách thức tổng quát kiểm soát việc xuất nhập. Mỗi luồng đều có cung cấp các hàm đọc, ghi ký tự và đóng luồng. Bảng 2 là một đoạn mã thực hiện đơn giản một luồng xuất nhập chuẩn dùng thư viện C chuẩn.

     

    Tạo đối tượng chuyên biệt cho ứng dụng

    Một ứng dụng của Bob trong ứng dụng nhúng là tạo các đối tượng chuyên biệt cho ứng dụng. Bob cung cấp kiểu dữ liệu BobCPtrObject cho phép khai báo biến có hành vi giống như các đối tượng theo nghĩa có thể trả lời thông điệp và có các thuộc tính. Khác biệt ở chỗ các thủ tục hàm của một BobCPtrObject được viết bằng C chứ không phải Bob, và giá trị của các thuộc tính của một BobCPtrObject được truy cập qua các hàm C getter và setter. Bảng 3 trình bày cách thức định nghĩa một kiểu BobCPtrObject mới. Hàm BobEnterCPtrObject thêm một kiểu mới cho môi trường thông dịch Bob được xác định với đối số đầu tiên. Đối số thứ hai xác định BobCPtrObject mà kiểu mới kế thừa, đối số này có thể là NULL nếu kiểu mới là kiểu gốc. Đối số thứ ba là tên của kiểu mới. Khi lệnh gọi hàm hoàn tất, một thể hiện mới sẽ được định nghĩa trong vùng toàn cục với tên này. Hai đối số cuối cùng chỉ tới các bảng thủ tục hàm và thuộc tính của kiểu mới. 

     

    Thủ tục hàm

    Bảng 4 giới thiệu một thủ tục hàm được viết bằng C. Lệnh gọi BobParseArguments phân tích các đối số được truyền trong lệnh gọi thủ tục hàm và gán vào các biến C. Đối số đầu tiên là một con trỏ tới môi trường thông dịch Bob. Đối số thứ hai là một chuỗi mô tả các kiểu đối số. Giống như định dạng chuỗi trong hàm printf của C, mỗi mô tả đối số gồm đối số đi liền theo chuỗi mô tả. Đối số đầu tiên luôn luôn là giá trị của biến this. Đối số thứ hai là giá trị của biến _next. Trong bảng 4, “p=” có nghĩa là đối số đầu tiên phải là một kiểu con của nuiBobWidgetType. Đây là kiểu của tất cả widget trong NUI (NUON User Interface). Ký hiệu “*” để chỉ  đối số được bỏ qua. Đối số _next không cần thiết trong thủ tục hàm này. Ký hiệu “ |” có nghĩa đối số theo sau là tuỳ chọn (có thể có hoặc không). Trong chương trình C, bạn nên gán giá trị mặc định cho các biến liên kết với các đối số trước khi gọi BobParseArguments, vì các biến này sẽ không được gán giá trị nếu đối số Bob tương ứng bị loại khỏi lời gọi thủ tục hàm. Ký hiệu “B” có nghĩa đối số tương ứng có giá trị Bool. Biến C liên kết với đối số này sẽ là một số nguyên và được gán giá trị FALSE(0) nếu đối số Bob là rỗng (nil hay null) hoặc sai, và TRUE(1) nếu đối số Bob có giá trị bất kỳ khác. Nói cách khác, Bob dịch các giá trị khác rỗng hay sai ra thành đúng.

    Thủ tục hàm C sẽ trả về một giá trị Bob. Môi trường thông dịch Bob cung cấp sẵn một số giá trị như trueValue và falseValue. Các giá trị khác có thể tạo bằng cách dùng các hàm Bob API như BobMakeInteger và BobMakeCString.

     

    Thuộc tính

    Bảng 5 là thủ tục thuộc tính viết bằng C. Bob dùng cặp hàm getter và setter để truy cập các thuộc tính. Hàm getter dùng để lấy giá trị thuộc tính, hàm setter gán giá trị cho thuộc tính. Với thuộc tính loại chỉ đọc (read-only) thì không cần tới hàm setter. Trong trường này, hàm setter sẽ truyền đi giá trị NULL. Hàm getter lấy thông số môi trường thông dịch Bob và đối tượng có giá trị thuộc tính yêu cầu, và trả về giá trị này. Hàm setter lấy thông số môi trường thông dịch, đối tượng có thuộc tính cần gán giá trị và giá trị mới để gán cho thuộc tính.

     

    Môi trường NUON

    Giao diện người dùng của NUON (NUI) là dạng ứng dụng đơn giản tương tự như trình duyệt web, với nội dung được hiển thị trong các khung và từng khung có thể chứa các khung khác.

    NML là ngôn ngữ đánh dấu (markup language) dùng để miêu tả các trình đơn (menu) của NUON. NML, được xây dựng dựa trên XML, có các thẻ mô tả các khối thành phần (widget) tạo nên menu NUON. Một widget có thể dùng để hiển thị một giá trị hoặc nhận thông tin nhập vào của người dùng. NUI hỗ trợ nhiều dạng widget cho nhiều dạng ứng dụng. Bảng 6 là một menu NML. Thẻ <nml> bao toàn bộ phần miêu tả menu, thẻ <textStyle> mô tả kiểu chữ, thẻ <script> dùng để nạp một script vào, thẻ <body> bao phần thân của menu có chứa tất cả widget, thẻ <widget> mô tả widget, và thẻ <group> bao một nhóm widget có liên quan với nhau (đây thực ra là một dạng widget đặc biệt). Còn có một số dạng widget khác: text dùng để nhập và hiển thị chữ, slider hiện giá trị của một biến số dưới dạng hình một thanh có độ dài tỉ lệ với giá trị của biến, select cho phép thực hiện chọn lựa trong một tập giá trị, image hiển thị hình GIF, và frame dùng để hiển thị một file NML khác.

    Môi trường thực thi NUI xác định widget khung trên cùng, tức giá trị của biến topFrame. Một ứng dụng thoạt đầu sẽ nạp một file NML vào khung này. Widget có thuộc tính tên dùng tham chiếu tới. Khi một file NML được nạp thì sẽ có một biến widgets được tạo. Giá trị của biến này là một đối tượng với các thuộc tính là các widget trong file NML, giá trị của mỗi thuộc tính là một đối tượng widget. Để tránh nhầm lẫn các biến widgets của các file NML, một không gian biến mới được tạo ra mỗi khi một file NML được nạp. Mỗi không gian biến này có tính kế thừa không gian toàn cục, nhờ vậy có thể truy cập tới tất cả các hàm và biến toàn cục (tuy nhiên chúng có bản sao riêng của các biến tương tự như widgets). Điều này nhằm tránh những sự đụng độ tên giữa các file NML và các script liên kết của chúng. Các hàm Bob API khi tham chiếu tới các biến sẽ lấy đối số BobScope thay vì đối số BobInterpreter để chỉ ra không gian biến đang được dùng.

    Bạn có từng thắc mắc về cách thức đầu đọc DVD làm việc khi bạn nhấn nút phát nhanh trên bộ điều khiển từ xa (remote)? Trong thiết kế của đầu DVD NUON, mỗi nút trên remote khi ấn sẽ phát sinh một sự kiện được gửi tới trình điều khiển sự kiện tương ứng . Ở bộ N501, trình điều khiển sự kiện là một đoạn mã Bob. Trình điều khiển sự kiện phát nhanh (fast-forward) kiểm tra để đảm bảo chức năng phát nhanh được thực hiện ở những phần cho phép (ví dụ bạn không thể thực hiện phát nhanh qua phần khuyến cáo của FBI) và đưa ra một lời gọi tới hệ thống dịch chuỵển của DVD để yêu cầu phim bắt đầu chuyển nhanh. Bảng 6 là một ví dụ đơn giản của một trình điều khiển sự kiện được viết bằng Bob. Dòng onClick=’topFrame.LoadPage(“pages/wumpus.npg”)’ thể hiện công việc phải làm khi widget “start” được chỉ định và người dùng nhấn phím trên remote.

    DVD-N501 của Samsung là đầu DVD đầu tiên theo chuẩn NUON có khả năng đọc đĩa CD-R. Chính khả năng này làm cho chuẩn mở NUON trở nên khả khi. Với các công cụ do VN Labs cung cấp, bạn có thể biên soạn đĩa CD-R trên máy tính và sau đó chơi trên đầu DVD-N501. Bạn có thể tải về NUON SDK ở http://www.dev.nuon.tv, gồm bộ biên dịch C/C++ dựa trên bộ biên dịch GNU C, bộ assembler, linker và các công cụ cần thiết khác để xây dựng các ứng dụng NUON.

     

    Kết luận

    Trong khi assembler và C/C++ là phương thức tốt nhất để tạo ứng dụng hiệu suất cao cho NUON, thì bộ công cụ phát triển NUI cung cấp phương tiện để dễ dàng tạo các ứng dụng đơn giản trong môi trường trình duyệt. Bob cho phép dễ dàng lập kịch bản cho các ứng dụng này với ngôn ngữ lập trình tương tự ngôn ngữ JavaScript quen thuộc. Bob API cũng cho phép dễ dàng nhúng Bob vào các ứng dụng khác có yêu cầu một ngôn ngữ dạng kịch bản nhỏ và hiệu quả.

     

    Phương Uyên

     

    Quy trình phát triển ứng dụng Bob

    1. Thảo chương viên có thể dùng bất kỳ trình soạn thảo nào viết chương trình nguồn, sử dụng các thư viện NUON và các hàm BIOS API.

    2. Chương trình nguồn được biên dịch và liên kết với các thư viện được cung cấp để tạo file chương trình thực thi.

    3. Ghi chương trình thực thi lên đĩa CD. (hầu hết các thiết bị NUON sản xuất từ tháng 9/2001 trở đi hỗ trợ các đĩa CD-R và CD-RW).

    4. Đĩa CD giờ có thể chơi trên các đầu NUON-DVD.

    Việc phát triển ứng dụng Bob có thể thực hiện trên máy PC bình thường dùng hệ điều hành Windows 2000. Không có yêu cầu phần cứng đặc biệt. Chỉ yêu cầu có đủ bộ nhớ và không gian đĩa cứng trống để cài công cụ phát triển.

    ID: A0204_86