Hi,
I cant get my receive_task to open the serial device in non-blocking mode. This is what I have found:-
MQX calls _io_serial_default_init(); from init_bsp.c during system initialisation which leaves the driver open and sets the default kernel_data->INIT.IO_OPEN_MODE = BSP_DEFAULT_IO_OPEN_MODE (Note This is auto generated during the MQX bsp lib build)
where BSP_DEFAULT_IO_OPEN_MODE is defined as #define BSP_DEFAULT_IO_OPEN_MODE (void *) (IO_SERIAL_XON_XOFF | IO_SERIAL_TRANSLATION | IO_SERIAL_ECHO)
_io_serial_default_init() call kernel_data->PROCESSOR_STDIN = _io_fopen((char *)kernel_data->INIT.IO_CHANNEL,(char *)kernel_data->INIT.IO_OPEN_MODE);
Which at line 61 (below) opens the device in the default mode. When my receive_task makes a call to fopen in non-blocking mode (shown below at line 84) it calls _mqx_int _io_serial_polled_open where at line 136 it reports that the device is already open and returns leaving the open mode unchanged. Please advise the correct way to override this behaviour rather than me just hack it. Thanks
MQX_FILE_PTR _io_fopen(const char *open_type_ptr,const char *open_mode_ptr )
{ /* Body */
KERNEL_DATA_STRUCT_PTR kernel_data;
MQX_FILE_PTR file_ptr;
IO_DEVICE_STRUCT_PTR dev_ptr;
char *dev_name_ptr;
char *tmp_ptr;
_mqx_int result;
_GET_KERNEL_DATA(kernel_data);
_lwsem_wait((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
dev_ptr = (IO_DEVICE_STRUCT_PTR)((void *)kernel_data->IO_DEVICES.NEXT);
while (dev_ptr != (void *)&kernel_data->IO_DEVICES.NEXT) {
dev_name_ptr = dev_ptr->IDENTIFIER;
tmp_ptr = (char *)open_type_ptr;
while (*tmp_ptr && *dev_name_ptr &&
(*tmp_ptr == *dev_name_ptr))
{
++tmp_ptr;
++dev_name_ptr;
} /* Endwhile */
if (*dev_name_ptr == '\0') {
/* Match */
break;
} /* Endif */
dev_ptr = (IO_DEVICE_STRUCT_PTR)((void *)dev_ptr->QUEUE_ELEMENT.NEXT);
} /* Endwhile */
_lwsem_post((LWSEM_STRUCT_PTR)&kernel_data->IO_LWSEM);
if (dev_ptr == (void *)&kernel_data->IO_DEVICES.NEXT) {
return(NULL);
} /* Endif */
file_ptr = (MQX_FILE_PTR)_mem_alloc_system_zero((_mem_size)sizeof(MQX_FILE));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
if (file_ptr == NULL) {
return(NULL);
} /* Endif */
#endif
_mem_set_type(file_ptr, MEM_TYPE_FILE_PTR);
file_ptr->DEV_PTR = dev_ptr;
if (dev_ptr->IO_OPEN != NULL) {
result = (*dev_ptr->IO_OPEN)(file_ptr, (char *)open_type_ptr, (char *)open_mode_ptr); //Line 61
if (result != MQX_OK) {
_task_set_error(result);
_mem_free(file_ptr);
return(NULL);
} /* Endif */
} /* Endif */
return(file_ptr);
} /* Endbody */
#define TIMEOUT_ERR false;
void receive_task(uint32_t initial_data )
{
MQX_FILE_PTR rs232_dev = NULL;
char data_buffer[5] = {0};
uint32_t num_chars;
bool timed_out;
// receives characters okay but blocks. Note IO_SERIAL_NON_BLOCKING has no effect?
rs232_dev = fopen( "ttyc:", ( char const * ) IO_SERIAL_NON_BLOCKING ); // Line84
while(TRUE)
{
/* Read the data(s) in non blocking mode .. */
_time_delay( 150 );
num_chars = fread( data_buffer, 1, 2 , rs232_dev);
if (num_chars)
{
if(data_buffer[0] == 'r' )
{
/* receive all the other chars .. */
// post data to callee task - TBD
data_buffer[0] = 0;
}
}
else
{
timed_out = TIMEOUT_ERR;
//post timout event to callee - TBD
}
};
}
_mqx_int _io_serial_polled_open
(
/* [IN] the file handle for the device being opened */
MQX_FILE_PTR fd_ptr,
/* [IN] the remaining portion of the name of the device */
char *open_name_ptr,
/* [IN] the flags to be used during operation:
** echo, translation, xon/xoff, encoded into a pointer.
*/
char *flags
)
{
IO_DEVICE_STRUCT_PTR io_dev_ptr;
IO_SERIAL_POLLED_DEVICE_STRUCT_PTR polled_dev_ptr;
_mqx_uint result = MQX_OK;
_mqx_uint ioctl_val;
io_dev_ptr = fd_ptr->DEV_PTR;
polled_dev_ptr = (void *)io_dev_ptr->DRIVER_INIT_PTR;
if (polled_dev_ptr->COUNT) { // Line 136
/* Device is already opened */
polled_dev_ptr->COUNT++;
fd_ptr->FLAGS = polled_dev_ptr->FLAGS;
return (_mqx_int)(result);
}
polled_dev_ptr->CHARQ = (CHARQ_STRUCT_PTR)_mem_alloc_system((_mem_size)(
sizeof(CHARQ_STRUCT) - (4 * sizeof(char)) + polled_dev_ptr->QUEUE_SIZE
));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
if (polled_dev_ptr->CHARQ == NULL) {
return(MQX_OUT_OF_MEMORY);
}
#endif
_mem_set_type(polled_dev_ptr->CHARQ,MEM_TYPE_IO_SERIAL_CHARQ);
_CHARQ_INIT(polled_dev_ptr->CHARQ, polled_dev_ptr->QUEUE_SIZE);
polled_dev_ptr->FLAGS = (_mqx_uint)flags;
fd_ptr->FLAGS = (_mqx_uint)flags;
#if MQX_ENABLE_LOW_POWER
_lwsem_wait (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
result = (*polled_dev_ptr->DEV_INIT)(
polled_dev_ptr->DEV_INIT_DATA_PTR, &polled_dev_ptr->DEV_INFO_PTR, open_name_ptr
);
#if MQX_ENABLE_LOW_POWER
_lwsem_post (&(polled_dev_ptr->LPM_INFO.LOCK));
#endif
if (result == MQX_OK) {
if ((polled_dev_ptr->DEV_IOCTL) != NULL) {
ioctl_val = (_mqx_uint)flags;
(*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_SET_FLAGS, &ioctl_val);
}
if ((_mqx_uint)flags & IO_SERIAL_NON_BLOCKING) {
if ((_mqx_uint)flags & (IO_SERIAL_TRANSLATION | IO_SERIAL_ECHO | IO_SERIAL_XON_XOFF)) {
result = MQX_INVALID_PARAMETER;
} else {
if ((polled_dev_ptr->DEV_IOCTL) != NULL) {
result = (*polled_dev_ptr->DEV_IOCTL)(polled_dev_ptr->DEV_INFO_PTR, IO_IOCTL_SERIAL_CAN_TRANSMIT, &ioctl_val);
}
}
}
}
if (result != MQX_OK) {
_mem_free(polled_dev_ptr->CHARQ);
return (_mqx_int)(result);
}
polled_dev_ptr->COUNT = 1;
return (_mqx_int)(result);
}