For discussions about development of TAPs, patches and other software for the Toppy

Moderator: Technical

EMJB
Frequent contributor
Posts: 3645
Joined: Fri Jul 08, 2005 9:43 am
Location: Maldon Essex

Post by EMJB »

R2-D2 wrote:
EMJB wrote:As an aside, there appears to be a limit on the sting length sent by TAP_Print - I seem to get crashes if the string is longer than something around 256 bytes. Anyone else seen this?
One of the oldest known firmware bugs, I thought? It formats its string using a temporary on the stack. Very bad things can happen without being immediately obvious.
Unfortunately we have lost the wiki site which contained that sort of info, so I don't know where to look when using a function for the first time, or using it under different circumstances. Is there another with a list of all the TAP interface bugs?

EMJB
R2-D2
Frequent contributor
Posts: 12148
Joined: Mon Dec 18, 2006 11:15 am
Contact:

Post by R2-D2 »

Most of the normal ones you'd come across are fixed in FireBirdLib's TAPAPIFix section. I think that there isn't a fix for TAP_Print() because it'd have to use memory from somewhere so it's more about just being aware of what the size limit is.
EMJB
Frequent contributor
Posts: 3645
Joined: Fri Jul 08, 2005 9:43 am
Location: Maldon Essex

Post by EMJB »

I am beginning to think that acheiving zero lost bytes is going to be impossible. With only 8 byte hardware buffer, receipt of any messages longer than this is dependent on the processor not being grabbed for other purposes in any loop waiting for bytes to arrive. Am I right in thinking that a loop such as:

Code: Select all

do
{
    if (TAP_KbHit() != 0) 
         RxChar = TAP_GetCh();
    else
       RxChar = 0;
} while ...	
can get interrupted for low level housekeeping tasks?

If so are there any of these I can supend?

EMJB
R2-D2
Frequent contributor
Posts: 12148
Joined: Mon Dec 18, 2006 11:15 am
Contact:

Post by R2-D2 »

EMJB wrote:can get interrupted for low level housekeeping tasks?
Yes, all "processes" get time-sliced, even the main one (which runs TAPs). This is the difference between normal USB transfer mode and Turbo (where this time-slicing is disabled). So all the functions which don't work in Turbo mode are the sorts of things that will also be eating up processor time when your TAP is running. Plus, TAPs don't get given every EVT_IDLE: they get 1/8 of them (in pairs). And then, on top of that, all of the main process's TSRs (like doing the recording handling) do get serviced on every Idle.
EMJB
Frequent contributor
Posts: 3645
Joined: Fri Jul 08, 2005 9:43 am
Location: Maldon Essex

Post by EMJB »

R2-D2 wrote:
EMJB wrote:can get interrupted for low level housekeeping tasks?
Yes, all "processes" get time-sliced, even the main one (which runs TAPs). This is the difference between normal USB transfer mode and Turbo (where this time-slicing is disabled). So all the functions which don't work in Turbo mode are the sorts of things that will also be eating up processor time when your TAP is running. Plus, TAPs don't get given every EVT_IDLE: they get 1/8 of them (in pairs). And then, on top of that, all of the main process's TSRs (like doing the recording handling) do get serviced on every Idle.
Thanks for the clarification - looks like I need to concentrate on error tolerance rather than further efforts to reduce the error rate.

EMJB
EMJB
Frequent contributor
Posts: 3645
Joined: Fri Jul 08, 2005 9:43 am
Location: Maldon Essex

Post by EMJB »

R2-D2 wrote:
EMJB wrote:can get interrupted for low level housekeeping tasks?
Yes, all "processes" get time-sliced, even the main one (which runs TAPs). This is the difference between normal USB transfer mode and Turbo (where this time-slicing is disabled). So all the functions which don't work in Turbo mode are the sorts of things that will also be eating up processor time when your TAP is running. Plus, TAPs don't get given every EVT_IDLE: they get 1/8 of them (in pairs). And then, on top of that, all of the main process's TSRs (like doing the recording handling) do get serviced on every Idle.
Interactive On consumes so much time that the chances of a 150 byte message getting through unscathed seem minimal. Recording, including time-shifting, and Subtitles On both seem to approximately double the lost byte rate.

