Skip to content

andkae/SPI-Flash-Circular-Buffer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Test

SPI Flash Circular Buffer

C Library to transform a physical SPI Flash into a arbitrary number of logical circular buffers. The interface between SFCB and SPI core is realized as shared memory.

Features

  • Arbitrary SPI Flash support, selectable via -D at compile time
  • Arbitrary number of circular buffer queues (cbID) in a single SPI flash
  • Interaction between circular buffer and SPI interface is realized as shared memory
  • File system (LittleFS, SPIFFS) free

Releases

Version Date Source Change log
latest latest.zip

How-to

Clone

git clone --recursive https://github.com/andkae/SPI-Flash-Circular-Buffer.git

Build

The Makefile builds the repository with unit test:

$ make
gcc -c -O -Wall -Wextra -Wconversion -I . -I ../ -DW25Q16JV ./test/sfcb_test.c -o ./test/sfcb_test.o
gcc -c -O -Wall -Wextra -Wconversion -I . -I ../ -DW25Q16JV -DSFCB_PRINTF_EN ./spi_flash_cb.c -o ./test/sfcb.o
gcc -c -O -Wall -Wextra -Wconversion -I . -I ../ -DW25Q16JV  ./test/spi_flash_model/spi_flash_model.c -o ./test/spi_flash_model.o
gcc ./test/sfcb_test.o ./test/sfcb.o ./test/spi_flash_model.o -Wall -Wextra -I. -lm -o ./test/sfcb_test

The library part itself can be built with:

gcc -c -O -Wall -Wextra -Wconversion -I . -DW25Q16JV -Werror ./spi_flash_cb.c -o ./test/sfcb.o

The flash memory W25Q16JV was selected via compile switch -D.

Example

Test

To run the unit test call:

$ ./test/sfcb_test

Init

Initializes SFCB common handle and assigns memory.

int sfcb_init (t_sfcb *self, void *cb, uint8_t cbLen, void *spi, uint16_t spiLen);

Arguments:

Arg Description
self SFCB storage element
cb Circular buffer queue memory
cbLen max. number of cb queues
spi SFCB / SPI core exchange buffer
spiLen spi buffer size in bytes

Return:

Exit codes

New queue

Creates a new logical independent circular buffer queue in the SPI Flash.

int sfcb_new_cb (t_sfcb *self, uint32_t magicNum, uint16_t elemSizeByte, uint16_t numElems, uint8_t *cbID);

Arguments:

Arg Description
self SFCB storage element
magicNum Magic number, needs to be unique for every queue on the same SPI Flash
elemSizeByte Payload size in byte, header/footer causes
numElems minimal number of required elements in queue, rounded up to next full SECTOR
cbID assigned ID to this queue, needed for all further requests

Return:

Exit codes

Busy

Checks if SFCB is processing another request.

int sfcb_busy (t_sfcb *self);

Arguments:

Arg Description
self SFCB storage element

Return:

Exit codes

Error

In last request ended with error.

int sfcb_isero (t_sfcb *self);

Arguments:

Arg Description
self SFCB storage element

Return:

Exit codes

Build

Acquires all queue information from SPI flash. Needed after calling sfcb_add to update all management information.

int sfcb_mkcb (t_sfcb *self);

Arguments:

Arg Description
self SFCB storage element

Return:

Exit codes

Add (Append)

Append bytes to the current selected circular buffer queue element.

int sfcb_add (t_sfcb *self, uint8_t cbID, void *data, uint16_t len);

Arguments:

Arg Description
self SFCB storage element
cbID circular buffer queue to interact
*data pointer to write data
len number of bytes in *data

Return:

Exit codes

Add Done

Force writing the Footer if not all available bytes in the circular buffer queue element are occupied by Add. The Footer is used to detect an complete writing of an element. The general recommendation is to call sfcb_add_done every time when you completed the queue element writing.

int sfcb_add_done (t_sfcb *self, uint8_t cbID);

Arguments:

Arg Description
self SFCB storage element
cbID circular buffer queue to interact

Return:

Exit codes

Get Payload Offset

Acquire the current number of written bytes to queues element. Enables multistage data object writing to circular buffer element.

uint16_t sfcb_get_pl_wrcnt (t_sfcb *self, uint8_t cbID);

Arguments:

Arg Description
self SFCB storage element
cbID circular buffer queue to interact

Return:

Write byte count of queue element.

Get Last

Read last written queue element back.

int sfcb_get_last (t_sfcb *self, uint8_t cbID, void *data, uint16_t len, uint32_t *elemID);

Arguments:

Arg Description
self SFCB storage element
cbID circular buffer queue to interact
*data pointer to read data
len number of bytes in *data
*elemID queue element number

Return:

Exit codes

Flash raw read

Raw data read from flash.

int sfcb_flash_read (t_sfcb *self, uint32_t adr, void *data, uint16_t len);

Arguments:

Arg Description
self SFCB storage element
adr SPI Flash memory address
*data pointer to read data
len number of bytes in *data

Return:

Exit codes

Worker

Services circular buffer layer request as well SPI packet processing. This function should called in a time based matter. The SPI data packet transfer should use an ISR based dataflow.

void sfcb_worker (t_sfcb *self);

Arguments:

Arg Description
self SFCB storage element

Return:

None.

SPI packet size

By sfcb_worker created SPI packet size in bytes.

uint16_t sfcb_spi_len (t_sfcb *self);

Arguments:

Arg Description
self SFCB storage element

Return:

Byte Count of SPI packet.

Flash Size

Get SFCB compiled flash type total size.

uint32_t sfcb_flash_size (void);

Return:

Size in bytes.

Highest queue element number

Get highest element number of circular buffer queue cbID.

uint32_t sfcb_idmax (t_sfcb *self, uint8_t cbID);

Arguments:

Arg Description
self SFCB storage element
cbID circular buffer queue to interact

Return:

Highest element number.

Return: Exit codes

Value Description
SFCB_OK Accepted
SFCB_E_NO_FLASH no flash type selected, use -D
SFCB_E_MEM not enough memory assigned in sfcb_init
SFCB_E_FLASH_FULL Flash capacity exceeded
SFCB_E_WKR_BSY sfcb_worker is busy, wait
SFCB_E_NO_CB_Q circular buffer queue cbID not existent
SFCB_E_WKR_REQ circular buffer management data not prepared for request, run sfcb_mkcb
SFCB_E_CB_Q_MTY no valid entries in queue

Memory organization

The SFCB supports an arbitrary number of circular buffer queues. Each circular buffer starts at the lowest free SPI Flash address. The Flash architecture requires an dedicated data clear - so called Sector Erase. Through this limitation needs to be at least two sectors allocated. Otherwise would the overwrite of the first written element result in an complete circular buffer queue overwrite without keeping any previous entries. Every new entry is marked with the incremented highest 32bit IdNum and MagicNum. The MagicNum ensures the detection of an occupied circular buffer queue element.

An exemplary memory organization for 240 bytes payload and 32 elements (= two sectors) shows the figure below:

Example circular buffer queue 0 FLASH memory organization


References

Releases

No releases published

Packages

No packages published