Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

About Queue library (SDK 17.1.0)

Hi, Nordic

Recently, I'm experimenting with the queue library.

I found some strange problems:

1. When the data types of my data structure members are not unique, using queue will cause the whole system to crash without even error codes

typedef struct {
  bool flag;
  uint8_t data1;
  uint32_t data2;
  uint8_t data3;
  uint8_t data4;
  uint8_t data5;
  uint8_t data6;
} data_t;

NRF_QUEUE_DEF(data_t, m_data_queue, 255*sizeof(data_t), NRF_QUEUE_MODE_NO_OVERFLOW);

data_t test_data;

test_data.flag = true;
test_data.data1 = 0x01;
test_data.data2 = 0xAABBCC;
test_data.data3 = 0x03;
test_data.data4 = 0x04;
test_data.data5 = 0x05;
test_data.data6 = 0x06;

ret = nrf_queue_write(&m_data_queue, &test_data, sizeof(test_data));
APP_ERROR_CHECK(err_code);

data_t data_read;

ret = nrf_queue_read(&m_data_queue, &data_read, sizeof(data_read));
APP_ERROR_CHECK(err_code);

The whole system crashed before the program even performed error checking for queue writes

2. So I modified it according to other examples, as follows

typedef struct {
 uint8_t data[9];
} data_t;

NRF_QUEUE_DEF(uint8_t, m_data_queue, 255*sizeof(data_t), NRF_QUEUE_MODE_NO_OVERFLOW);

data_t test_data;

test_data.data[0] = true;
test_data.data[1] = 0x01;
test_data.data[2] = 0xAA
test_data.data[3] = 0xBB;
test_data.data[4] = 0xCC;
test_data.data[5] = 0x03;
test_data.data[6] = 0x04;
test_data.data[7] = 0x05;
test_data.data[8] = 0x06;

ret = nrf_queue_write(&m_data_queue, &test_data.data, sizeof(test_data));
APP_ERROR_CHECK(err_code);

data_t data_read;

ret = nrf_queue_read(&m_data_queue, &data_read.data, sizeof(data_read));
APP_ERROR_CHECK(err_code);

My questions are as follows:

In 1, do I have any misunderstandings? If so, please point it out!!!

In 2, can I change the data type in NRF_QUEUE_DEF from uint8_t to data_t?

In 2, I have 255 groups of data. What should I do if I want to take the 3rd to 5th bytes (0xaabbcc) in each group of data as a condition for overwriting the data content of the queue? Is it necessary to perform queue reading to read all the contents in the queue, open up a space to compare each group of data, and then write all the updated contents to the queue again? Is there a more elegant way, such as specifying the write location of the queue or other ways?

Regards,

June6

Parents
  • Hi there,

    Is the issue mitigated If you set data2 type to uint8_t instead of uint32_t?

    regards

    Jared

  • No, it hasn't improved.

    Moreover, I found that as long as the data type parameters filled in NRF_QUEUE_DEF are user-defined structures, the number of members of that structure cannot be too many.

    Specifically, I tested in the second test segment. If the array in data_t is defined as data [7] or larger, there will be a problem.

    On the contrary, if the data type filled in NRF_QUEUE_DEF is uint8_ t. Then no matter how many members of the structure are, there is no problem.

    This phenomenon is very strange. It is reasonable to say that although the parameter passed into the actual operation function is a pointer, the space occupied by my structure members is a fixed size, so I don't need to apply for additional memory. I can't figure it out

  • I have finished reading and writing, but now I have a new problem to confirm.

    Every time I finish reading, does it mean that I have taken out the data in the queue, and the data I have read no longer exists in the queue? In other words, for the purpose of query, I need to write back the read data again. Is this logic correct?

    By the way, the queue library is really difficult to use. Peek can only read the first byte of data. Pop and read will automatically clear the data out of the queue after reading the data.

  • Yes, that is correct. I believe the queue implementation in the SDK follows the normal definition of a queue. Is there a specific reason for why you're using a queue?

  • Well, maybe my usage scenario is so special that I don't care about the standard of the queue and complain

  • It is only used to temporarily store fixed length data, and finally it will be written to flash. However, data storage and reading will be a little frequent, so first use the queue to cache these data.

  • In addition, I still don't understand why def uses its own data structure, and its member size can't exceed 6. You can also try the following code snippet in the routine.

    typedef struct {
     uint8_t data[7];
    } data_t;
    
    NRF_QUEUE_DEF(data_t, m_data_queue, 255*sizeof(data_t), NRF_QUEUE_MODE_NO_OVERFLOW);
    
    int main (void) {
        data_t test_data;
        
        test_data.data[0] = 0x01;
        test_data.data[1] = 0x01;
        test_data.data[2] = 0xAA
        test_data.data[3] = 0xBB;
        test_data.data[4] = 0xCC;
        test_data.data[5] = 0x03;
        test_data.data[6] = 0x04;
        
        ret = nrf_queue_write(&m_data_queue, &test_data.data, sizeof(test_data));
        APP_ERROR_CHECK(ret);
        
        data_t data_read;
        
        ret = nrf_queue_read(&m_data_queue, &data_read.data, sizeof(data_read));
        APP_ERROR_CHECK(ret);
    }
    When running to nrf_queue_write, the system will crash 100%. The phenomenon is like using a wild pointer to cause memory overflow. No error code will be reported

Reply
  • In addition, I still don't understand why def uses its own data structure, and its member size can't exceed 6. You can also try the following code snippet in the routine.

    typedef struct {
     uint8_t data[7];
    } data_t;
    
    NRF_QUEUE_DEF(data_t, m_data_queue, 255*sizeof(data_t), NRF_QUEUE_MODE_NO_OVERFLOW);
    
    int main (void) {
        data_t test_data;
        
        test_data.data[0] = 0x01;
        test_data.data[1] = 0x01;
        test_data.data[2] = 0xAA
        test_data.data[3] = 0xBB;
        test_data.data[4] = 0xCC;
        test_data.data[5] = 0x03;
        test_data.data[6] = 0x04;
        
        ret = nrf_queue_write(&m_data_queue, &test_data.data, sizeof(test_data));
        APP_ERROR_CHECK(ret);
        
        data_t data_read;
        
        ret = nrf_queue_read(&m_data_queue, &data_read.data, sizeof(data_read));
        APP_ERROR_CHECK(ret);
    }
    When running to nrf_queue_write, the system will crash 100%. The phenomenon is like using a wild pointer to cause memory overflow. No error code will be reported

Children
Related