AnsweredAssumed Answered

What is the correct way to override and initialise io_serial driver in MQX

Question asked by DaveTonyCook on Jun 21, 2016
Latest reply on Jun 21, 2016 by Daniel Chen

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);

}

Outcomes