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 CCS Technical Support

PCD: Help from someone who knows assembly?

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



Joined: 04 Aug 2010
Posts: 24

View user's profile Send private message

PCD: Help from someone who knows assembly?
PostPosted: Tue Sep 28, 2010 5:03 pm     Reply with quote

My program was going through reboots for no apparent reason, and after a LOT of debugging I was able to narrow it down to a single line.

Code:
Y->Omega_LV_ECI_LV_y = -Compute_Omega_LV_ECI_LV_41_1;


If I changed that to
Code:
Y->Omega_LV_ECI_LV_y = -1.0 * Compute_Omega_LV_ECI_LV_41_1;


No more reboots!

This problem really confuses me, so I copied down the disassembly listings. But I'm a real novice at assembly, and can't find the error, so I'm hoping someone can interpret the following for me.

Assembly Code for the WORKING version:
Code:

3490:                   
Y->Omega_LV_ECI_LV_y = -1.0 * Compute_Omega_LV_ECI_LV_41_1;    // mra: wtf?! this is the problem?
06496  822730     mov.w 0x44e6,0x0000
06498  200044     mov.w #0x4,0x0008
0649A  420280     add.w 0x0008,0x0000,0x000a
0649C  200000     mov.w #0x0,0x0000
0649E  2BF801     mov.w #0xbf80,0x0002
064A0  8227C2     mov.w 0x44f8,0x0004
064A2  8227D3     mov.w 0x44fa,0x0006
064A4  023B9C     call 0x003b9c
064A8  200004     mov.w #0x0,0x0008
064AA  781AB4     mov.w [0x0008++],[0x000a++]
064AC  781AB4     mov.w [0x0008++],[0x000a++]


Assembly Code for the BROKEN version:
Code:

3489:                   
Y->Omega_LV_ECI_LV_y = -Compute_Omega_LV_ECI_LV_41_1;     // mra: wtf?! this is the problem?
06496  822730     mov.w 0x44e6,0x0000
06498  200044     mov.w #0x4,0x0008
0649A  420280     add.w 0x0008,0x0000,0x000a
0649C  244F84     mov.w #0x44f8,0x0008
0649E  781AB4     mov.w [0x0008++],[0x000a++]
064A0  781AB4     mov.w [0x0008++],[0x000a++]
064A2  A2F016     btg [0x000c],#15


Additional info that might be helpful:
The RHS of the equation is a float.
The LHS is a struct with 3 floats that was passed by reference into the function.
The assignment is to the middle (2nd) float of the 3 in the struct.

Any help is greatly appreciated!
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Sep 29, 2010 4:08 am     Reply with quote

I can't see a reason for reboot at first sight, although I doubt, that the negation is performed correctly. Can you post a short, complete example code, that demonstrates the error?

P.S.: Please tell also your PCD version.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Wed Sep 29, 2010 8:00 am     Reply with quote

Obvious other question, is 'how is Compute_Omega_LV_ECI_LV_41_1 declared'?.
In the 'working' version, you have a -1, on the right of the equation. This will force signed arithmetic to be used. If Compute_Omega_LV_ECI_LV_41_1 is 'unsigned', then the crash may be the compiler trying to negate an unsigned number.

Best Wishes
miketwo



Joined: 04 Aug 2010
Posts: 24

View user's profile Send private message

PostPosted: Wed Sep 29, 2010 1:54 pm     Reply with quote

Thanks for the responses guys. PCD version is 4.111, the PIC is a 24FJ256GA110.

FvM, you are correct -- the negation does not happen correctly. I think this leads to a math-error-induced reboot in another section of my program.

I can't get the reboot to occur in my test program, but I definitely was able to duplicate the failure in negation. The failure to negate happens on the assignment to a passed struct -- the last one in the test.
Code:
// Device
#include <24FJ256GA110.h>
#pragma case                  // Makes all code case-sensitive
#use delay(clock=32MHZ,internal=8M)  // Tells compiler what the clock speed is

// UART
#pin_select U1TX = PIN_F3
#pin_select U1RX = PIN_F2
#use rs232(baud=9600, UART1, BITS=8, STREAM=COM_A, ERRORS)

// Dependencies
#include <string.h>                           // Standard string lib
#include <stdlib.h>                           // Standard lib

// Declarations
struct f_s
{
   float a;
   float b;
   float c;
};

// Negative Float assignment test
void Test11(struct f_s * f_ptr)
{
   float b,c;
   struct f_s f_local;

   b=2.46245e3;

   disable_interrupts(INTR_GLOBAL);
   fprintf(COM_A,"\r\nNegative Float test:");
   fprintf(COM_A,"\r\nOriginal float (all others should be negative):\t %f",b);
   c=-b;
   fprintf(COM_A,"\r\nAssigned to auto float (c=-b;):\t\t\t %f",c);
   f_local.b=-b;
   fprintf(COM_A,"\r\nAssigned to local struct (f_local.b=-b;):\t %f",f_local.b);
   f_ptr->b=-1.0 * b;   
   fprintf(COM_A,"\r\nAssigned to struct ptr v1: (f_ptr->b=-1.0 * b;): %f",f_ptr->b);
   f_ptr->b=-b;
   fprintf(COM_A,"\r\nAssigned to struct ptr v2: (f_ptr->b=-b;):\t %f",f_ptr->b);

   return;
}


//==============================================
//                 MAIN
//==============================================
void main()
{
   struct f_s floatstruct;

   // Setup Port
   setup_uart(9600, COM_A);
   delay_ms(100);   // give it a second to work out the port setup

   // Run Test
   Test11(&floatstruct);   // Negative Float Test

   getch();
}


Floats. They're a bad a idea. I wish I could avoid them.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Wed Sep 29, 2010 2:00 pm     Reply with quote

I was also able to reproduce the generated code of your example in the meantime. It's still identical with most recent PCD V4.112
Code:
typedef struct
{
   float f1,f2,f3;
} FSTRUCT, *PFSTRUCT;
FSTRUCT fs;
PFSTRUCT pfs;
float f;

pfs = &fs;
f = -25.123456;
pfs->f2 = -f;
pfs->f2 = -1.0*f;


The problem is in this instruction
Code:
btg [0x000c],#15

At first sight, I doubted correctly that it doesn't negate the float variable. Because 0x000c (WREG6) is never set inside the calculation, the result of the bit set is unpredictable and will cause an address error trap in two cases:
- WREG6 is holding an odd number
- WREG6 is not pointing to a valid data address

At best, it's "only" corrupting the application data!

This operation would correctly negate a float value
Code:
btg [--0x000a],#15
miketwo



Joined: 04 Aug 2010
Posts: 24

View user's profile Send private message

PostPosted: Wed Sep 29, 2010 2:15 pm     Reply with quote

Thanks so much FvM, especially for the descriptions of what conditions would cause a reboot. That explains why it would run for a little while "correctly."

I just submitted a bug report. Hopefully they'll address this immediately, because it's a pretty basic operation.
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