|
|
View previous topic :: View next topic |
Author |
Message |
benoitstjean
Joined: 30 Oct 2007 Posts: 566 Location: Ottawa, Ontario, Canada
|
PIC24EP512 - strlen() problem with long strings? |
Posted: Mon Feb 12, 2024 1:23 pm |
|
|
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: 19539
|
|
Posted: Tue Feb 13, 2024 2:59 am |
|
|
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: 566 Location: Ottawa, Ontario, Canada
|
|
Posted: Tue Feb 13, 2024 6:09 am |
|
|
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: 19539
|
|
Posted: Tue Feb 13, 2024 6:41 am |
|
|
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. |
|
|
|
|
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
|