|
|
View previous topic :: View next topic |
Author |
Message |
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
FYI: Potential Memory Clobbering bug in 5.087 (and 5.085) |
Posted: Thu Aug 01, 2019 8:06 am |
|
|
Just wanted to make folks aware since this was a pretty nasty surprise. I don't know the scope of the bug or the exact specific cause of it (I haven't had time to go through iterations of different option combinations, but the following code does something really *fun*. It's nonsense code, but reproduces the problem. The same issue occurs in correct slave SPI code running on this chip.
Code: |
#include <24FJ256GB410.h>
#use delay(clock=8000000)
#use SPI(SLAVE, SPI4, MODE=0, XFER16, FORCE_HW,stream=SPI_STREAM)
BOOLEAN dont_clobber_me = FALSE;
void main()
{
dont_clobber_me = TRUE;
spi_xfer(SPI_STREAM,0,16);
//This clobbers the dont_clobber_me variable
while(TRUE);
}
|
The relevant RAM section of the SYM file:
Code: |
800 @SPIWRITE_1
801.0 dont_clobber_me
4780-47FF _STACK_
|
and the relevant section of the LST file:
Code: |
.................... #use SPI(SLAVE, SPI4, MODE=0, XFER16, FORCE_HW,stream=SPI_STREAM)
*
00200: MOV W5,[W15++]
00202: MOV W0,W4
00204: MOV W1,W5
00206: MOV #8,W3
00208: CP W2,#10
0020A: BRA Z,20E
0020C: MOV #A,W3
0020E: CP0.B 800
00210: CLR 800
00212: BRA NZ,21C
00214: MOV [W3],[W15++]
00216: POP 454
00218: BTSS.B 450.0
0021A: BRA 218
0021C: MOV 454,W0
0021E: MOV W0,[W3--]
00220: BCLR.B 450.6
00222: SUB.B #10,W2L
00224: BRA GTU,20E
00226: MOV W4,W0
00228: MOV W5,W1
0022A: MOV [--W15],W5
0022C: RETURN
|
Notice line 00210 for the nice 16bit clear on address 800
this lead to all kinds of fun in our code. For some builds certain global flags would mysteriously reset. I'm guessing it has to do with the 16bit mode in conjunction with slave mode given the nature of the memory clobbering, but I haven't spent any significant time trying to isolate the source.
I submitted a bug report to CCS via email, so hopefully they can put in a fix at some point. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Thu Aug 01, 2019 1:10 pm |
|
|
I'd suspect that attempting to write to the SPI peripheral on a slave is the
problem. A slave can only physically 'write' data when it receives a
transfer. Does it do the same if you use spi_prewrite, which is the command
to pre load the data for the master to read?.
I'd agree on the 16bit mode 'core' to the problem. It looks as if the compiler
is only assigning an 8bit temporary register. What happens if you specify
bits=16 in the #USE as well as the XFER16?.
Specifying 'SPIx', always automatically does a 'FORCE_HW', as does
specifying 'slave' so the setup is rather OTT!. However that shouldn't matter.
Does it do the same on SPI1 or 2?.
Not at a computer with CCS today, so will have to leave having a look at
this till I get back!... :0 |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Thu Aug 01, 2019 7:11 pm |
|
|
I'd have go get the code base from my coworker to see his actual code and try out other options This was just a contrived example that I could plop over to CCS in an email. Basically just keeping it minimal since it is a code generation bug. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Fri Aug 02, 2019 12:47 am |
|
|
Just tested, and adding BITS=16 to the #USE SPI, fixes the problem.
It moves "dont_clobber_me" up to address 802.
It's interesting, since the default is meant to be 32bit max transfers.
Explicitly selecting BITS=32, has it allocating 4 bytes for the transfer.
So somehow the 'default' size is not being applied, resulting in only a
single byte buffer being allocated.
Went back to 5.074, and by default it uses a CLR.B, so doesn't clobber the
next byte. 5.080 though has the fault. In all cases though you have to
explicitly use BITS= to get more than one byte of storage allocated. |
|
|
jeremiah
Joined: 20 Jul 2010 Posts: 1354
|
|
Posted: Fri Aug 02, 2019 10:15 am |
|
|
I checked back to 5.078 and it used CLR 800, so it broke somewhere between 5.074 and 5.078.
I checked my coworker's code. They are using spi_xfer even though it is in slave mode. Aside from the clobbering bug, it does correct enough SPI for them to talk to another device without any issues. The original fix was to #locate a ram variable right after the one CCS created to absorb the 16bit access. I'll update their bug report with the BITS=16 option, but since they aren't using the SPI in the traditional slave way, they'll probably want to do some bench testing to make sure it doesn't break something. |
|
|
|
|
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
|