문제

플래시 칩에 원형 대기열에 다양한 길이의 품목을 저장해야합니다. 각 항목에는 캡슐화가 있으므로 다음 항목이 얼마나 큰지, 다음 항목이 시작되는지 알 수 있습니다. 버퍼에 충분한 항목이 있으면 처음으로 감싸게됩니다.

플래시 칩에 원형 대기열을 저장하는 좋은 방법은 무엇입니까?

내가 저장하고 싶은 수만 개의 품목이있을 가능성이 있습니다. 따라서 처음부터 시작하여 버퍼의 끝까지 읽는 것은 끝까지 검색하는 데 시간이 걸리기 때문에 이상적이지 않습니다.

또한 원형이기 때문에 첫 번째 항목을 마지막 항목과 구별 할 수 있어야합니다.

마지막 문제는 이것이 플래시로 저장되므로 각 블록을 지우는 데 시간이 많이 걸리고 각 블록에 대해 세트 한 번만 수행 할 수 있다는 것입니다.

도움이 되었습니까?

해결책

먼저, 블록 관리 :

각 블록의 시작 부분에 더 작은 헤더를 넣으십시오. "가장 오래된"과 "최신"을 추적하는 데 필요한 주요 사항은 블록 번호이며, 단순히 모듈로를 증가시킵니다. 케이. 케이 총 블록 수보다 더 커야합니다. 이상적으로는 만들어집니다 케이 최대 값 (예 : 0xffff)보다 적으므로 지워진 블록이 무엇인지 쉽게 알 수 있습니다.

스타트 업시 코드는 각 블록의 헤더를 차례로 읽고 N 순서에서 첫 번째 및 마지막 블록을 찾습니다.I+1 = (n + 1) 모듈로 k. 지워진 블록 (블록 번호는 0xffff) 또는 어떻게 든 손상된 데이터 (예 : 불완전한 지우기)에 의해 혼란스러워지지 않도록주의하십시오.

각 블록 내에서

각 블록은 처음에 비어 시작합니다 (각 바이트는 0xff입니다). 각 레코드는 단순히 다른 레코드 후에 작성됩니다. 고정 크기 레코드가있는 경우 간단한 색인으로 액세스 할 수 있습니다. 가변 크기 레코드가있는 경우 읽기를 읽으려면 블록의 시작 부분에서 링크 된 목록 스타일을 스캔해야합니다.

가변 크기 레코드를 원하지만 선형 스캔을 피하려면 각 레코드에 잘 정의 된 헤더가있을 수 있습니다. 예를 들어 0을 레코드 구분 기자로 사용합니다 코브-encode (또는 COBS/R-encode) 각 레코드. 또는 원하는 바이트를 구분 기자로 사용하고 각 레코드에서 발생하는 경우 바이트를 '탈출'하십시오 ( PPP 프로토콜).

스타트 업에서 최신 블록을 알면 최신 레코드를 선형 스캔 할 수 있습니다. 또는 고정 된 크기의 레코드가 있거나 구분 구분동이있는 경우 이진 검색을 수행 할 수 있습니다.

일정을 지우십시오

일부 플래시 메모리 칩의 경우 블록을 지우는 데 5 초가 걸릴 수 있습니다. 배경 작업으로 지우기를 예약하는 것을 약간 "미리"하는 것을 고려하십시오. 예를 들어 현재 블록이 x% 가득 차면 다음 블록을 지우기 시작합니다.

레코드 번호 매기기

레코드 번호를 원할 수도 있습니다. 내가 과거에했던 방식은 각 블록의 헤더에 첫 번째 레코드의 레코드 번호를 넣는 것입니다. 그런 다음 소프트웨어는 블록 내의 각 레코드 수를 유지해야합니다.

체크섬 또는 CRC

