Hello everybody,
I am trying to use Queue Data Struct in order to implement an alarm history.
The documentation is quite poor and there is not an example.
When I enqueue the second element, I get an 0x1d (29) error code that I could not find its mean anywhere.
After, for example, enqueue 10 elements, the queue size is correct (=10).
When I read the '_queue_head', that should be the first element enqueued, I get the last one (tail).
Then I keep going with '_queue_next' and all elements are the same, i.e. the last one (tail).
A simple code I implemented (based upon MFS code) just to test the feature:
#include <mqx.h>
#include <fio.h>
typedef struct _mfs_drive_struct
{
uint32_t DATA_START_SECTOR;
QUEUE_STRUCT HANDLE_LIST;
uint32_t FAT_TYPE;
} _MFS_DRIVE_STRUCT, *_MFS_DRIVE_STRUCT_PTR;
/*
** file handle as defined by MFS
*/
typedef struct _mfs_handle
{
QUEUE_ELEMENT_STRUCT HEADER_PTR;
long LOCATION;
long SIZE;
uint32_t VALID;
} _MFS_HANDLE, * _MFS_HANDLE_PTR;
void _test_queue()
{
_MFS_DRIVE_STRUCT ds;
_MFS_DRIVE_STRUCT_PTR drive_ptr=&ds;
_MFS_HANDLE_PTR handle;
_MFS_HANDLE hp, q_error;
_MFS_HANDLE_PTR handle_ptr=&hp;
_MFS_HANDLE_PTR next_handle;
_queue_init(&drive_ptr->HANDLE_LIST, 0);
for(int i = 0; i < 10; i++)
{
handle_ptr->SIZE = i*5;
_queue_enqueue( &drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) handle_ptr);
printf("erro=0x%02x\n", _queue_test (&drive_ptr->HANDLE_LIST, (void*)&q_error));
}
next_handle = (_MFS_HANDLE_PTR) _queue_head(&drive_ptr->HANDLE_LIST);
printf("head: %d\n", next_handle->SIZE);
while ( next_handle )
{
next_handle = (_MFS_HANDLE_PTR) _queue_next(&drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) next_handle);
printf("next: %d\n", next_handle->SIZE);
}
}
Solved! Go to Solution.
Interesting. This is the MQX_CORRUPT_QUEUE error code.
Perhaps the _queue_enqueue cannot handle re-using the same element each time. The QUEUE_ELEMENT_STRUCT pointers are getting mangled in your for loop, here:
_queue_enqueue( &drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) handle_ptr);
Can you make hp an array of 10 elements, and change handle_ptr = hp[i]; on each loop?
Cheers,
+Joel.
Hi Sandro,
I'm not sure your parameters for _queue_test() are correct.
you have:
_MFS_HANDLE q_error;
_queue_test (&drive_ptr->HANDLE_LIST, (void*)&q_error));
But the intent of the second parameter is to return a _pointer_ to the element in error, and not a copy of the full element. Try passing in the address of pointer type:
QUEUE_ELEMENT_STRUCT_PTR q_error;
_queue_test(&drive_ptr->HANDLE_LIST, (void*)&q_error));
Hope this helps!
+Joel.
Hi Joel,
Thanks for contributing.
Yes, you are right, it was a mistake but, unfortunately, it did not change the wrong behavior, I mean, it still returning 0x1d error and I just can read the tail element, not the others.
thank you and best regards,
Sandro
Interesting. This is the MQX_CORRUPT_QUEUE error code.
Perhaps the _queue_enqueue cannot handle re-using the same element each time. The QUEUE_ELEMENT_STRUCT pointers are getting mangled in your for loop, here:
_queue_enqueue( &drive_ptr->HANDLE_LIST, (QUEUE_ELEMENT_STRUCT_PTR) handle_ptr);
Can you make hp an array of 10 elements, and change handle_ptr = hp[i]; on each loop?
Cheers,
+Joel.
Hi Joel and David,
I was trying to understand the David's approach when Joel unveiled the problem.
David, thank you very much for your help but I think MQX needs a better documentation - where are the error codes of '_queue_test()'? A little and silly example will be very appreciated to.
Joel, thank you for helping to understand the David's approach.
best regards,
Sandro
Hi Sandros,
I took a slightly different approach to work with queues and see how they are working.
I started with: C:\Freescale\Freescale_MQX_4_1_Vybrid\mqx\examples\test\test.c
Borrowed code from: C:\Freescale\Freescale_MQX_4_1_Vybrid\mqx\examples\lwevent\lwevent.c
Attached is my modified test.c and BSP/user_config.h.
I tested on my TWR-VF65GS10 Rev G tower kit with TWR-SER card so that I could use the DB-9 serial interface to my terminal utility.
I am using ARM DS5 IDE and lasted Vybrid MQX as path shows above.
The project is running test_twrvf65gs10_m4 on the Cortex M4 code and not the Cortex A5.
Each pass of the code will first call " result = _lwevent_test(&error_ptr, &error2_ptr);" .
The test will check the lwevent queues so if you step into you can see that process.
The code will add lwevent as loop_cnt grows: if (_lwevent_create(&lwevent_array[loop_cnt],0) != MQX_OK)
Using DS5 I can see the OS Data Lightweight Events "Event Group*" grow as well.
After creating 11 new lwevents, the loop_cnt will decrement to 0 each loop and during that portion of the code we destroy lwevents.
Reference: if (_lwevent_destroy(&lwevent_array[loop_cnt]) != MQX_OK)
Stepping into the create and destroy code show how the queue process is being implemented.
Terminal Output:
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 0
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 1
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 2
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 3
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 4
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 5
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 6
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 7
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 8
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 9
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 10
_lwevent_test passed... _lwevent_create passed... All tests passed with loop_cnt = 10
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 9
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 8
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 7
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 6
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 5
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 4
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 3
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 2
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 1
_lwevent_test passed... _lwevent_destroy passed... All tests passed with loop_cnt = 0
Regards,
David