Translate

14 tháng 4, 2020

[100daysTIL] Day 4 - About C Embedded Language

Logo của group DÂN KỸ THUẬT
Cách đây vài năm, mình có tham gia một group rất hay trên facebook có tên là DÂN KỸ THUẬT. Mục tiêu của mình khi tham gia group này là để nâng cao kiến thức, kỹ năng cũng như học hỏi thêm những điều mới lạ từ các vị tiền bối đi trước. Và may mắn thay, ở đây mình đã tìm được một cuốn sách thật hay về lập trình nhúng. Và mình quý nó như là báu vật vậy, nên bạn bè thân thích gì là mình chia sẻ hết cả. Cuốn sách có tựa đề là "Lập trình nhúng: Chuyện chưa kể" của tác giả Nguyễn Thành Công, xuất bản ngày 15 tháng 7 năm 2018. Hôm nay mình sẽ nói về cuốn sách này, và những điều mình đã học được từ nội dung của cuốn sách. 
Đầu tiên là văn phong của cuốn sách thật sự gần gũi và thân thuộc với độc giả, phù hợp với những cậu sinh viên mới vào nghề như mình. Lối viết dí dỏm và lôi cuốn, thú vị lắm các bạn ạ ^^ Trước hết là khái niệm lập trình nhúng, nghe qua thì có vẻ xa xôi và lạ hoắc nhưng bản chất của nó thì chỉ có một: 
Lập trình nhúng là việc viết các chương chình điều khiển phần cứng, bạn vừa phải biết lập trình, lại vừa phải giỏi về phần cứng. 
Đó là điều kiện cần và đủ để bắt đầu với cái nghề này :v Ngoài ra, trong lập trình nhúng có rất nhiều ngôn ngữ khác nhau như: C, C++, Java và thậm chí có cả Python nữa. Nhưng ngôn ngữ C thì có khả năng tương tác mạnh hơn cả, và nó cũng cung cấp những giải pháp tối ưu về tốc độ cho các ứng dụng nhúng. Hơn nữa C cũng là ngôn ngữ mà tác giả đề cập trong nội dung cuốn sách này. Về cú pháp của C thì nó quanh đi quẩn lại chỉ là khai báo biến, rồi mấy vòng lặp for, while hoặc rẽ nhánh if, else chẳng hạn, nhưng kỹ năng sử dụng C để giải quyết một vấn đề thì cần nhiều bài tập để trau dồi. Giống như tác giả đã nói: 
Bạn không thể đọc sách học bơi là biết bơi, không thể đọc kiếm phổ là thành cao thủ.

 Ngôn ngữ C trong lập trình nhúng

1) Cơ bản về chương trình
Ý nghĩa của việc lập trình là chỉ cho cái máy biết, bạn muốn nó làm cái gì. Để hiểu một chương trình hoạt động ra sao, có 3 thứ mà bạn cần đặc biệt lưu tâm đó là ROM, RAM và CPU. Còn một khái niệm nữa không kém phần quan trọng đó là trình biên dịch, đây là nơi bạn viết và thực thi các dòng lệnh của mình bằng một ngôn ngữ lập trình nhất định. Trình biên dịch sẽ chuyển các dòng lệnh (người hiểu được) sang ngôn ngữ máy (máy hiểu được), và nạp vào ROM. Khi khởi chạy chương trình, CPU sẽ đọc các dữ liệu được lưu trong ROM và thực thi. ROM giống như ông trùm vậy, ra lệnh thế nào thì CPU phải làm thế đó và không được cãi lời. Còn RAM là bộ nhớ được sử dụng để thực hiện chương trình, nên phải đọc và ghi liên tục. CPU được toàn quyền sử dụng bộ nhớ này, giống như việc CPU là trưởng phòng thì RAM là nhân viên ý. 

Tóm lại: 
- ROM (Read only memory): Bộ nhớ chỉ cho phép đọc, khi mất điện dữ liệu vẫn còn đó.
- RAM (Random access memory): Bộ nhớ truy cập ngẫu nhiên, khi mất điện dữ liệu bị xóa hoàn toàn.
- CPU (Control processing unit): Là bộ xử lý chung tâm, chịu trách nhiệm thực thi chương trình.

2) Cách tổ chức bộ nhớ
Thông thường thì đơn vị nhỏ nhất của bộ nhớ là Byte (hay còn gọi là 1 ô nhớ), và ứng với mỗi byte sẽ có một địa chỉ riêng biệt. Mỗi ô nhớ sẽ có 2 thông số mà chúng ta cần quan tâm đó là:  
- Địa chỉ (nó ở đâu, địa chỉ có thể là số 8-bit, 16-bit, 32-bit...)
- Giá trị được lưu (là bao nhiêu, chỉ là số 8-bit (1 byte) thôi)
Dữ liệu trong bộ nhớ