손상된 데이터를 감지하려면 (예 : 예상치 못한 정전으로 인해 불완전한 쓰기 또는 지우기) 각 레코드 및 블록 헤더에 체크섬 또는 CRC를 추가 할 수 있습니다. 참고 블록 헤더 CRC는 각각의 새 레코드가 작성 될 때 다시 작성할 수 없기 때문에 레코드가 아닌 헤더 자체 만 커버됩니다.

다른 팁

첫 번째 레코드의 시작과 마지막 레코드의 끝에 대한 포인터가 포함 된 별도의 블록을 유지하십시오. 총 레코드 수 등과 같은 자세한 정보를 보관할 수도 있습니다.

처음에 공간이 부족할 때까지 레코드를 추가하는 것은 버퍼 끝에 기록하고 테일 포인터를 업데이트하는 것만 큼 간단합니다.

공간을 되 찾아야하므로 현재 레코드를 맞출 수 있도록 충분한 레코드를 삭제하십시오. 레코드를 삭제할 때 헤드 포인터를 업데이트하십시오.

여분의 공간이 얼마나 해방되었는지 추적해야합니다. 마지막 레코드의 끝에 대한 포인터를 유지하면 다음에 레코드를 추가해야 할 때는 첫 번째 레코드와의 포인터와 비교하여 더 이상 레코드를 삭제 해야하는지 확인할 수 있습니다.

또한 NAND 인 경우 귀하 또는 플래시 컨트롤러는 탈 블로킹 및 마모 수준을 수행해야하지만 원형 버퍼에 공간을 할당하는 것보다 낮은 층에 있어야합니다.

나는 지금 그것을 얻는 것 같아요. 가장 큰 문제는 녹음을위한 사용 가능한 공간을 채운 것 같습니다. 다음에 어떻게됩니까? 새로운 데이터는 가장 오래된 데이터를 덮어 써야합니다. 즉, 원형 버퍼의 의미를 믿습니다. 그러나 데이터는 고정 길이가 아니기 때문에 둘 이상의 레코드를 덮어 쓸 수 있습니다.

나는 길이의 변동성 양이 모든 것을 고정 길이로 패딩하는 것이 옵션이 아닐 정도로 높다고 가정합니다.

쓰기 세그먼트는 다음 레코드의 시작을 나타내는 주소를 추적해야합니다. 미리 쓸 블록의 크기를 알고 있다면 논리 버퍼의 끝에서 끝날지 말해서 '0'에서 다시 시작할 것인지 알 수 있습니다. 나는 마지막에 일부와 일부와 일부와 레코드를 나누지 않을 것입니다.

별도의 레지스터는 시작을 추적 할 수 있습니다. 이것은 아직 덮어 쓰지 않은 가장 오래된 데이터입니다. 데이터를 읽으 러 가면 시작하는 곳입니다.

그런 다음 데이터 작성자는 쓰기 시작 주소와 커밋하려는 데이터의 길이를 감안할 때, 읽기 레지스터를 충돌시켜야하는 경우 첫 번째 블록을 검사하고 길이를보고 다음 레코드로 전진 할 때까지 확인합니다. 데이터가 무엇이든 쓸 수있는 충분한 공간이 있습니다. 서면 데이터의 끝과 가장 오래된 데이터의 시작 사이에 사는 정크 데이터의 차이가있을 것입니다. 그러나 이런 식으로, 당신은 단지 주소를 오버 헤드로 작성하고 블록을 재정렬하지 않을 수 있습니다.

적어도, 아마도 내가 할 것입니다. HTH

세 가지 옵션이 있습니다.

옵션 1 : 모든 것을 같은 크기로 채우는 것입니다. 이것은 간단합니다. 버퍼의 헤드와 꼬리에 포인터를 저장하여 글을 어디에서 읽을 것인지, 어디서 읽을 것인지 알 수 있도록 각 객체의 크기를 사용하여 오프셋을 얻습니다. 다음으로, 이는 링크 된 목록과 같이 버퍼를 가로 지르는 것을 의미합니다. 일명 항목 5000이 필요한 경우 느리게 만듭니다.

