title: C S-function to read data from serial
body: <p>After issues I met, trying to read from COM port with Simulink, as I wrote in <a href="https://stackoverflow.com/questions/21957839/some-help-writing-a-s-function-to-read-data-from-serial-port">this discussion</a>, I would like to follow Phil Goddard's suggestion on writing a C S-function for that. My problem is that I am not able to write C-code, so I hope in some help from you.
  I have found this two scripts on the net about C S-function for serial communication:</p>
  
  <p>1)</p>
  
  <pre><code>#define S_FUNCTION_NAME sfun_comport
  
  #define S_FUNCTION_LEVEL 2
  
  #include "simstruc.h"
  
  #include "windows.h"
  
  #include "Strsafe.h"
  
  #define MDL_START
  
  #if defined(MDL_START)
  
  /* Function: mdlStart =================================================*/
  static void mdlStart(SimStruct *S)
  {
      HANDLE hCom;
      DCB dcb;
      COMMTIMEOUTS uCtm;
      char pcCommPort[10];
      uint8_T comport = 4;
        //-------------------------------------------------------------------
        StringCbPrintfA((STRSAFE_LPSTR)&amp;pcCommPort,
                        sizeof(pcCommPort),
                        "COM%d",
                        comport);
        //-------------------------------------------------------------------
        hCom = CreateFileA (pcCommPort,
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            NULL,
                            OPEN_EXISTING,
                            0,
                            NULL);
        if (hCom == INVALID_HANDLE_VALUE)
        {
            ssSetErrorStatus(S,"COM-Port konnte nicht geoeffnet werden!");
            return;
        }
        //-------------------------------------------------------------------
        SecureZeroMemory(&amp;dcb, sizeof(dcb));
        memset(&amp;dcb, 0, sizeof(dcb));
        dcb.DCBlength = sizeof(dcb);
        dcb.BaudRate  = (uint16_T)9600;
        dcb.ByteSize  = 8;
        dcb.Parity    = NOPARITY;
        dcb.StopBits  = ONESTOPBIT;
        //-------------------------------------------------------------------
        uCtm.ReadIntervalTimeout         = MAXDWORD;
        uCtm.ReadTotalTimeoutMultiplier  = 0;
        uCtm.ReadTotalTimeoutConstant    = 0;
        uCtm.WriteTotalTimeoutMultiplier = 0;
        uCtm.WriteTotalTimeoutConstant   = 0;
        //-------------------------------------------------------------------
        if ((!SetCommState(hCom, &amp;dcb)) | (!SetCommTimeouts(hCom, &amp;uCtm)))
        {
            CloseHandle(hCom);
            ssSetErrorStatus(S,"Konfigurationsfehler des COM-Ports!");
            return;
        }
        //-------------------------------------------------------------------
        ssSetPWorkValue(S, 0, hCom);
    }
  #endif
  /* Function: mdlOutputs =================================================*/
  
  static void mdlOutputs(SimStruct *S, int_T tid) {
  
      const real_T *u0 = (const real_T*) ssGetInputPortSignal(S,0);
      real_T       *y0 = ssGetOutputPortSignal(S,0);
      HANDLE hCom = (HANDLE*)ssGetPWorkValue(S, 0);
      uint32_T read_cnt;
      uint32_T write_cnt;
      char getbuffer[] = "test";
      char putbuffer[] = "Dies ist ein Test\r";
      //int i;
      //---------------------------------------------------------------------
      read_cnt = sizeof(putbuffer)-1;
      ReadFile(hCom, putbuffer, read_cnt, &amp;read_cnt, NULL);
      //---------------------------------------------------------------------    
      write_cnt = sizeof(putbuffer)-1;
      WriteFile(hCom, putbuffer, write_cnt, &amp;write_cnt, NULL);
      //---------------------------------------------------------------------
      Sleep(3000);
  }
  #define MDL_UPDATE
  
  #if defined(MDL_UPDATE)
  
  /* Function: mdlUpdate ================================================*/
  static void mdlUpdate(SimStruct *S, int_T tid)
  {
  }
  #endif
  /* Function: mdlTerminate ===============================================*/
  
  static void mdlTerminate(SimStruct *S) {
  
      CloseHandle((HANDLE*)ssGetPWorkValue(S, 0));
  }
  
  
  
  #ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
  #include "simulink.c"      /* MEX-file interface mechanism */
  #else
  #include "cg_sfun.h"       /* Code generation registration function */
  #endif
  </code></pre>
  
  <p>But when I try to compile it by <code>mex sfun_comport.c</code> it returns following errors:</p>
  
  <pre><code>C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(449) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(1692) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(1701) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(1724) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2373) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2380) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2393) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2402) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2408) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2448) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2459) : error C2065: 'mdlInitializeSizes' : undeclared identifier 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2459) : warning C4047: '=' : 'mdlInitializeSizesFcn' differs in levels of indirection from 'int' 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2548) : error C2065: 'mdlInitializeSampleTimes' : undeclared identifier 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2548) : warning C4047: '=' : 'mdlInitializeSampleTimesFcn' differs in levels of indirection from 'int' 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2679) : warning C4013: 'mdlInitializeSizes' undefined; assuming extern returning int 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2948) : warning C4013: 'mdlInitializeSampleTimes' undefined; assuming extern returning int 
  
    C:\PROGRA~1\MATLAB\R2013B\BIN\MEX.PL: Error: Compile of 'sfun_comport.c' failed. 
  </code></pre>
  
  <p>2) </p>
  
  <pre><code>#define S_FUNCTION_NAME  sfun_tryserial
  #define S_FUNCTION_LEVEL 2
  
  
  #include "simstruc.h" 
  #include "windows.h" 
  #include "strsafe.h" 
  #include "stdio.h" 
  #include "string.h" 
  #include "stdlib.h" 
  
  
  static void mdlStart(SimStruct *S) 
  { 
      HANDLE hCom; 
      DCB dcb; 
      COMMTIMEOUTS uCtm;     
      char pcCommPort[12]; 
      //char pcCommPort[10]="COM4"; 
      uint8_T comport = mxGetScalar(ssGetSFcnParam(S, 0)); 
  
      StringCbPrintfA((STRSAFE_LPSTR)&amp;pcCommPort, sizeof(pcCommPort), "COM%d:", comport); 
      //--------------------------------------------------------------- 
      hCom = CreateFileA (pcCommPort, 
                 GENERIC_READ | GENERIC_WRITE, 
                 0, 
                 NULL, 
                 OPEN_EXISTING, 
                 0, 
                 NULL); 
  
      if (hCom == INVALID_HANDLE_VALUE) 
      { 
     ssSetErrorStatus(S,"COM-Port konnte nicht geoeffnet werden!"); 
          return; 
      } 
      //--------------------------------------------------------------- 
      SecureZeroMemory(&amp;dcb, sizeof(dcb)); 
      memset(&amp;dcb, 0, sizeof(dcb)); 
      dcb.DCBlength = sizeof(dcb); 
      dcb.BaudRate = (uint16_T)9600; 
      dcb.ByteSize = 8; 
      dcb.Parity = NOPARITY; 
      dcb.StopBits = ONESTOPBIT; 
      //dcb.fDtrControl = 0X01; //ENABLE 
      //dcb.fRtsControl = 0x01; //ENABLE 
      //---------------------------------------------------------------   
      uCtm.ReadIntervalTimeout = MAXDWORD; 
      uCtm.ReadTotalTimeoutMultiplier = 0; 
      uCtm.ReadTotalTimeoutConstant = 0; 
      uCtm.WriteTotalTimeoutMultiplier = 0; 
      uCtm.WriteTotalTimeoutConstant = 0; 
      //--------------------------------------------------------------- 
      if ((!SetCommState(hCom, &amp;dcb)) | (!SetCommTimeouts(hCom, &amp;uCtm))) 
      { 
          CloseHandle(hCom); 
          ssSetErrorStatus(S,"Konfigurationsfehler des COM-Ports!"); 
          return; 
      } 
      //--------------------------------------------------------------- 
      ssSetErrorStatus(S,"Konfigurationsfehler des COM-Ports!"); 
      ssSetPWorkValue(S, 0, &amp;hCom); 
  } 
  
  
  static void mdlOutputs(SimStruct *S, int_T tid) 
  { 
      const real_T   *u0 = (const real_T*)ssGetInputPortSignal(S, 0); 
      real_T           *y0 = (real_T *)ssGetOutputPortRealSignal(S, 0); 
  
      uint32_T read_cnt; 
      uint32_T write_cnt; 
      char getbuffer[255] = {0}; 
      char putbuffer[255] = {0}; 
  
      HANDLE hCom = (HANDLE*)ssGetPWorkValue(S, 0); 
  
      //++++++++++++++++++++++++++++++++++++++++++++++ 
      if (ReadFile(hCom, getbuffer, sizeof(getbuffer), &amp;read_cnt, NULL)) 
      { 
          // Daten auswerten, read_cnt enthält die Anzahl gelesener Bytes 
      } 
      else 
      { 
          // keine Daten empfangen 
          // z.B. Fehlermeldung oder nix machen 
      }     
       //++++++++++++++++++++++++++++++++++++++++++++++ 
      if (!WriteFile(hCom, putbuffer, write_cnt, &amp;read_cnt, NULL)); 
      { 
          // Fehlermeldung, weil die Daten nicht verschickt werden konnten 
      } 
      //++++++++++++++++++++++++++++++++++++++++++++++ 
  } 
  
  static void mdlTerminate(SimStruct *S) 
  { 
      CloseHandle((HANDLE*)ssGetPWorkValue(S, 0)); 
  } 
  
  #ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
  #include "simulink.c"      /* MEX-file interface mechanism */
  #else
  #include "cg_sfun.h"       /* Code generation registration function */
  #endif
  </code></pre>
  
  <p>This produces:</p>
  
  <pre><code>sfun_tryserial.c(20) : warning C4244: 'initializing' : conversion from 'double' to 'uint8_T', possible loss of data 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(449) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(1692) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(1701) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(1724) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2373) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2380) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2393) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2402) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2408) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2448) : warning C4995: 'sprintf': name was marked as #pragma deprecated 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2459) : error C2065: 'mdlInitializeSizes' : undeclared identifier 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2459) : warning C4047: '=' : 'mdlInitializeSizesFcn' differs in levels of indirection from 'int' 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2548) : error C2065: 'mdlInitializeSampleTimes' : undeclared identifier 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2548) : warning C4047: '=' : 'mdlInitializeSampleTimesFcn' differs in levels of indirection from 'int' 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2679) : warning C4013: 'mdlInitializeSizes' undefined; assuming extern returning int 
  C:\Program Files\MATLAB\R2013b\simulink\include\simulink.c(2948) : warning C4013: 'mdlInitializeSampleTimes' undefined; assuming extern returning int 
  
    C:\PROGRA~1\MATLAB\R2013B\BIN\MEX.PL: Error: Compile of 'sfun_provaseriale2.c' failed. 
  </code></pre>
  
  <p>As you can notice common errors between two S-function are about:</p>
  
  <pre><code>'mdlInitializeSizes'
  'mdlInitializeSizesFcn'
  'mdlInitializeSampleTimes'
  'mdlInitializeSampleTimesFcn'
  'mdlInitializeSizes'
  </code></pre>
  
  <p>Do you have some suggestion to fix those errors ?</p>
  
  <p>PS: I have MATLAB 2013b 64-bit, 64-bit Windows 7, Microsoft Visual C++ 2010 (32-bit) as compiler (it has worked fine in 64-bit matlab to produce mex files)</p>