3) Khai báo biến
Các kiểu biến thông thường khi lập trình C là char, int, long, float, double. Nhưng trong lập trình nhúng, tài nguyên bộ nhớ hạn chế nên việc bạn biết các biến chiếm bao nhiêu ô nhớ là điều rất quan trọng. Thông thường, các biến được khai báo dưới dạng uint8_t, int8_t, uint16_t, int16_t... để sử dụng thì bạn cần #include <stdin.h>. Một điểm đặc biệt nữa là kiểu uint8_t thường được dùng để đại diện cho một ô nhớ (8-bit), uint16_t sẽ yêu cầu bộ nhớ cấp 2 ô nhớ liền kề (16 bits), . . . Hãy thường sử dụng các kiểu dữ liệu với bộ nhớ tường minh trên để kiểm soát bộ nhớ chặt chẽ hơn nhé.

4) Kiểu dữ liệu tự định nghĩa (typedef)
Ngôn ngữ C cung cấp cơ chế tự định nghĩa kiểu dữ liệu để việc truy xuất dữ liệu được thuận tiện. Chúng ta sẽ cùng nhau xem xét ví dụ sau để hiểu hơn về vấn đề này nhé :v
typedef struct { 
  int8_t   temp; 
  uint8_t  humi; 
  uint16_t lux ; 
}env_t
Khi bạn tự định nghĩa một kiểu dữ liệu như trên, thực chất là bạn đang tương tác với một vùng nhớ cho trước. Nếu bạn khai báo một biến env_t evn; thì ngay lập tức, nó sẽ cung cấp cho bạn 4 ô nhớ liền nhau. Nếu bạn in địa chỉ của biến evn ra nó sẽ hiển thị địa chỉ ô nhớ đầu tiên của dãy 4 ô nhớ đó. Và kiểu env_t sẽ cho máy tính biết cách truy cập tới 4 ô nhớ đó như thế nào.
Truy cập biến kiểu evn_t
Một điểm cần lưu ý là các máy tính thường có cơ chế làm tròn biên kiểu dữ liệu (data structure alignment). Nếu chúng ta khai báo như sau:
typedef struct { 
  int8_t   temp;
  uint16_t lux ; 
  uint8_t  humi; 
}env_t
Biến lux khai báo ở giữa, thì kiểu dữ liệu env_t giờ đây có độ dài là 6 byte chứ không phải 4!!!. Lúc này cấu trúc của kiểu biến env_t sẽ có dạng như sau:
Truy cập biến kiểu evn_t
Hai ô nhớ tên padding được thêm vào để tăng hiệu suất việc đọc ghi dữ liệu trong máy tính hiện đại. Nếu các bạn quan tâm thì có thể tìm hiểu sâu hơn nhé.

5) Con trỏ
Có thể nói con trỏ là công cụ lợi hại nhất của C, bạn khó mà giỏi C nếu bỏ qua con trỏ được. Bản chất của con trỏ (chưa nói đến con trỏ hàm) là trỏ tới một vùng nhớ nào đó và tương tác với vùng nhớ đó. Một con trỏ cần 2 thông tin sau để có thể hoạt động được: địa chỉkiểu dữ liệu nó sẽ trỏ tới. 2 yếu tố trên giúp bạn có thể đi đến vùng nhớ mà bạn quan tâm sau đó có thể truy cập vùng nhớ đó theo cách bạn muốn. Một lưu ý nữa là ngôn ngữ C đồng nhất giữa mảng và con trỏ. Ví dụ mình khai báo mảng: uint32_t arr[4]; Lúc này ta sẽ có arr là địa chỉ của phần tử đầu tiên của mảng, hay arr = &arr[0] (cùng 1 địa chỉ),  *arr = arr[0] (cùng 1 giá trị).

Trên đây là một số tóm lược của mình về nội dung cuốn sách, cảm ơn các bạn đã đón đọc.

9 nhận xét:

  1. thực ra t chưa đọc bài này c viết, t chỉ định góp ý là blog cậu design như thế này đọc trên android rất khó, tối qua định đọc mà khộng thể đọc được

    Trả lờiXóa
    Trả lời
    1. Uk, cảm ơn cậu đã góp ý :v Tớ cũng hay ngồi đọc lại bằng điện thoại của mình, và cũng thấy sự bất tiện của nó =))) Nhưng tớ thấy cái theme này có vẻ đẹp đẽ hơn các theme khác :v Nên tớ đã quyết định chọn cái theme này :P

      Xóa
  2. Cách viết rất dễ hiểu, dễ đọc. Khá phú hợp với những người mới tiếp cận với nhúng. Đọc qua lại được ôn lại kiến thức một chút. Cảm ơn em nhé

    Trả lờiXóa
    Trả lời
    1. Cảm ơn anh đã đón đọc bài viết của em nha =)) Còn nhiều thứ hay lắm, cơ mà em chưa biết nên viết tiếp thế nào anh ạ =))) Em chưa nghĩ ra nhan đề ý mà :v

      Xóa
    2. Nó khá là hay, nên a sẽ đón đọc nó

      Xóa
  3. Lại là ngôn ngữ hành tinh khác rồi, nhưng rất ngắn gọn và dễ hiểu mặc dù t cũng không hiểu gì. hahaha. Ôn lại kiến thức vô cùng hữu ích luôn.

    Trả lờiXóa
    Trả lời
    1. :v Cậu có nhất thiết phải bão cmt như vậy không? :v

      Xóa
    2. Chắc do t chắc >.<

      Xóa

Cảm ơn bạn đã gióp ý ^^