Arduino error "unable to find a register to spill in class 'NO_REGS'"

时间:2016-08-31 16:55:50

标签: c++ arduino

I get an error when compiling a sketch. This sketch compiled well in previous versions (1.0.6) of the arduino IDE, I know use 1.6.9. I don't understand the message. The message is this:

Arduino: 1.6.9 (Windows 7), TD: 1.29, Board: "Arduino/Genuino Micro"

C:\Users\arnold\AppData\Local\Arduino15\packages\arduino\hardware
    \avr\1.6.13\cores\arduino\main.cpp: In function 'main':

C:\Users\arnold\AppData\Local\Arduino15\packages\arduino\hardware
    \avr\1.6.13\cores\arduino\main.cpp:51:1: error: unable to find a 
     register to spill in class 'NO_REGS'

 }

 ^

C:\Users\arnold\AppData\Local\Arduino15\packages\arduino\hardware
    \avr\1.6.13\cores\arduino\main.cpp:51:1: error: this is the insn:

(insn 601 598 604 45 (set (mem:QI (post_dec:HI (reg/f:HI 32 __SP_L__)) [0  S1 A8])

        (subreg:QI (reg/f:HI 658) 1)) sketch\coordinates.cpp:23 1 {pushqi1}

     (expr_list:REG_ARGS_SIZE (const_int 1 [0x1])

        (nil)))

C:\Users\arnold\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.13\cores\arduino\main.cpp:51: confused by earlier errors, bailing out

lto-wrapper: C:\Users\arnold\AppData\Local\Arduino15\packages\arduino\tools\avr-gcc\4.9.2-atmel3.5.3-arduino2/bin/avr-gcc returned 1 exit status

c:/users/arnold/appdata/local/arduino15/packages/arduino/tools/avr-gcc/4.9.2-atmel3.5.3-arduino2/bin/../lib/gcc/avr/4.9.2/../../../../avr/bin/ld.exe: lto-wrapper failed

collect2.exe: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino/Genuino Micro.

It seems to refer to class coordinates, line 23. I use a sscanf function in that line.

coordinates.cpp

#include "coordinates.h"

// Include common data (shared bps and such)
#include "D:\home\arnold\development\arduino\drone\serial_comm\data.h"
// TX_FORMAT_1 found in data.h: #define TX_FORMAT_1 "%ld %ld %ld %d %d"
Coordinates::Coordinates ()
{
   ap_latitude = 0; 
   ap_longitude = 0;
   ap_bar_altitude = 0;
   ap_groundspeed = 0;
   ap_heading = 0;
   noGPSLock = 1;
   setHome (52.026919, 6.373969); // Defaults to Varsel airport
} /*** Coordinates ***/

// Decodes a data string
void Coordinates::readSettings (char *buffer)
{
   int32_t lat, lng;
   int32_t alt;

   sscanf (buffer, TX_FORMAT_1, &lat, &lng, &alt, &ap_groundspeed, &ap_heading);
   ap_latitude  = double (lat) / 10000000.0;
   ap_longitude = double (lng) / 10000000.0;
   ap_bar_altitude = double (alt) / 100.0;
   noGPSLock = (lat == 0) && (lng == 0);
} /*** readSettings ***/   

int8_t Coordinates::setHome (double lat, double lng)
{
   if ((ap_latitude >= -90000000) && (ap_latitude <= +90000000) &&
       (ap_longitude >= -180000000) && (ap_longitude <= 180000000))
   {
      home_latitude  = lat;  
      home_longitude = lng;
      Serial.print (F ("New home set at: ("));
      Serial.print (home_latitude, 7);
      Serial.print (F (", "));
      Serial.print (home_longitude, 7);
      Serial.println (")");
      return 1; // ok
   } else
   {
      Serial.print (F ("Couldn't set home. Lat = "));
      Serial.print (ap_latitude, 7);
      Serial.print (F ("long = "));
      Serial.print (ap_longitude, 7);
      Serial.println ("");
      return 0; // abnormal values encountered, no home set, return error
   } // if
} /*** setHome ***/

// Returns the distance of two coordinates (in decimal degrees) in meters
double Coordinates::haverSine (double lat1, double lon1, double lat2, double lon2)
{
   double R, phi_1, phi_2, phi_delta;
   double lambda_delta;
   double a, c;

   phi_1 = radians (lat1);
   phi_2 = radians (lat2);
   phi_delta = radians (lat2-lat1);
   lambda_delta = (radians (lon2) - radians (lon1));

   a = sin(phi_delta/2) * sin(phi_delta/2) +
       cos(phi_1) * cos(phi_2) *
        sin(lambda_delta/2) * sin(lambda_delta/2);

   if (a < 0.0) a = 0.0;
   c = 2.0 * atan2 (sqrt (a), sqrt (1-a));
   return Radius * c;
} /*** haverSine ***/

