I am having a look to the generic_list.c in order to reuse the code for my own lists.
The serial_manager is using it for the SERIAL_MANAGER_NON_BLOCKING_MODE.
Nevertheless I can not see how can it work:
When adding elements to the list, we are passing the address of "link", which is type "list_element_t"
static void SerialManager_AddTail(list_t *queue, serial_manager_write_handle_t *node)
{
LIST_AddTail(queue, &node->link);
}
But when retrieving the element from the list
serial_manager_write_handle_t *writeHandle =
(serial_manager_write_handle_t *)LIST_GetHead(&handle->runningWriteHandleHead);
What we get from the list is a "list_element_t" (the "&node->link" previously added), the casting to "serial_manager_write_handle_t" does not work.
Am I missing something?
PS: I am using SDK 2.7.0 on a MK26
Actually what I think is missing here is something like this: (source is iot_linear_containers.h from amazon freertos)
/**
* @brief Calculates the starting address of a containing struct.
*
* @param[in] type Type of the containing struct.
* @param[in] pLink Pointer to a link member.
* @param[in] linkName Name of the #IotLink_t in the containing struct.
*/
#define IotLink_Container( type, pLink, linkName ) \
( ( type * ) ( void * ) ( ( ( uint8_t * ) ( pLink ) ) - offsetof( type, linkName ) ) )
Hi Roberto,
This is because list_element_t is a member of serial_manager_write_handle_t. Not only that, list_element_t is locate at the head of serial_manager_write_handle_t. So, the address of list_element_t is also equal to the serial_manager_write_handle_t address.
(serial_manager_write_handle_t *)(void *)LIST_GetHead(&handle->runningWriteHandleHead)
The type casting can work here.
Regards,
Jing