EMJB
EMJB
Frequent contributor
Posts: 3645
Joined: Fri Jul 08, 2005 9:43 am
Location: Maldon Essex

Post by EMJB »

R2-D2 wrote:Most of the normal ones you'd come across are fixed in FireBirdLib's TAPAPIFix section. I think that there isn't a fix for TAP_Print() because it'd have to use memory from somewhere so it's more about just being aware of what the size limit is.
Is the size limit actually 255 bytes, or is it something less? I am having trouble with some spurious output. I have tried doing a TAP_PutCh() on each byte of the string but that is no better>

EMJB
R2-D2
Frequent contributor
Posts: 12148
Joined: Mon Dec 18, 2006 11:15 am
Contact:

Post by R2-D2 »

EMJB wrote:Is the size limit actually 255 bytes, or is it something less?
The area of stack reserved is exactly 256 bytes, so that's a maximum string length of 255 real characters (with null termination). Any more than that and the first thing that gets overwritten is the return address of the calling function (EEK!).
EMJB
Frequent contributor
Posts: 3645
Joined: Fri Jul 08, 2005 9:43 am
Location: Maldon Essex

Post by EMJB »

R2-D2 wrote:
EMJB wrote:Is the size limit actually 255 bytes, or is it something less?
The area of stack reserved is exactly 256 bytes, so that's a maximum string length of 255 real characters (with null termination). Any more than that and the first thing that gets overwritten is the return address of the calling function (EEK!).
Thanks for confirming that - have found my source of stray bytes elsewhere!

EMJB
EMJB
Frequent contributor
Posts: 3645
Joined: Fri Jul 08, 2005 9:43 am
Location: Maldon Essex

Post by EMJB »

This is the code I am using to receive the serial data:

Code: Select all

switch(wEvent)
	/* ------------------------------------------------------------------------------------ */
	{
		 case EVT_UART:												// Character(s) received on serial input. Note 8 byte hardware buffer only!!

		{	
			bool		FoundLastChar = FALSE;
			
			RxChar = (byte) dwParam1;
			MsgTimeOut = TAP_GetTick() + MaxMsgTime;				// Define latest end of message time, so don't wait for ever if terminating character lost
			do
			{
				if (TAP_GetTick() > MsgTimeOut)						// Terminating character apparently lost
				{
					memset(M1Str,0,sizeof(M1Str));
					strncpy(M1Str,Msg,40);
					if (Active)
					{
						DisplayProgress("End of message not recd within allowed time",M1Str,"",TRUE);
						TAP_Delay(ErrorDisplayTime);
					}
					memset(Msg,0,sizeof(Msg));				// Abandon message
					CharNo = 0;
					break;									// From do/while loop, not from EVT_UART!!!
				}
			
				if (RxChar == TermChar) 						// Found terminating character
				{
					FoundLastChar = TRUE;
					ClearRxBuffer();
					if (PosString(Msg,"41") == 0) SetActive(TRUE);
					if (Active) 
					{
						if (strlen(Msg) > 0)
							ProcessMsg();						// Process message and take relevant action
						else
						{
							TAP_SPrint(SData,"34 - Blank message received by %s%c",StateName,(char) TermChar);
							SendSerialMsg(SData);
							DisplayProgress("Blank message received","","",TRUE);
						}
					}
					CharNo = 0;
					RxChar = 0;
					memset(Msg,0,sizeof(Msg));
					break;									// From do/while loop, not from EVT_UART!!!
				}
				else
				{
					if &#40;&#40;CharNo + 2 < MaxMsgLength&#41; && &#40;RxChar !=  0&#41;&#41;  
					&#123;
						Msg&#91;CharNo&#93; = RxChar;
						CharNo++;
					&#125;
				&#125;
				if &#40;TAP_KbHit&#40;&#41; != 0&#41; 
					RxChar = TAP_GetCh&#40;&#41;;
				else
					RxChar = 0;	
			&#125;	while &#40;!FoundLastChar&#41;;
			returnKey = 0;
			break;
		&#125;
just in case anyone else wants to try using the serial channel.

If messages of more than 8 bytes are to be sent, it is essentail that "Interactive" is switched off. To minimise erors, ensure subtitles are off and both channels stopped.

EMJB
Post Reply