// Returns the distance between ap_lat/long and home_lat/long in meters
double Coordinates::distanceToHome ()
{
   return haverSine (ap_latitude, ap_longitude, home_latitude, home_longitude);
} /*** distanceToHome ***/

// returns the time (s) an object takes to fall to earth (in NL) given a height (in m)
double Coordinates::fallTime (double h)
{
   double val = 2.0 * h / g;

   if (val > 0.0) // Value should be > 0
      return sqrt (val);
   else // else return 0, no check on negative results (which is erroneous)
      return 0.0;   
} /*** fallTime ***/

// return the number of meters travelled given time t (s) and speed v (m/s)
double Coordinates::travelled (double t, double v)
{
   return v * t;      
} /*** travelled ***/

// return the number of meters travelled given time t (s) and 
// current ground speed (m/s)
double Coordinates::distanceToTravel (double t)
{
   return travelled (t, ap_groundspeed);      
} /*** distanceToTravel ***/

double Coordinates::computeAngle (double x1, double y1, double x2, double y2)
{
   double deltaY = y2 - y1;
   double deltaX = x2 - x1;
   double angleInDegrees = atan2(deltaY, deltaX) * 180 / PI;

   return angleInDegrees;
} /*** computeAngle ***/

void Coordinates::printStatus (Stream* stream)
{
   double t;
   double d;

   Serial.print (F(">>> Lat: "));
   Serial.print (ap_latitude, 7);
   Serial.print (F(", Long: "));
   Serial.print (ap_longitude, 7);
   Serial.print (F(", Alt: "));
   Serial.print (ap_bar_altitude);
   Serial.print (F(", Speed: "));
   Serial.print (ap_groundspeed);
   Serial.print (F(", Heading: "));
   Serial.print (ap_heading);
   Serial.print (F(", distance: "));
   Serial.print (distanceToHome ());
   Serial.print (F(", Angle: "));
   Serial.print (computeAngle (ap_latitude, ap_longitude, home_latitude, home_longitude), 7);
   Serial.println ("");

   t = fallTime (double (ap_groundspeed));
   d = abs (distanceToHome () - distanceToTravel (t));
   Serial.print (F ("Given Alt - drop time: "));
   Serial.print (t);
   Serial.print (F(", d(travel): "));
   Serial.print (travelled (t, ap_bar_altitude), 4);
   Serial.print (F(", d (ground speed): "));
   Serial.print (distanceToTravel (t));
   Serial.print (F(", abs (d (home)-d (travel)): "));
   Serial.print (d, 4);
   Serial.println ("");
} /*** printStatus ***/

coordinates.h

#ifndef coordinates__h
#define coordinates__h

#include <arduino.h>
#include <HardwareSerial.h>

const double Radius = 6367444.5; // radius of earth in meters
const double g = 9.8124; // m/s2 for Varsel airport

class Coordinates
{
private:

public:
   double   ap_latitude;              // decimal degrees
   double   ap_longitude;             // decimal degrees
   double   ap_bar_altitude;          // 100 = 1m
   uint32_t ap_groundspeed;           // in m/s
   uint32_t ap_heading;               // degrees

   double home_latitude;
   double home_longitude;

   int8_t noGPSLock;

   Coordinates ();
   void   readSettings (char *buffer);
   int8_t setHome (double lat, double lng);
   double haverSine (double lat1, double lon1, double lat2, double lon2);
   double distanceToHome ();
   double fallTime (double h);
   double travelled (double t, double v);
   double distanceToTravel (double t);
   double computeAngle (double x1, double y1, double x2, double y2);
   void   printStatus (Stream* stream);
}; /*** class: Pwn ***/

#endif

Does anyone how I can avoid this error?

Edit 1

When experimenting I noticed that reading one variable like:

sscanf (buffer, TX_FORMAT_1, &lat);

compiles correctly. Adding a second variable however, generates the error again.

1 个答案:

答案 0 :(得分:0)

在网上搜索似乎指向版本1.6.9(和其他1.6.x版本)中使用的the cpp compiler中的错误。通过&#34;升级&#34; arduino IDE从1.6.9到1.0.6问题消失了。这不是最好的方式,但它有效。因为我没有使用1.6版本升级的任何功能都没有问题。