Title Image

Blog Logo

Safety Code in Embedded C

🌱 Safety Code in Embedded C

    Có một vài nguyên tắc mình rút ra sau một thời gian lập trình C - nhúng, không chắc là những ngôn ngữ bậc cao có hay không, và chắc chắn đây không phải tất cả các nguyên tắc khi coding 😁. Nhưng các ban có thể lưu ý để sử dụng trong quá trình coding giúp code của mình đẹp, dễ đọc và an toàn hơn.

    👉 Include Guard với header file

    Vấn đề này mình đã nhắc đến trong bài Chỉ thị tiền xử lý - Preprocessor. Thực chất include guard là một preprocessor, dùng để ngăn cản việc include một header file nhiều lần. 

    Nếu không sử dụng include guard cho header file, việc một nó được include ở nhiều chỗ khác nhau sẽ dẫn đến lỗi "Duplicate" các biến hoặc hàm hoặc macro trong file đó. Đôi khi lỗi này sẽ không thể phát hiện được ngay, khi mà chúng ta viết một file header, sau đó cung cấp cho nhiều người trong cùng project, những người đó sẽ include vào module của họ, và không hề bị lỗi gì. Cho đến khi kết hợp các module thì mới ra lỗi này !!! 

    👉 Vì vậy hãy luôn nhớ thêm Include Guard ngay khi khởi tạo một header file theo cú pháp sau:

C

    👉 Sử dụng Bit-mask thay vì phép gán

    Một điều đặc biệt trong lập trình nhúng là chúng ta thường tác động vào các thanh ghi rất nhiều. Và mỗi bit trong thanh ghi lại mang một tác dụng riêng biệt. Vì vậy, khi muốn tác động vào một hoặc một vài bit riêng biệt, chúng ta không nên làm ảnh hưởng đến các bit khác. 

    Việc phải nhớ giá trị trước đó của tất cả các bit và dùng phép gán là hoàn toàn không khả thi !!! 

    Vì vậy, việc sử dụng thành thạo Bit-mask là vô cùng quan trọng và phải ghi nhớ để sử dụng. Chi tiết các kiến thức về Bitwise/Bitmask mình đã tổng hợp trong bài viết này!

    👉 Sử dụng Inline Function thay vì Function-Like Macro 

    Mặc dù được sử dụng tương đối giống nhau, nhưng đối với những Macro mà có truyền vào tham số, mình đề xuất sử dụng Inline Function để thay thế. Function-Like Macro cũng có thể sử dụng nhưng nó không mang lại hiệu quả tốt bằng, đặc biệt các tham số trong đó không thể dùng được một vài toán tử, như ++, --, .... Và đặc biệt các tham số trong Macro không có kiểu dữ liệu !!!


Cách sử dụng Inline Function và so sánh nó với Function-Like Macro được mình trình bày trong bài viết về Inline Function.

    👉 Kiểm tra tính hợp lệ tham số đầu vào của hàm

    Điều này khá quan trọng trong các dự án, hoặc làm việc nhiều người. Đôi khi chúng ta viết một hàm như sau cho người khác sử dụng. 


    Tự mình dùng thì không sao, nhưng những thành viên khác sẽ không biết điều này, và hoàn toàn họ có thể gọi hàm: ADC_Init (ADC2);

    Điều này dẫn đến lỗi build hoặc chương trình bị chạy sai. Vì vậy, việc "rào" các tham số đầu vào là rất quan trọng đối với các hàm. Các bạn có thể tham khảo cách check tham số dưới đây của mình.


    👉 Thêm vào một biến Check_Var để trả về, kiểm tra các tham số nếu không hợp lệ thì Check_Var = 0, và không thực hiện thêm gì nữa, hàm sẽ return 0. Còn nếu tham số chuẩn rồi thì thực hiện đoạn code, và trả về 1. Khi gọi hàm này chúng ta có thể kiểm tra giá trị của nó trước khi chuyển sang hàm khác, hoặc có thể raise lên một thông báo lỗi khi mà hàm trả về 0 (Có lỗi do sai tham số). 

    👉 Đặt hằng số ở trước phép so sánh trong câu lệnh điều kiện

    Điều này nhằm hạn chế sai xót trong quá trình coding. Và ví dụ ở trên chính là một cách viết chuẩn mà mình hay sử dụng. Nếu như các viết thông thường:


    Chúng ta viết nhầm thành phép gán '=', thì chương trình vẫn chạy bình thường và ADC_Instance sẽ được gán bằng ADC0 và điều kiện luôn đúng, dẫn đến chương trình bị chạy sai mong muốn. 

    Trong khi đó, nếu để ADC0 ở trước phép so sánh như ví dụ phần trên, thì nếu viết nhầm thành phép gán '=', chương trình sẽ raise lên một lỗi khi build và chúng ta sẽ phát hiện được. 

    👉 Gán giá trị cho biến khi khởi tạo

    Thường thì khi sử dụng các biến, chúng ta cần biết giá trị hiện tại của nó là bao nhiêu. Và khi khai báo, các biến sẽ có giá trị khởi tạo mặc định nếu chúng ta không gán cho nó. Có thể một số biến bạn biết trước nó là 0 khi khởi tạo rồi, nhưng tốt hơn hết là vẫn nên gán cho nó một giá trị khi khởi tạo, để khi sử dụng chúng ta được tường minh hơn. 

    Còn rất nhiều quy tắc khác mà mình mong muốn chia sẻ với các bạn, như quy tắc đặt tên biến, comment khi code, một số rule chuẩn khi coding, .... Tuy nhiên, bài viết cũng đã dài rồi, và trong một bài viết cũng khó mà tổng hợp hết được toàn bộ kiến thức, nên mình mong các bạn đọc đến đây có thể tự tìm hiểu. Mình recommend một cuốn sách mà các bạn có thể tìm đọc về vấn đề chuẩn coding trong nhúng, đó là tài liệu Embedded C Coding Standard.

>>>= 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ập tốt 😊


Optimize Code

Đăng nhận xét

0 Nhận xét