🌱 Giới thiệu về Semihosting

🌱 Giới thiệu về Semihosting

    Khi làm việc với Vi điều khiển, kỹ thuật thường được sử dụng với người lập trình Firmware là Logging, dùng để ghi lại thông tin trong quá trình debug, thực hiện chương trình, có thể ghi lại dưới dạng text. Đối với các Vi điều khiển, việc ghi lại thông tin này thường được thực hiện bằng các giao thức nối tiếp (UART, SPI), giao tiếp dữ liệu vào file text trên máy tính.

    Tuy nhiên cách này lại tiêu tốn tài nguyên của vi điều khiển, đó là giao thức UART hay SPI. Chúng ta có thể sử dụng 1 cơ chế nâng cao hơn, đó là Semi-hosting.

    👉 Semi-hosting là gì?

    Semi-hosting là một cơ chế cho phép chương trình chạy trên chip ARM giao tiếp và sử dụng các cơ chế Input/Output trên một host - máy tính đang chạy Debug. Chức năng này có sẵn trên các vi điều khiển ARM Cortex.

    Ví dụ, Vi điều khiển có thể sử dụng một số hàm của thư viện C như printf()scanf(), fopen(). Điều này rất có ích đối với việc debug, khi chúng ta muốn in giá trị biến hay ô nhớ lên màn hình máy tính. 

Core

    👉 Cách hoạt động của Semi-hosting

    Semi-hosting được thực hiện bằng cách tạm dừng hoạt động của CPU (Debug), sử dụng breakpoint hoặc gửi một lệnh Supervisor Call (SVC 0xAB hoặc SVC 0x123456) - Như hình trên.

    Debugger trên máy tính có thể giao tiếp với Vi điều khiển khi bị tạm dừng bằng cách tác động vào 2 thanh ghi R0 và R1. 

    ➤ Dưới đây là một số Semi-hosting Operations

/* File operations */
SYS_OPEN        EQU 0x01 //Open a file or stream on the host system.
SYS_ISTTY       EQU 0x09 //Check whether a file handle is associated with a file or a stream/terminal such as stdout.
SYS_WRITE       EQU 0x05 //Write to a file or stream.
SYS_READ        EQU 0x06 //Read from a file at the current cursor position.
SYS_CLOSE       EQU 0x02 //Closes a file on the host which has been opened by SYS_OPEN.
SYS_FLEN        EQU 0x0C //Get the length of a file.
SYS_SEEK        EQU 0x0A //Set the file cursor to a given position in a file.
SYS_TMPNAM      EQU 0x0D //Get a temporary absolute file path to create a temporary file.
SYS_REMOVE      EQU 0x0E //Remove a file on the host system. Possibly insecure!
SYS_RENAME      EQU 0x0F //Rename a file on the host system. Possibly insecure!

/* Terminal I/O operations */
SYS_WRITEC      EQU 0x03 //Write one character to the debug terminal.
SYS_WRITE0      EQU 0x04 //Write a 0-terminated string to the debug terminal.
SYS_READC       EQU 0x07 //Read one character from the debug terminal.

/* Time operations */
SYS_CLOCK       EQU 0x10
SYS_ELAPSED     EQU 0x30
SYS_TICKFREQ    EQU 0x31
SYS_TIME        EQU 0x11

/* System/Misc. operations */
SYS_ERRNO       EQU 0x13 //Returns the value of the C library errno variable that is associated with the semihosting implementation.
SYS_GET_CMDLINE EQU 0x15 //Get commandline parameters for the application to run with (argc and argv for main())
SYS_HEAPINFO    EQU 0x16
SYS_ISERROR     EQU 0x08
SYS_SYSTEM      EQU 0x12

    👉 Ví dụ sử dụng Semi-hosting

    Đối với Vi điều khiển STM32, Semihosting thường được sử dụng cùng openOCD

    Ở ví dụ này mình sử dụng arm-none-eabi-gcc làm Cross Compiler. Các bạn có thể thực hành với Vi điều khiển STM32 và tham khảo một số bài viết liên quan đến makefile của mình.

    💬 Để sử dụng chức năng Semi-hosting, chúng ta cần thêm một số thư viện trong quá trình Linking.

  • libc.a, đây là thư viện C chuẩn (newlin cho arm-none-eabi-gcc).
  • librdimon.a, thư viện libgloss (platform-specific code).

Để thêm 2 thư viện này, chúng ta cần đảm bảo chúng có trong ổ cài arm-none-eabi-gcc. Và sau đó thêm các option sau vào Linker Options:

  • -lc -lrdimon
  • --specs=rdimon.specs để sử dụng version semihost của syscalls.
  • Xóa option -nostartfiles nếu có để cho phép link đến thư viện C chuẩn.

    💬 Việc thứ 2 cần làm là gọi hàm sau trong code C: initialise_monitor_handles() để bắt đầu sử dụng các function trong thư viện C chuẩn. 

    Ví dụ một đoạn code C sử dụng Semi-hosting

#ifdef SEMIHOSTING
extern void initialise_monitor_handles(void);
#endif

int main(void) {
#ifdef SEMIHOSTING
  	initialise_monitor_handles();
#endif

  	// other tasks ...

#ifdef SEMIHOSTING
    printf("hello world!\n");
    printf("hello world!\n");
#endif

    // other tasks ...

  	return 0;
}

    💬 Việc thực hiện Semi-hosting rất hữu ích khi chúng ta Debug, tuy nhiên lại k được sử dụng khi chương trình hoàn thiện để run, vì vậy các bạn hãy dùng nó thật hiệu quả để test chương trình và xóa nó khi nạp vào một chương trình hoàn chỉnh (Vì nó làm tăng size code và giảm hiệu suất chương trình khi run).

    Mình sẽ có video hướng dẫn sau!

    👉 Link tham khảo

    What is semihosting - developer.arm.com

>>>= Follow ngay =<<<

💚 Kênh Youtube Lập trình - Điện tử 💚

Để nhận được những bài học miễn phí mới nhất nhé 😊

    Chúc các bạn học tốt 😊

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

1 Nhận xét

  1. Anh đã có video phần này chưa ạ, em rất muốn tham khảo về phần này ạ.

    Trả lờiXóa
Mới hơn Cũ hơn