标签:pen info topic struct get error life 简单的 possible
The FIFO library provides a simple circular buffer implementation for storing bytes. The FIFO uses the size and buffer memory provided by the application on initialization.
// Create a FIFO structure app_fifo_t my_fifo; // Create a buffer for the FIFO uint16_t buffer_size = 8; uint8_t buffer[buffer_size]; // Initialize FIFO structure uint32_t err_code = app_fifo_init(&my_fifo, buffer, (uint16_t)sizeof(buffer));
The application must provide a FIFO structure and a memory buffer to the initialization function.
The FIFO structure (app_fifo_t) is passed by reference and will be initialized by the FIFO module. It ensures correct indexing when reading and writing data to the FIFO. The library module itself will not store state information, thus the application must ensure that the memory used by app_fifo_t is not reclaimed as long as the FIFO is in use.
The size of the buffer must be a power of two. As seen in the code example, the application must ensure that the buffer has a reserved memory space for the lifetime of the FIFO.
The app_fifo_t structure that is used to create a FIFO instance contains 4 members:
The FIFO is implemented as a circular buffer of size n. Whenever the nth element is added to the buffer, the index wraps over and counts from index zero. This can be summarized to i = count mod n
, where:
To simplify the index handling, the FIFO is restricted to require the buffer size n to be a power of two, because this reduces the modulus operation to become a simple AND operation with n-1. For example, if the buffer size n=8:
n = 8 = 0b00001000 n - 1 = 7 = 0b00000111
If n is a power of two, ANDing any number with n-1 is identical to the modulus operation of n. For example:
11 mod 8 = 3 11 AND 7 = 0b00001011 & 0b00000111 = 0b00000011 = 3
During initialization of the FIFO, a check is performed to ensure that the size n is a power of two.
The following image shows how the FIFO instance looks like when it is initialized. The two arrows on the top illustrate the read and write indexes. They both start at index 0, and all bytes in the buffer are free to be used.
To add an element to the FIFO, the application must use the app_fifo_put function. This is done by passing the FIFO structure and the data to app_fifo_put.
Example of adding an element to the FIFO:
uint8_t data = 88; uint32_t err_code; // Add an element to the FIFO err_code = app_fifo_put(&my_fifo, data);
When the new element is added to the buffer, the value supplied as parameter to the put function will be copied over to the current index of the write_pos member of the FIFO instance. When an element has been added to the FIFO, the write_pos member of the instance will be incremented by 1 to point to the next free byte. This is illustrated in Figure 2.
For each element added, the write_pos counter increments. This is illustrated in Figure 3.
If the FIFO is full, NRF_ERROR_NO_MEM will be returned.
To get an element from the FIFO, the application must use the app_fifo_get function. This is done by passing the FIFO structure and a reference, return_val
, for returning the data from app_fifo_get.
Example of fetching an element from the FIFO:
// Consume one element from FIFO uint8_t return_val; uint32_t err_code; err_code = app_fifo_get(&my_fifo, &return_val);
When app_fifo_get is called, the memory of the supplied by-reference parameter is filled with the value stored in the memory buffer. Then, the read_pos member of the FIFO instance is incremented to free the byte that was read. Therefore, each byte can be fetched only once. An example of a FIFO where two elements have been consumed is shown in Figure 4.
The read_pos and write_pos indexes have the same value when the FIFO is empty. This is the case when the FIFO is initialized, because both read_pos and write_pos are initialized to 0, and when all elements in the FIFO have been fetched. This is illustrated in Figure 5.
The FIFO can also be emptied by executing app_fifo_flush.
When the FIFO is empty, all calls to app_fifo_get will return NRF_ERROR_NOT_FOUND.
When write_pos == read_pos + n
, the buffer is full. All subsequent calls to app_fifo_put will return NRF_ERROR_NO_MEM.
It is possible to write and read multiple bytes at the same time. Writing to the FIFO is equivalent to adding multiple bytes, one at a time. Reading from the FIFO is equivalent to fetching multiple bytes, one at a time.
Example of a write operation:
uint32_t err_code; uint32_t data_len = 5; uint8_t write_data = {1, 2, 3, 4, 5}; // Write 5 elements to the FIFO return_val = app_fifo_write(&my_fifo, &write_data, &data_len); // Check if write was successful if (return_val == NRF_SUCCESS) { // Check if write was partial if (data_len < 5) { // Attempt another write operation using data_len value as offset } } else if (return_val == NRF_ERROR_NO_MEM) { // FIFO is full } else { // API parameters incorrect, should not happen } Example of a read operation: uint32_t return_val; uint32_t data_len = 5; uint8_t read_data[5]; // Read 5 elements to the FIFO return_val = app_fifo_read(&my_fifo, &read_data, &data_len); // Check if write was successful if (return_val == NRF_SUCCESS) { // Check if read was partial if (data_len < 5) { // Not as many elements in array as requested } } else if (return_val == NRF_ERROR_NOT_FOUND) { // FIFO is empty } else { // API parameters incorrect, should not happen }
To query how many elements are available in the FIFO, the application can use the app_fifo_read function. To query how many elements can be written to the FIFO, the application can use the app_fifo_write function.
Example for querying how many bytes can be written to the FIFO:
uint32_t err_code; uint32_t data_len; // Request number of elements that can be written to the FIFO err_code = app_fifo_write(&my_fifo, NULL, &data_len); // Check if request was successful if (err_code == NRF_SUCCESS) { // data_len contains the number of bytes that can be written } else if (err_code == NRF_ERROR_NO_MEM) { // FIFO is full } else { // API parameters incorrect, should not happen } Example for querying how many bytes can be read from the FIFO: uint32_t err_code; uint32_t data_len; // Request number of elements in the FIFO err_code = app_fifo_read(&my_fifo, NULL, &data_len); // Check if request was successful if (err_code == NRF_SUCCESS) { // data_len contains the number of elements that can be read } else if (err_code == NRF_ERROR_NOT_FOUND) { // FIFO is empty } else { // API parameters incorrect, should not happen }
标签:pen info topic struct get error life 简单的 possible
原文地址:https://www.cnblogs.com/damaohai/p/13803688.html