September 30, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Palm OS Communications Primer: Serial Manager

  • July 28, 2004
  • By Alex Gusev
  • Send Email »
  • More Articles »

Now, let's consider some RX queue-related issues. Its default size is 512 bytes; you may change it by a SrmSetReceiveBuffer call. Your application is responsible to release this buffer by setting its size to zero, because Serial Manager won't do it. If you're planning to transmit large amount of data, think about sending/receiving it by blocks, say 1K, otherwise buffer overflows, and you will get an error serLineErrorSWOverrun.

You may want to know when Serial Manager sent all data or put something into receiving buffer. Well, you can do it pretty simply. In the case of reading data, that's probably the best way to handle it. Your application will need to pass two steps. The first one is to call SrmReceiveWait. This will block all the processes during the required timeout or data arriving. Note, that the timeout is applied for every new incoming byte; in other words, you may control maximum delay between two incoming bytes of data. In case of SrmSendWait "timeout" means "send buffer is empty." SrmReceiveWait also saves the PDA's battery because processor is put into a low-power state. The second step is trivial: Yes, you simply read data that is ready to be received. If there were any errors during transmitting, you should call SrmClearErr to clean them up.

For lengthly Serial I/O operations, your application should take care of at least two things. One is to handle user input during transmitting, either by calling EvtSysEventAvail or EvtGetEvent. Doing it with at least every 'timeout' will make the user's life much happier. In addition, if you have an I/O session that should not be interrupted, you should prevent the PDA from switching to automatic sleeping mode, which occurs when no user input is available. Calling EvtReserAutoOffTimer once per minute is a good solution in such cases.

Serial Manager also provides direct access to its receive queue. This method is not communly used, but it gives a "backdoor" solution. Thus, call SrmReceiveWindowOpen/SrmReceiveWindowClose when you really need it.

And, finally, you can set up Serial Manager to notify your application when a preset amount of data is ready to be received. SrmSetWakeupHandler calls for a callback in your program (WakeupHandlerProcPtr proc parameter), which in turn gets refCon as the only parameter. The minimal thethreshold is defined by the SrmPrimeWakeupHandler function.

Some Samples

To illustrate all the dry theory from above, take a look at the following example. For more details, please refer to the attached sample project.

static void OnSerialIO()
{
   FieldType * field = GetObjectPtr<FieldType>(MainDescriptionField);
   if (field)
   {
      FldDelete(field, 0, 0xFFFF);
      FldDrawField(field);
   }

   Char szError[128];
   MemSet(szError,sizeof(szError),0);

   Char szAnswer[128];
   MemSet(szAnswer,sizeof(szAnswer),0);

   Char szBuffer[128];
   MemSet(szBuffer,127,0x30);
   szBuffer[127] = 0;
   MemMove(szBuffer,"Sample Message",StrLen("Sample Message"));

   UInt16 dwSize = StrLen(szBuffer) + 1;

   UInt16 nInsPos = 0;
   Char szInfo[1024];
   StrPrintF(szInfo,"PackSize = %u\nMessage = %s\n",dwSize,szBuffer);
   if (field)
   {
      nInsPos = Log(field, szInfo, nInsPos);
   }

   UInt16 nPortId;
   Err err = SrmOpen(0x8000,9600,&nPortId);
   if ( err != errNone )
   {
      StrPrintF(szInfo,"SrmOpen returned error = 0x%X - %s\n",err,
                GetSerialErrorText(err, szError));
      if (field)
      {
         nInsPos = Log(field, szInfo, nInsPos);
      }
      return;
   }
   UInt32 nBytes = SrmSend(nPortId, &dwSize, sizeof(dwSize), &err);
   StrPrintF(szInfo,"1. SrmSend returned %lu\n",nBytes);
   if (field)
   {
      nInsPos = Log(field, szInfo, nInsPos);
   }

   if ( err != errNone )
   {
      StrPrintF(szInfo,"1. SrmSend returned error = 0x%X - %s\n",
                err,GetSerialErrorText(err, szError));
      if (field)
      {
         nInsPos = Log(field, szInfo, nInsPos);
      }
      return;
   }

   err = SrmReceiveWait(nPortId,3,5 * SysTicksPerSecond());
   if ( err != errNone )
   {
      StrPrintF(szInfo,"1. SrmReceiveWait returned error =
                0x%X - %s\n",err,GetSerialErrorText(err, szError));
      if (field)
      {
         nInsPos = Log(field, szInfo, nInsPos);
      }
      return;
   }
   nBytes = SrmReceive(nPortId, (void*)szAnswer, sizeof(szAnswer),
                       5 * SysTicksPerSecond(), &err);
   if ( err != errNone )
   {
      StrPrintF(szInfo,"1. SrmReceive returned error = 0x%X - %s\n",
                err,GetSerialErrorText(err, szError));
      if (field)
      {
         nInsPos = Log(field, szInfo, nInsPos);
      }
      return;
   }
   StrPrintF(szInfo,"1. SrmReceive returned buffer %s\n",szAnswer);
   if (field)
   {
      nInsPos = Log(field, szInfo, nInsPos);
}

   nBytes = SrmSend(nPortId, szBuffer, StrLen(szBuffer) + 1, &err);
   StrPrintF(szInfo,"2. SrmSend returned %lu\n",nBytes);
   if (field)
   {
      nInsPos = Log(field, szInfo, nInsPos);
   }

   if ( err != errNone )
   {
      StrPrintF(szInfo,"2. SrmSend returned error = 0x%X - %s\n",
                err,GetSerialErrorText(err, szError));
      if (field)
      {
         nInsPos = Log(field, szInfo, nInsPos);
      }
      return;
   }

   SrmClose(nPortId);
}

This snippet just transmits data by the simplest way. The sample project also contains the MFC application as PC-side stuff.

Download

Download the accompanying code's zip file here.

About the Author

Alex Gusev started to play with mainframes in the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers' lives in the mobile jungles a little bit simpler.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel