Looking for suggestion on Photon application

Hello everyone,

I built a initial application with Photon for serial communication. And I just used write() and read() function. I want to constantly get the data reply from a device in my application, and then display the data. the lenght of the data depends on different status. I used two threads, one for sending and receiving the data, and the other for extracting data and display. the code is below:

void *thread_disp1(void *arg)
{
int i, handles,j;
double q0,qx,qy,qz,x,y,z,error;
unsigned long frame;
char *pszTransformInfo = NULL;
const uint64_t timeout=100000000;
event.sigev_notify=SIGEV_UNBLOCK;
do
{
TimerTimeout( CLOCK_REALTIME, _NTO_TIMEOUT_INTR,&event, &timeout, NULL );
InterruptWait(0,NULL);
pszTransformInfo=transforms;
handles=uASCIIToHex(pszTransformInfo, 2 );
pszTransformInfo+=2;
if (!strncmp(transforms+4,“MISSING”,7))
{
q0=0;
qx=0;
qy=0;
qz=0;
x=0;
y=0;
z=0;
error=0;
Xfrms[i].ulFrameNumber= uASCIIToHex( transforms+19, 8 );
frame = Xfrms[i].ulFrameNumber;
}

	else
	{
		for(j=0;j<handles;j++)
		{
		i = uASCIIToHex( pszTransformInfo, 2 );
		pszTransformInfo+=2;
		//PtTextModifyText(ABW_revid_text, 0,0,-1, pszTransformInfo, 300);
		bExtractValue( pszTransformInfo, 6, 10000.,&Xfrms[i].rotation.q0 ); 
		bExtractValue( pszTransformInfo + 6, 6, 10000.,&Xfrms[i].rotation.qx );
		bExtractValue( pszTransformInfo + 12, 6, 10000.,&Xfrms[i].rotation.qy );
		bExtractValue( pszTransformInfo + 18, 6, 10000.,&Xfrms[i].rotation.qz );
		bExtractValue( pszTransformInfo + 24, 7, 100.,&Xfrms[i].translation.x );
		bExtractValue( pszTransformInfo + 31, 7, 100.,&Xfrms[i].translation.y );
		bExtractValue( pszTransformInfo + 38, 7, 100.,&Xfrms[i].translation.z );
		bExtractValue( pszTransformInfo + 45, 6, 10000.,&Xfrms[i].fError );
		pszTransformInfo+=59;
		Xfrms[i].ulFrameNumber = uASCIIToHex( pszTransformInfo, 8 );
		q0=Xfrms[i].rotation.q0;
		qx=Xfrms[i].rotation.qx;
		qy=Xfrms[i].rotation.qy;
		qz=Xfrms[i].rotation.qz;
		x=Xfrms[i].translation.x;
		y=Xfrms[i].translation.y;
		z=Xfrms[i].translation.z;
		error=Xfrms[i].fError;
		Xfrms[i].ulFrameNumber= uASCIIToHex( transforms+63, 8 );
		frame = Xfrms[i].ulFrameNumber;
		pszTransformInfo+=8;
		pszTransformInfo++;
		
		}
	}
	PtEnter(0);
	PtTextModifyText(ABW_text_status, 0,0,-1,transforms,200);
	PtTextModifyText(ABW_text_status, 0,0,-1, pszTransformInfo, 300);
		
		PtSetResource (ABW_rot_q0, Pt_ARG_NUMERIC_PRECISION, 4, 0);
		PtSetResource (ABW_rot_qx, Pt_ARG_NUMERIC_PRECISION, 4, 0);
		PtSetResource (ABW_rot_qy, Pt_ARG_NUMERIC_PRECISION, 4, 0);
		PtSetResource (ABW_rot_qz, Pt_ARG_NUMERIC_PRECISION, 4, 0);
		PtSetResource (ABW_rot_q0, Pt_ARG_NUMERIC_VALUE, &q0, 0);
		PtSetResource (ABW_rot_qx, Pt_ARG_NUMERIC_VALUE, &qx, 0);
		PtSetResource (ABW_rot_qy, Pt_ARG_NUMERIC_VALUE, &qy, 0);
		PtSetResource (ABW_rot_qz, Pt_ARG_NUMERIC_VALUE, &qz, 0);
	
		PtSetResource (ABW_tran_x, Pt_ARG_NUMERIC_PRECISION, 4, 0);
		PtSetResource (ABW_tran_y, Pt_ARG_NUMERIC_PRECISION, 4, 0);
		PtSetResource (ABW_tran_z, Pt_ARG_NUMERIC_PRECISION, 4, 0);
		PtSetResource (ABW_tran_x, Pt_ARG_NUMERIC_VALUE, &x, 0);
		PtSetResource (ABW_tran_y, Pt_ARG_NUMERIC_VALUE, &y, 0);
		PtSetResource (ABW_tran_z, Pt_ARG_NUMERIC_VALUE, &z, 0);
		PtSetResource( ABW_frame, Pt_ARG_NUMERIC_VALUE, frame, 0);
		PtLeave(0);
}while(flag==1);

}

void* serthread( void *data)//create a new thread to handle serial port interrogation and receiving
{

int i, temp;
						char Buf[20];
do
{
	
	write(fd, "TX \r", 4);
	delay(130);
	read(fd, transforms,sizeof(transforms));
	tcflush( fd, TCIOFLUSH );
		}while(flag==1);

}

int
starttrack( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )

{

flag=1;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED );
pthread_create(NULL, &attr, &serthread, NULL);
pthread_create(NULL, NULL, &thread_disp1, NULL);
/* eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;

return( Pt_CONTINUE );

}

Because it require the data is alway the latest, so I create a thread for data acquirement. The delay-time between the write and read() is bother me since the data lenght is uncertain. And the display is seems not very fluent, the display data is ok if it not the latest.
Any idea about it? would it be better if I employ resource manager?
Thanks a lot?

Jason

First think that jumps out is “transform” is not protected (with say a mutex ).

Unless the serial port is very very high rate I wouldn’t use thread. Setup a fd handler. That means when ever data is waiting in the receive buffer a function would be called automaticly, then read what ever data is available, buffer and parse it. When all the data you need is ready, then update the widget and send the next command. You can also add a timer function to deal with timeout. Don’t forget to set up the serial port in NON_BLOCK command .

Why are you using InterruptWait?? There doesn’t seems to by any source of interrupt?

Thank you mario,

yes… I made a mistake with InterruptWait, it unnecessary. I just want TimerTimeout for unblock here.
How to set the fd handler? because the system needs to send ‘TX’ continuously in order to receive the latest data, I think maybe I should set the ‘fd handler’ in a new thread.
Would you please give me more details about the fd handler, is there any example in the help documents of QNX?

Check PtAppAddFd().

I wrote a code with PtAppAddFd(), it seems like the display is no big difference from the multi-threads. And I got two more questions:

  1. Is it necessary to release the handle if I’d like to move on to other commands;
  2. The sensor has a update rate (for example 60Hz), and I can obtain the frame number (the number incremented by 1 at rate 60Hz) of the sensor, How can I display the frame number continuously, for now it is jump not incremented 1 by 1…

Many thanks and best regards,

[code]
int
fd_handler_function( int fd, void *data, unsigned mode )
{
int i, handles,j;
double q0,qx,qy,qz,x,y,z,error;
unsigned long frame;
char
pszTransformInfo = NULL;
switch( mode )
{
case Pt_FD_READ:
/

* drain out the available data
*/

     read(fd, transforms,sizeof(transforms));
     		.
                            .
                  parse data.....	
                            .
                            .
                    display data....
                            .
                            .
									
     PtTextModifyText(ABW_text_status, 0,0,-1,transforms,200);
     tcflush( fd, TCIOFLUSH );
   
     /*
      * display what we've received 
      */
     
    PtAppSetFdMode(NULL, fd, Pt_FD_WRITE);
     break;
     case Pt_FD_WRITE:
     write(fd, "TX \r", 4);
     delay(100);
     PtAppSetFdMode(NULL, fd, Pt_FD_READ);
     break;
  default:  /* do nothing */
  	;

}

/* eliminate ‘unreferenced’ warnings */
data = data;

return( Pt_CONTINUE );
}

int
starttrack( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t *cbinfo )

{

if( (PtAppAddFd( NULL, fd, Pt_FD_WRITE, fd_handler_function, NULL ) ) == -1)
{
PtTextModifyText(ABW_text_status, 0,0,-1,“ERROR”,7);
}
}[/code]

well…I am also a newbie and I think it is not necessary to end PtAppAddFd() if you finish to use it.
and it difficult to determine a exact interval between the write and read()…