Table of Contents
Hệ thống nhúng thường cần quản lý dữ liệu cục bộ mà không cần toàn bộ máy phục vụ cơ sở dữ liệu. Việc sử dụng một cơ sở dữ liệu nhỏ ở C cung cấp quyền điều khiển trực tiếp cho các nhà phát triển bộ nhớ, khả năng làm việc và lưu trữ. Bài viết này đi qua thiết kế và thực hiện một cơ sở dữ liệu nhúng đơn giản, bao gồm cấu trúc dữ liệu, thao tác CUD, chỉ mục, và kiên trì cho môi trường được đào tạo tài nguyên.
Cần thiết lõi cho cơ sở dữ liệu nhúng
Một cơ sở dữ liệu nhúng phải hoạt động trong giới hạn chặt chẽ trên RAM, flash và xử lý tốc độ. Những yêu cầu điển hình bao gồm hành vi xác định, dấu chân mã tối thiểu, và không có phụ thuộc bên ngoài. Máy nên hỗ trợ thao tác cơ bản: chèn, cập nhật, xoá, và tìm kiếm. Nhiều cơ sở dữ liệu nhúng cũng cần sống sót qua mất điện và lưu trữ dữ liệu không hoạt động được trên bộ nhớ không hoạt động như EEPROM, SPI flash, hoặc SD.
Chọn cấu trúc dữ liệu đúng là quyết định đầu tiên. Arrays là đơn giản nhưng hạn chế kích cỡ tĩnh. Danh sách liên kết cho phép tăng trưởng động, nhưng thêm con trỏ trên. Đối với hiệu suất cân bằng, một phương pháp lai sử dụng hồ sơ cố định- smlid với một danh sách miễn phí có thể hoạt động tốt. [FLT: 0] Thiết kế [FLT: 0] [FLT: 1] cho phép khả năng nhận thức hữu ích ngay cả cho các động cơ đơn giản hơn.
Thiết kế lớp lưu trữ đĩa
Lớp lưu trữ quản lý cách ghi chép được đặt trong bộ nhớ hay đĩa. Một mô hình chung là xem mỗi đĩa như một cấu trúc cố định để đơn giản hóa con trỏ và cho phép chỉ số trực tiếp. Ghi chú biến phức tạp và cần một bộ nhớ quản lý.
Hồ sơ cố định của Langth với hồ thu âm
Xác định số bản ghi tối đa (v. d., [FLT: 0] và cấp một dãy tĩnh. Một số đường dẫn nhỏ hoặc danh sách miễn phí được dùng. Khi mục ghi rõ, khe của nó sẽ trở về hồ. Cách tiếp cận này tránh sự phân phối động và bảo đảm O( 1) định vị.
#define MAX_RECORDS 256
typedef struct {
int id;
char name[32];
float value;
int active; // 1 if slot in use
} Record;
Record pool[MAX_RECORDS];
Để lưu trữ bền bỉ, hồ bơi có thể được hỗ trợ bởi một tập tin hay một vùng đèn flash. Khi khởi động, động cơ sẽ đọc hồ bơi từ bộ nhớ không hoạt động thành RAM, và khi tắt (hoặc định kỳ) nó sẽ viết lại.
Kiểm tra tính chính xác của dữ liệu
Thêm một trường kiểm tra đơn giản vào mỗi hồ sơ để phát hiện tham nhũng. [FLT: 0]CRC-32 là một sự lựa chọn tốt cho các hệ thống nhúng, cân bằng sự phức tạp với sức mạnh phát hiện lỗi.
Hoạt động CRID cơ bản
Với hồ sơ được xác định, thực hiện chức năng để chèn, tìm, cập nhật và xoá hồ sơ. Hoạt động tìm kiếm thường là cổ chai hiệu suất, vì vậy việc tìm kiếm tuyến tính ngây thơ chỉ được chấp nhận cho cơ sở dữ liệu nhỏ (một vài trăm đĩa)
Name
Duy trì danh sách các danh sách liên kết miễn phí. Trên chèn, bật một chỉ mục từ danh sách tự do, điền vào hồ sơ, và đánh dấu nó hoạt động. Tự danh sách miễn phí có thể là một chồng đơn giản bằng cách sử dụng một dãy số nguyên.
int free_list[MAX_RECORDS];
int free_count = MAX_RECORDS;
for (int i = 0; i < MAX_RECORDS; i++) free_list[i] = i;
int db_insert(int id, const char* name, float value) {
if (free_count == 0) return -1; // no space
int idx = free_list[--free_count];
pool[idx].id = id;
strncpy(pool[idx].name, name, sizeof(pool[idx].name)-1);
pool[idx].value = value;
pool[idx].active = 1;
return idx;
}
Tìm kiếm và cập nhật
Một bản tìm kiếm đơn giản in trên hồ sơ, chỉ kiểm tra các hồ sơ hoạt động. Để cập nhật, tìm bản ghi, sửa đổi trường, và chọn lại danh sách miễn phí nếu mục ghi bị xoá.
int db_find_by_id(int id) {
for (int i = 0; i < MAX_RECORDS; i++) {
if (pool[i].active && pool[i].id == id) return i;
}
return -1;
}
void db_update(int idx, float new_value) {
if (idx >= 0 && idx < MAX_RECORDS && pool[idx].active)
pool[idx].value = new_value;
}
Ý kiến cấp cao: Chỉ mục và Kiên trì
Khi số đĩa nhạc tăng, việc tìm kiếm tuyến tính trở nên đắt đỏ. Thêm một chỉ số đơn giản như một dãy các con trỏ khóa hoặc một cây tìm kiếm nhị phân, không thể thu hồi thời gian. Đối với hệ thống nhúng, một mảng tĩnh được sắp xếp trên phím với việc tìm kiếm nhị phân thường là đủ nếu chèn không thường xuyên.
Comment
Duy trì một dãy các danh sách ghi lưu song song được sắp xếp bởi khóa tìm kiếm (v. d. ID). Khi chèn một mục ghi mới, hãy chèn chỉ mục vào trong danh sách sắp xếp bằng cách chèn một chuỗi nhị phân. Sau đó tìm kiếm trở thành O(log n) thông qua tìm kiếm nhị phân. Các dấu chấm phẩy cần thiết thay đổi danh mục, nhưng cho cơ sở dữ liệu nhỏ điều này là chấp nhận được.
Lưu trữ bền bỉ dùng tập tin I/O
Trên các bộ điều khiển vi mạch, bộ nhớ tạm thô hoạt động rất phổ biến. Trên hệ thống nhúng dựa trên Linux, các tập tin chuẩn PIST /, ], bộ nhớ thô hoạt động tốt. Dùng định dạng tập tin đơn giản (số phiên bản, số phiên bản) theo sau bởi tập tin thô. Để bật khả năng bật lên, một bản ghi (WAL) có thể giúp đỡ, nhưng đối với cơ chế cơ bản một động cơ bản viết (chỉ trong một trang). [T: số tùy chọn sáng tạo, bằng cách viết hoa]. [T: 0]
void db_save(const char* filename) {
FILE* fp = fopen(filename, "wb");
if (!fp) return;
fwrite(pool, sizeof(pool), 1, fp);
fclose(fp);
}
void db_load(const char* filename) {
FILE* fp = fopen(filename, "rb");
if (!fp) return;
fread(pool, sizeof(pool), 1, fp);
fclose(fp);
// Rebuild free-list from pool
free_count = 0;
for (int i = 0; i < MAX_RECORDS; i++) {
if (!pool[i].active) free_list[free_count++] = i;
}
}
Các công ty nhỏ và các giao dịch
Động cơ cơ cơ co sở dữ liệu nhúng phải đối mặt với một cuộc trao đổi không đổi giữa các tính năng và cách sử dụng tài nguyên. Chọn những tính năng nào cần bao gồm phụ thuộc vào ứng dụng:
- Việc tuân thủ – thường không cần thiết. Nguyên tử đơn giản viết đủ để ghi dữ liệu nhạy nhất.
- Đang thực hiện – Thêm chi phí chèn nhưng tăng tốc đọc. Để ghi- tải công việc, bỏ qua chỉ mục.
- Concurency ) – Phần lớn hệ thống nhúng chạy một chỉ duy nhất. Lắp đặt txes nếu dùng RTOS.
- Dấu chân của bộ nhớ – Định vị Static an toàn hơn hoạt động . Hãy dùng hằng số để thay đổi kích cỡ bộ đệm.
- Thiếu hụt – Để lưu lưu lưu tạm, hãy thường xuyên ghi. Batch updates và sử dụng một bộ màu hai chiều.
Ví dụ thực tiễn: Cơ sở dữ liệu nhiệt độ
Hãy xem xét một bộ nhạy nhiệt độ IoT mà ghi âm mỗi phút và lưu trữ chúng tại địa phương trong 24 giờ. Cơ chế cơ sở dữ liệu phải xử lý hệ thống 1440 đĩa (một phút). Mỗi đĩa có thể chứa một nhãn thời gian (không có dấu chấm phẩy), nhiệt độ (fru+4+4) và bộ nhạy dùng khoảng 40 KB, nhiều khe cắm cố định với phiên bản rộng tới phiên dùng 0. 0; ở đây chúng ta cần [FL:10]. Với 28 dấu ngoặc (số hoá theo định sẵn (số lần) mỗi bảng ghi chú (4+4+4+4) cho chi phí trên đầu, hồ sơ dùng khoảng 40 KB, nhiều bộ điều khiển bởi 128.
Máy có thể lưu dữ liệu vào thời trang bấm vòng: khi hồ bơi đầy, kỷ lục cũ nhất được ghi. Tăng độ ghi « đầu » cho khe ghi kế tiếp và « đuôi » cho đĩa nhạc hoạt động cổ nhất. Nó tránh sử dụng logic miễn phí và cung cấp O(1) chèn. Tìm kiếm có thể được tối ưu hoá với một thiết bị tìm kiếm thời gian nếu tài liệu được lưu theo thứ tự thời gian.
typedef struct {
uint32_t timestamp;
float temp_c;
uint8_t sensor_id;
uint8_t active; // not needed if using ring buffer
} TemperatureRecord;
#define MAX_LOGS 1440
TemperatureRecord logs[MAX_LOGS];
uint16_t head = 0; // next write position
uint16_t count = 0; // number of valid records
Chèn một đọc: viết , tăng dần . Việc tìm kiếm một kiểu thời gian riêng , tăng dần (bị bao phủ . Việc tìm kiếm một kiểu chữ hoa/ thường: nếu tính toán [FX LG], bản ghi là một chuỗi âm tiết, từ đầu đến đầu 1]. Hãy dùng hệ thống tìm kiếm hệ thống điện tử sau khi khởi động. Hình này cực kỳ nhỏ và được dùng rộng rãi. [R: 0]
Thử ra và làm báp têm phần cứng của mục tiêu
Luôn luôn kiểm tra cơ chế cơ sở dữ liệu trên phần cứng nhúng thực sự. Mô phỏng bỏ qua các hạn chế thời gian, đặc biệt là cho thời gian ghi nhanh và kịch bản mất điện. Theo dõi RAM với một công cụ phân tích và kiểm tra các trường hợp cạnh: lưu trữ đầy đủ, bị hỏng dữ liệu, đặt lại giữa. Một bộ khởi chạy thử đơn giản hàng ngàn chèn ngẫu nhiên, tìm kiếm và xoá bỏ trong khi so sánh với mô hình vàng.
- Đồ mặc ) – Nếu viết cho EEPROM hoặc OR flash, tổng số sẽ viết cho vài trăm ngàn. Một bộ đệm hình tròn với lớp mặc sẽ kéo dài tuổi thọ.
- An toàn ) – Dùng dấu cam kết: hãy viết một lá cờ sau một loạt dữ liệu. Khi khởi động lại, kiểm tra lại lá cờ; nếu thiếu, bỏ mục cuối cùng rồi trở lại trạng thái trước.
- Hợp nhất ) – tránh đệ quy sâu. Giữ hàm gọi chồng nông. Dùng bộ đệm tĩnh cho tập tin I/ O.
Kết luận
Xây dựng cơ sở dữ liệu cơ bản trong hệ thống nhúng là một phương pháp thực tế để quản lý dữ liệu trong các thiết bị hạn chế tài nguyên. Bằng cách tập trung vào các cấu trúc dữ liệu đơn giản như hồ sơ lưu trữ cố định và vòng đệm, các nhà phát triển đạt được các thao tác CUD hiệu quả với chi phí tối thiểu. Thêm mục lục và tính kiên trì cơ bản biến một loạt đơn giản thành một tập tin dữ liệu cục bộ đáng tin cậy. Các kỹ thuật được mô tả ở đây từ các bản ghi nhỏ đến hệ thống phức tạp hơn, và cung cấp một nền tảng để hiểu cách tích hợp dữ liệu lớn hơn như igit hay D Berkeley hoạt động dưới nắp đậy.