CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

PIC24EP512 - strlen() problem with long strings?

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
benoitstjean



Joined: 30 Oct 2007
Posts: 546
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PIC24EP512 - strlen() problem with long strings?
PostPosted: Mon Feb 12, 2024 1:23 pm     Reply with quote

Device: PIC24EP512GP806
Compiler: 5.026 (ordering new this week!!)

Hi guys,

Here's a weird one:

I am putting data in a string Lora.DataBuffer which is is an unsigned char and is max 241 bytes (240+NULL):

Code:


typedef struct
{
     unsigned char DataBuffer[241];
     [... other parameters ...]

} SLORA;

SLORA Lora;


At some point in my code, I do the following:


         memset( Lora.DataBuffer, NULL, sizeof( Lora.DataBuffer ));

         sprintf( Lora.DataBuffer, "^R&%Ld;%u;%s;%u;%u;%u;%u;%s;%u;%s;%s$", Lora.Address,
                                                                            Lora.NetworkID,
                                                                            Lora.Band,
                                                                            Lora.Parameters.SF,
                                                                            Lora.Parameters.BW,
                                                                            Lora.Parameters.CR,
                                                                            Lora.Parameters.PP,
                                                                            Lora.Key,
                                                                            Lora.RFPower,
                                                                            Lora.FWVersion,
                                                                            Lora.ModuleUID );

         fprintf( UART1, "Length: %Ld", strlen( Lora.DataBuffer ));
         
         dma_start( [...] );



In the above example string, ^R& is my start of protocol, then the data and the string ends with $.

The end-result string should look like this: ^R&10001;1;915000000;7;3;4;5;00000000000000000000000000000000;{firmware_version};164738323135383200100025$

That string is then sent over UART2 on a DMA channel. I am monitoring the TX RX lines with a logic analyzer. I'm sure it's not the DMA the problem because it's from previous functional code I've been using for many years. The problem here is with the string manipulation.


For some reason, the "Length" line just before dma_start() indicates that the data is 541 characters long but it's false, it's the length of whatever the number of characters is seen above.

Then after the data has been sent over from DMA to the UART and I look at the logic analyzer and count them, there's 29 characters and abruptly ends like this: ^R&10001;1;915000000;7;3;4;5; <-- Abruptly ends here for some reason


Just for testing, I decided to change Lora.DataBuffer to print 50 characters 0-9 with the framing characters: ^R&01234567890123456789012345678901234567890123456789$

The results is that the "Length" returns 54 - just as I expect - and the data shows exactly this on the analyzer: ^R&01234567890123456789012345678901234567890123456789$


The last thing I tried is that I went back to my initial code without DMA by just doing this:

Code:
fprintf( UART2, "^R&%Ld;%u;%s;%u;%u;%u;%u;%s;%u;%s;%s$", Lora.Address,
                                                         Lora.NetworkID,
                                                         Lora.Band,
                                                         Lora.Parameters.SF,
                                                         Lora.Parameters.BW,
                                                         Lora.Parameters.CR,
                                                         Lora.Parameters.PP,
                                                         Lora.Key,
                                                         Lora.RFPower,
                                                         Lora.FWVersion,
                                                         Lora.ModuleUID );


And this works exactly as it should and the logic analyzer captures everything properly. The reason I use DMA is because all the data to transmit over the UART is queued and when time permits, the data is unqueued and sent-out.


My mind is boggled.

Thanks for any pointers.

Benoit



[EDIT 5 minutes later] Here's a new finding: I took the DataBuffer out of the Lora structure and repeated the steps to make it fail like in my first example above and this time it works, the length reported is 105 characters and all the data is properly transmitted to the DMA channel as I receive it at the other end. So why does it fail in the structure but does not fail out of the structure? This is what I now have:


Code:
memset( DataBuffer, NULL, sizeof( DataBuffer ));

         sprintf( DataBuffer, "^R&%Ld;%u;%s;%u;%u;%u;%u;%s;%u;%s;%s$", Lora.Address,
                                                                            Lora.NetworkID,
                                                                            Lora.Band,
                                                                            Lora.Parameters.SF,
                                                                            Lora.Parameters.BW,
                                                                            Lora.Parameters.CR,
                                                                            Lora.Parameters.PP,
                                                                            Lora.Key,
                                                                            Lora.RFPower,
                                                                            Lora.FWVersion,
                                                                            Lora.ModuleUID );

         fprintf( UART1, "Length: %Ld", strlen( DataBuffer ));
         
         dma_start( [...] );
Ttelmah



Joined: 11 Mar 2010
Posts: 19231

View user's profile Send private message

PostPosted: Tue Feb 13, 2024 2:59 am     Reply with quote

You don't show your Lora variable being mapped into the the DPSRAM.
Post a printout of the symbol map including this variable.
You do understand that if it isn't in the DPSRAM, the processor will have
to stall and wait whenever a DMA transfer is done.
Not the real problem though.

I do remember there being problems back around your version, with
single sprintf statements that output more that a certain number of
characters. I suspect this is what you are hitting. However where it ends
suggests there may be a problem with the formatting of the Key string?.
There is an issue with your version, if this is null (zero length), it will
print this null into the output string.
benoitstjean



Joined: 30 Oct 2007
Posts: 546
Location: Ottawa, Ontario, Canada

View user's profile Send private message

PostPosted: Tue Feb 13, 2024 6:09 am     Reply with quote

Alrighty, I got fed-up and figured that since the Lora device will not be communicating at great speeds and just some random blip here and there, I just reduced my code to the bear minimum to also account for any other potential issues I may get and stuck with the standard good'ole fprintf( serial_port, "{data}" ) and that solved the problem.

I may re-introduce the DMA code at some point for this this application at the moment, I don't need it really due to the low tx/rx speeds.


As for "issues" with printf's, I do also remember some time ago running into issues that were mind boggling and it turned-out it was some weird problem that I was able to circumvent but I don't remember it was in what post. However, I know that I can output long strings because in another program, I was outputting 133 bytes without a problem.

Anyhow, thanks for your time, it's appreciated as always and if I end-up re-introducing DMA and run into issues, then I'll dig deeper into it. Hopefully this has been resolved with the newer CCS version.

Ben
Ttelmah



Joined: 11 Mar 2010
Posts: 19231

View user's profile Send private message

PostPosted: Tue Feb 13, 2024 6:41 am     Reply with quote

One other thing that might cause problems. The use of 241 bytes.
You don't show what your following variables are, but most will need
a int16 alignment. Might be worth simply extending to 242 bytes to help
keep this. Alignments in structures are sometimes complex.

It is always worth looking at the symbols list and making sure things
are placed logically.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group