옵션 2 : 원형 버퍼의 실제 데이터에 포인터 만 저장하는 것입니다. 실제 데이터를 원형 버퍼에 저장하고 패드하지 않으면 1 개의 새로운 데이터 객체로 여러 항목을 재직하는 상황에 빠질 수 있습니다.

실제 데이터를 플래시에 저장하면 대부분의 플래시는 일종의 마모 레벨링이 내장되어 있으므로 동일한 위치를 여러 번 덮어 쓰는 것에 대해 걱정할 필요가 없다면 IC는 실제로 칩에 저장할 위치를 파악합니다. 다음으로 사용 가능한 여유 공간에 편지를 보내십시오.

즉, 원형 버퍼의 최대 크기를 선택 해야하는 방식은 데이터 변동성에 따라 다릅니다. 데이터의 크기가 단지 몇 바이트 만 말하면, 단지 몇 바이트 만 말하면, 당신은 그것을 패드하고 옵션 1을 사용해야합니다. 해당 크기 중 플래시에 맞습니다. 버퍼의 최대 항목 수로 사용하십시오. 이것은 당신이 많은 공간을 낭비한다는 것을 의미합니다.

옵션 3 : 객체가 실제로 크기가 될 수있는 경우 파일 시스템 만 사용해야하는 지점에서 파일의 이름을 순서대로 이름을 지정하고 새 항목이 크면 전체를 염두에두면 삭제해야 할 수도 있습니다. 옵션 2가 여러면에서 간단한 파일 시스템이므로 옵션 2의 확장 일뿐입니다.

플래시의 "원형"은 블록 크기를 기준으로 수행 할 수 있습니다. 즉,이 버퍼에 할당하는 플래시 블록의 양을 선언해야합니다.

버퍼의 실제 크기는 각각의 특정 시간에 n-1 (n은 블록 수)과 n 사이에있다.

각 블록은 다른 블록보다 오래된 블록을 결정하는 데 사용할 수있는 순차적 번호 또는 타임 스탬프가 포함 된 헤더로 시작해야합니다.

각 항목은 헤더와 바닥 글로 캡슐화되었습니다. 기본 헤더에는 원하는 내용이 포함되어 있지만이 헤더에 따라 항목의 크기를 알아야합니다. 기본 바닥 글은 0xffffffff입니다. 이 값은 널 종료를 나타냅니다.

RAM에서 가장 오래된 블록에 대한 포인터와 최신 블록 및 가장 오래된 아이템 및 최신 항목에 대한 포인터를 저장해야합니다. Power Up에서는 모든 블록을 넘어서 관련 블록을 찾아이 멤버를로드합니다.

새 항목을 저장하려면 최신 블록 에이 항목에 충분한 공간이 포함되어 있는지 확인하십시오. 이전 항목의 끝에 항목을 저장하고 이전 바닥 글을 변경 하여이 항목을 가리 키도록합니다. 공간이 충분하지 않은 경우 가장 오래된 블록을 지울 필요가 있습니다. 이 블록을 지우기 전에 가장 오래된 블록 멤버 (RAM)를 변경하여 다음 블록을 가리키고 가장 오래된 항목은이 블록의 첫 번째 항목을 가리 킵니다. 그런 다음이 블록에 새 항목을 저장하고 최신 항목의 바닥 글을 변경 하여이 항목을 가리킬 수 있습니다.

나는 설명이 복잡하게 들릴지 모르지만 프로세스는 매우 간단하고 글을 올바르게 작성하면 전력 실패를 안전하게 만들 수 있습니다 (항상 글의 순서를 염두에 두십시오).

버퍼의 원형이 플래시에 저장되지 않았지만 플래시에는 블록 헤더 및 항목 헤더에 따라 결정할 수있는 항목이 포함 된 블록 만 포함되어 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top