You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To begin with, this library is excellent for people who are sandwiched between C++ and Arduino. :) Nevermind, I have started to use this library and it works with most of my cases except the situation my single global class object is giving different address at two places.
Consider this scenario:
driver.h file I have placed this header file at the Arduino.h level so that I can access driver.h file from anywhere.
#pragma once
#ifndef MOTOR_DRIVER_INCLUDED_
#define MOTOR_DRIVER_INCLUDED_
#include<ArduinoSTL.h>
#include<Arduino.h>
class Element {
public:
bool isTLE;
Element() {
isTLE = false;
}
};
class Motor {
public:
Motor() {
Serial.println("Calling the motor constructor");
}
~Motor() {
}
void stopAllBoard();
std::vector<Element*> commandsQueue;
};
SPI1.h file It is placed at its own standard path.
This is a standard SPI1 library with only minor modifcation in transfer16 function. I am just pushing the command in transfer16 to an queue and printing the address of the object there. Snapshot of SPI1.h file:
....
#include<driver.h>
....
inline static uint16_t transfer16(uint16_t data) {
// My code starts
Element* elem = new Element();
elem->isTLE = true;
motor->commandsQueue.push_back(elem);
Serial.print("Pushed the SPI1 object into the queue with 16bit data. Size queue = ");
Serial.println(motor->commandsQueue.size());
Serial.printf("Motor address at transfer : %x", motor);
Serial.println("");
Serial.print("Size of motor object at transfer: ");
Serial.println(sizeof(motor));
// My code ends
union { uint16_t val; struct { uint8_t lsb; uint8_t msb; }; } in, out;
in.val = data;
if (!(SPCR1 & _BV(DORD))) {
SPDR1 = in.msb;
asm volatile("nop"); // See transfer(uint8_t) function
while (!(SPSR1 & _BV(SPIF)));// {Serial.println(data,HEX);}
out.msb = SPDR1;
SPDR1 = in.lsb;
//Serial.println(in.msb,HEX);
asm volatile("nop");
while (!(SPSR1 & _BV(SPIF))) ;
out.lsb = SPDR1;
} else {
SPDR1 = in.lsb;
asm volatile("nop");
while (!(SPSR1 & _BV(SPIF))) ;
out.lsb = SPDR1;
SPDR1 = in.msb;
asm volatile("nop");
while (!(SPSR1 & _BV(SPIF))) ;
out.msb = SPDR1;
}
return out.val;
}
....
....
main.cpp
#include<motor_driver.h>
void setup() {
Serial.begin(9600);
Serial.println("");
Serial.printf("Motor address at setup : %x", motor);
Serial.println("");
motor->stopAllBoard();
motor->stopAllBoard();
Serial.print("Commands queue size at the operation start = ");
Serial.println(motor->commandsQueue.size());
Serial.printf("Motor address at setup : %x", motor);
Serial.println("");
}
Output of main.cpp comes out like this in Arduino serial monitor.
18:54:31.008 -> Motor address at setup : 2df
18:54:31.008 -> Pushed the SPI1 object into the queue with 16bit data. Size queue = 1
18:54:31.066 -> Motor address at transfer : 2c4
18:54:31.148 -> Size of motor object at transfer: 2
18:54:31.148 -> ,
18:54:31.148 -> Pushed the SPI1 object into the queue with 16bit data. Size queue = 2
18:54:31.288 -> Motor address at transfer : 2c4
18:54:31.288 -> Size of motor object at transfer: 2
18:54:31.335 -> , ,
18:54:31.335 -> Commands queue size at the operation start = 0
18:54:31.335 ->
If you notice the output, motor address at main.cpp is different than the motor object address in SPI1.h. This means that my vector, considering it as queue. :), does not have right elements in main.cpp.
Out of ideas for this since I do not see any programming issue here. Can anyone suggest a way to move forward. Thank you.
The text was updated successfully, but these errors were encountered:
This is because motor is an internal-linked (as declared by the keyword static) variable defined in a header file included in multiple translation units (.cpp files, TU). An internal-linked variable is TU-local, i.e., has an independent copy for each TU, so they must have different addresses, and cannot be named in other TUs. See storage class specifiers.
If you want to name the same shared motor across TUs, you must declare the motor as external-linked (extern) in the header file and define it in one of your TUs. For example:
//driver.hextern Motor* motor;
//driver.cpp
Motor* motor = new Motor;
Hi Everyone,
To begin with, this library is excellent for people who are sandwiched between C++ and Arduino. :) Nevermind, I have started to use this library and it works with most of my cases except the situation my single global class object is giving different address at two places.
Consider this scenario:
driver.h file I have placed this header file at the Arduino.h level so that I can access driver.h file from anywhere.
#pragma once
#ifndef MOTOR_DRIVER_INCLUDED_
#define MOTOR_DRIVER_INCLUDED_
#include<ArduinoSTL.h>
#include<Arduino.h>
class Element {
public:
bool isTLE;
Element() {
isTLE = false;
}
};
class Motor {
public:
Motor() {
Serial.println("Calling the motor constructor");
}
~Motor() {
}
void stopAllBoard();
std::vector<Element*> commandsQueue;
};
static Motor* motor = new Motor;
#endif
driver.cpp file
#include <SPI1.h>
void Motor::stopSomething() {
SPI1.transfer16(0x801);
}
SPI1.h file It is placed at its own standard path.
This is a standard SPI1 library with only minor modifcation in transfer16 function. I am just pushing the command in transfer16 to an queue and printing the address of the object there. Snapshot of SPI1.h file:
....
#include<driver.h>
....
inline static uint16_t transfer16(uint16_t data) {
// My code starts
Element* elem = new Element();
elem->isTLE = true;
motor->commandsQueue.push_back(elem);
Serial.print("Pushed the SPI1 object into the queue with 16bit data. Size queue = ");
Serial.println(motor->commandsQueue.size());
Serial.printf("Motor address at transfer : %x", motor);
Serial.println("");
Serial.print("Size of motor object at transfer: ");
Serial.println(sizeof(motor));
// My code ends
}
....
....
main.cpp
#include<motor_driver.h>
void setup() {
Serial.begin(9600);
Serial.println("");
Serial.printf("Motor address at setup : %x", motor);
Serial.println("");
motor->stopAllBoard();
motor->stopAllBoard();
Serial.print("Commands queue size at the operation start = ");
Serial.println(motor->commandsQueue.size());
Serial.printf("Motor address at setup : %x", motor);
Serial.println("");
}
Output of main.cpp comes out like this in Arduino serial monitor.
18:54:31.008 -> Motor address at setup : 2df
18:54:31.008 -> Pushed the SPI1 object into the queue with 16bit data. Size queue = 1
18:54:31.066 -> Motor address at transfer : 2c4
18:54:31.148 -> Size of motor object at transfer: 2
18:54:31.148 -> ,
18:54:31.148 -> Pushed the SPI1 object into the queue with 16bit data. Size queue = 2
18:54:31.288 -> Motor address at transfer : 2c4
18:54:31.288 -> Size of motor object at transfer: 2
18:54:31.335 -> , ,
18:54:31.335 -> Commands queue size at the operation start = 0
18:54:31.335 ->
If you notice the output, motor address at main.cpp is different than the motor object address in SPI1.h. This means that my vector, considering it as queue. :), does not have right elements in main.cpp.
Out of ideas for this since I do not see any programming issue here. Can anyone suggest a way to move forward. Thank you.
The text was updated successfully, but these errors were encountered: