Thuật toán nhật ký tròn nhẹ (giống như hệ thống tập tin) để lưu trữ dựa trên flash


8

Tôi hiện đang làm việc trên một dự án liên quan đến việc ghi nhật ký nhanh chóng, liên tục của một số liệu cụ thể ứng dụng trong suốt cuộc đời dài. Để làm điều này, tôi đã kết thúc bằng cách sử dụng chip NXP M0 và chip flash 32MiB SPI. Việc đăng nhập là liên tục và cần kéo dài nhiều năm trong lĩnh vực này (10+) và được kiểm tra định kỳ bởi một người để phát hiện xu hướng. Cuối cùng, bộ đệm lấp đầy và bắt đầu ghi đè dữ liệu cũ, điều này hoàn toàn tốt. Tôi đã đưa ra một thuật toán đơn giản để đi bộ toàn bộ thiết bị flash để tìm đầu hiện tại sau khi bật nguồn (thiết bị bị tắt nguồn thường xuyên ngoài tầm kiểm soát của tôi) để việc đăng nhập có thể tiếp tục ở nơi nó tắt. Tôi chỉ có thể vũ phu thông qua bước đi này và thực hiện nó với ~ 4s là trường hợp xấu nhất.

Điều này khiến tôi suy nghĩ, có bất kỳ hệ thống tập tin cấu trúc nhật ký nào được phục vụ cho các thiết bị flash và vi điều khiển không? JFFS và tất cả các FS có cấu trúc log nổi tiếng khác mà tôi tưởng tượng sẽ hơi nặng đối với một vi điều khiển đơn giản (tất nhiên phụ thuộc vào ứng dụng). Để cụ thể hơn, tôi muốn biết bất kỳ thuật toán nào được thiết kế cụ thể là nhật ký tròn với thời gian tìm kiếm nhanh và / hoặc bất kỳ thuật toán nào được thiết kế cho hệ thống tệp "truyền thống" trên thiết bị flash có thể chạy trên vi điều khiển. Theo nghĩa truyền thống này là ngang bằng với một cái gì đó như JFFS, trong đó có một cấu trúc dữ liệu đại diện cho một tập hợp các tệp truy cập ngẫu nhiên có thể thay đổi trong một không gian tên phân cấp.


là FAT32 hoặc FAT16 trên thẻ SD quá chậm?
Abbeyatcu

2
Câu hỏi này hoàn toàn thuộc chủ đề ở đây, nhưng nếu bạn không nhận được bất kỳ câu trả lời tuyệt vời nào thì StackOverflow có thể giúp ích. Hãy hy vọng chúng ta có thể nhận được một số câu trả lời tốt ở đây!
Kellenjb

@vicatcu Không phải là nó quá chậm, đối với ứng dụng thẻ SD cộng với đầu nối của tôi tốn kém hơn và thẻ SD có thể kém tin cậy hơn. Kellenjb Tôi không chắc chắn nên đặt nó ở đâu. Giống như rất nhiều câu hỏi thiết kế nhúng loại này rơi vào giữa. Nếu nó không hoạt động tốt ở đây, tôi sẵn sàng di chuyển nó.
Kris Bahnsen

Nó có phải là một chip flash thô? Nếu vậy, làm thế nào để bạn xử lý các khối chết? Khá nhiều phần trong thỏa thuận triển khai flash FS với các khối chết. Nếu bạn cảm thấy JFFS / JFFS2 quá nặng, bạn có thể muốn kiểm tra YAFFS. Nó cảm thấy giống như một hệ thống tập tin rất đơn giản, vì vậy nó sẽ khá nhẹ.
Leo

Vâng, đúng vậy. Các khối xấu không phải là khủng khiếp trong ứng dụng cụ thể này vì nó quá dài đến nỗi dữ liệu được rút ra chỉ là một xu hướng thô và trong hầu hết các trường hợp tôi nghi ngờ việc đăng nhập sẽ được sử dụng.
Kris Bahnsen

Câu trả lời:


2

cấu trúc dữ liệu dây

Tôi bị mê hoặc bởi cấu trúc dữ liệu dây. Tôi có một dự án sở thích đang cố gắng điều chỉnh nó thành một vi điều khiển chỉ với một vài byte RAM được gắn vào một bộ nhớ Flash lớn, để tôi có thể chèn và xóa và tùy ý chỉnh sửa văn bản có độ dài thay đổi trong các tệp văn bản lớn. Các tệp văn bản quá lớn để vừa với RAM. Xóa nửa cuối của tệp và ghi lại thành flash, được dịch chuyển một byte, mỗi lần tôi chèn hoặc xóa một ký tự ở giữa tệp văn bản nhiều megabyte, sẽ quá chậm, nhưng cấu trúc dữ liệu dây có thể làm điều này nhanh hơn nhiều. Do cấu trúc dữ liệu dây có thể biểu thị các tệp có độ dài thay đổi truy cập ngẫu nhiên có thể thay đổi như các phần có độ dài cố định bất biến, nên nó có vẻ phù hợp với bộ nhớ flash - tất cả các chỉnh sửa được viết theo kiểu nhật ký tròn. Than ôi, tất cả các lỗi chưa được xử lý trong mã của tôi. :-(

nhật ký thời gian cố định

Tôi đã làm cho một hệ thống nhật ký tròn tương tự làm việc, cho một sản phẩm tôi đã giúp phát triển.

Tôi chỉ đơn giản viết các bản ghi có độ dài cố định lần lượt, lấp đầy đèn flash dưới dạng một mảng tròn.

(Với đèn flash hoàn toàn trống, tôi bắt đầu viết các bản ghi khoảng 3 khối trước khi kết thúc mảng, vì vậy tôi có thể kiểm tra vòng tròn chỉ sau một vài bản ghi dữ liệu được lưu trữ, thay vì bắt đầu ở mức 0 và chờ giá trị của dữ liệu được viết trước khi phát hiện ra rằng có một lỗi trong mã bao quanh của tôi).

Tôi chắc chắn rằng luôn có ít nhất 2 "khối xóa" đã sẵn sàng để viết. Sau khi viết một bản ghi, nếu chỉ có 2 "khối bị xóa" sau khi nó trống, tôi đã xóa vô điều kiện khối dữ liệu cũ nhất - khối thứ 3 của dữ liệu cũ nhất sau 2 "khối bị xóa". (Gần cuối bộ nhớ flash, "after" có nghĩa là "bao quanh đến đầu bộ nhớ flash) (Có lẽ một khối bị xóa sẽ là đủ - Tôi quên tại sao tôi nghĩ tôi cần ít nhất 2 và đôi khi 3) .

Tôi quên chính xác có bao nhiêu bản ghi tôi đã đặt trong mỗi "khối xóa", nhưng tôi chắc chắn rằng tôi chưa bao giờ có một bản ghi hai khối xóa - 2 byte đầu tiên của mỗi khối flash bị xóa là giá trị "bị xóa" 0xFFFF, hoặc hai byte đầu tiên của tổng kiểm tra Fletcher-16 (không bao giờ là 0xFFFF) trong tiêu đề của mỗi bản ghi.

Điều đó giúp cho việc quét nhanh vào lần tiếp theo được cấp nguồn và tìm phần đầu của nhật ký tròn - tôi chỉ phải nhìn vào hai byte đầu tiên của mỗi khối xóa để phân biệt giữa các khối "bị xóa" và "dữ liệu". (Tôi hơi lo lắng về "sự cố mất điện ở giữa khi xóa một khối" khiến hai byte đầu tiên bị xóa thành 0xFFFF nhưng để lại các byte không bị xóa ở giữa khối, vì vậy tôi đã viết mã cho vi điều khiển để kiểm tra cho việc này và khởi động lại quá trình "xóa một khối").

Vui lòng cho tôi biết nếu bạn tìm thấy các cấu trúc dữ liệu hoặc hệ thống tệp thân thiện với flash khác.


Cách tiếp cận của bạn nghe có vẻ tương tự như của tôi. Tuy nhiên, tôi sẽ đề nghị thêm một bước xoắn nhỏ khác: dự trữ một vài byte trong mỗi khối để chỉ ra rằng nó đã được "bắt đầu" và nó "đầy đủ". Tất cả các khối ngoại trừ các khối bị xóa sẽ được lập trình các bit "bắt đầu". Khi đến lúc xóa một khối, hãy đặt byte "đầy đủ" trên byte dữ liệu cuối cùng, sau đó xóa khối đó và sau đó ngay lập tức thiết lập bit "bắt đầu" của khối bị xóa cũ nhất. Khi khởi động, nếu bạn thấy khối "cuối cùng" là "đầy đủ", thay vì "bắt đầu", hãy làm lại việc xóa.
supercat

Cách tiếp cận như vậy có vẻ như quá mức cần thiết, nhưng nếu một khối flash bị xóa một phần, các byte có thể tự ý quyết định đọc FF hoặc một cái gì đó khác. Việc một khối xuất hiện trống không đảm bảo rằng các bit sẽ không tự động "xuất hiện" ở đó. Nếu bạn bị mất điện trong khi quá trình xóa đang diễn ra, hãy đợi một lát trong lần khởi động tiếp theo và sau đó lặp lại việc xóa ngay cả khi khối xuất hiện trống .
supercat

Cảm ơn thông tin, tôi sẽ xem xét sâu hơn một chút khi tôi thực sự nhấn mã cho bộ lưu trữ flash và cho bạn biết điều gì xảy ra.
Kris Bahnsen

@supercat: Cảm ơn bạn, nghe có vẻ là một ý tưởng tuyệt vời.
davidcary 17/03 '

@davidcary: Tôi không biết rằng tôi đã từng có một khối hoàn toàn trống và không, nhưng tôi đã có một khối sẽ mang lại kết quả khác nhau trong các lần đọc liên tiếp. Có thể khối đó đã được đọc không chính xác vì mã của tôi đã cố gắng lập trình nó bằng mọi cách, dẫn đến một sự nhầm lẫn kỳ lạ của dữ liệu được lập trình mới và rác đã bị gián đoạn cũ. Trong mọi trường hợp, một kịch bản trong đó một khối đôi khi xuất hiện trống hầu như không thực tế.
supercat

0

Đã được một vài năm nhưng tôi muốn theo dõi điều này trong trường hợp có ai khác đi lang thang. Dường như có một vài dự án hiện nay, được duy trì tích cực (kể từ tháng 1 năm 2020) là các hệ thống tập tin dành cho các bộ vi điều khiển được nhắm mục tiêu trong flash SP SPI.

Lưu ý rằng tôi đã không kiểm tra những điều này trong bất kỳ khả năng nào, nhưng họ thực hiện chính xác câu hỏi ban đầu đang tìm kiếm: "... cấu trúc dữ liệu đại diện cho một tập hợp các tệp truy cập ngẫu nhiên có thể thay đổi ..."

https://github.com/ARMmbed/littlefs - Được tạo bởi ARM, BSD được cấp phép

https://github.com/joembedded/JesFs - Không thực sự có vẻ được cấp phép, nhưng được thiết kế rất đặc biệt cho flash SPI NOR.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.