const
có nghĩa là biến không thể được sửa đổi bởi mã c, không phải là nó không thể thay đổi. Có nghĩa là không có lệnh nào có thể ghi vào biến, nhưng giá trị của nó vẫn có thể thay đổi.
volatile
có nghĩa là biến có thể thay đổi bất kỳ lúc nào và do đó không có giá trị được lưu trong bộ nhớ cache nào có thể được sử dụng; mỗi quyền truy cập vào biến phải được thực thi đến địa chỉ bộ nhớ của nó.
Vì câu hỏi được gắn thẻ "nhúng" và giả sử temp
là một biến do người dùng khai báo, không phải là một thanh ghi liên quan đến phần cứng (vì chúng thường được xử lý trong một tệp .h riêng biệt), hãy xem xét:
Một bộ xử lý nhúng có cả bộ nhớ dữ liệu đọc-ghi dễ bay hơi (RAM) và bộ nhớ dữ liệu chỉ đọc không thay đổi, ví dụ bộ nhớ FLASH theo kiến trúc von-Neumann, nơi dữ liệu và không gian chương trình chia sẻ một bus địa chỉ và dữ liệu chung.
Nếu bạn khai báo const temp
có một giá trị (ít nhất nếu khác 0), trình biên dịch sẽ gán biến cho một địa chỉ trong không gian FLASH, vì ngay cả khi nó được gán cho một địa chỉ RAM, nó vẫn cần bộ nhớ FLASH để lưu giá trị ban đầu. của biến, làm cho địa chỉ RAM trở nên lãng phí không gian vì tất cả các hoạt động ở chế độ chỉ đọc.
Hậu quả:
int temp;
là một biến được lưu trữ trong RAM, được khởi tạo bằng 0 khi khởi động (cstart), các giá trị được lưu trong bộ nhớ cache có thể được sử dụng.
const int temp;
là một biến được lưu trữ trong FLASH (read-ony), được khởi tạo bằng 0 tại thời điểm trình biên dịch, các giá trị được lưu trong bộ nhớ cache có thể được sử dụng.
volatile int temp;
là một biến được lưu trữ trong RAM, được khởi tạo bằng 0 khi khởi động (cstart), các giá trị được lưu trong bộ nhớ cache sẽ KHÔNG được sử dụng.
const volatile int temp;
là một biến được lưu trữ trong FLASH (read-ony), được khởi tạo bằng 0 tại thời điểm trình biên dịch, các giá trị được lưu trong bộ nhớ cache sẽ KHÔNG được sử dụng
Đây là phần hữu ích:
Ngày nay, hầu hết các bộ xử lý nhúng đều có khả năng thực hiện các thay đổi đối với bộ nhớ không bay hơi chỉ đọc của chúng bằng mô-đun chức năng đặc biệt, trong trường hợp này const int temp
có thể thay đổi trong thời gian chạy, không phải trực tiếp mua. Nói theo cách khác, một hàm có thể sửa đổi giá trị tại địa chỉ temp
được lưu trữ.
Một ví dụ thực tế sẽ là sử dụng temp
cho số sê-ri của thiết bị. Lần đầu tiên bộ xử lý chạy nhúng, temp
sẽ bằng 0 (hoặc trị giá khai báo) và một chức năng có thể sử dụng thực tế này để chạy thử nghiệm trong sản xuất và nếu sucessfull, yêu cầu được chỉ định một số sê-ri và sửa đổi các giá trị của temp
bằng phương tiện của một chức năng đặc biệt. Một số bộ xử lý có dải địa chỉ đặc biệt với bộ nhớ OTP (có thể lập trình một lần) chỉ dành cho điều đó.
Nhưng ở đây có sự khác biệt:
Nếu const int temp
là ID có thể sửa đổi thay vì số sê-ri có thể lập trình một lần và KHÔNG được khai báo volatile
, một giá trị được lưu trong bộ nhớ cache có thể được sử dụng cho đến lần khởi động tiếp theo, có nghĩa là ID mới có thể không hợp lệ cho đến khi khởi động lại tiếp theo hoặc thậm chí tệ hơn, một số chức năng có thể sử dụng giá trị mới trong khi khác có thể sử dụng giá trị được lưu trong bộ nhớ cache cũ hơn cho đến khi khởi động lại. Nếu const int temp
IS khai báo voltaile
, thay đổi ID sẽ có hiệu lực ngay lập tức.
const volatile int temp;
ở phạm vi khối (tức là bên trong{ }
), nó không có tác dụng gì ở đó.