Important changes to forums and questions
All forums and questions are now archived. To start a new conversation or read the latest updates go to forums.mbed.com.
6 years, 1 month ago.
Problem creating class that inherits Serial
I am trying to adapt a GPS module library to be used with a STM32 board. My problem is basically when creating the class "class UbxGps : public Serial". It seems Serial is not being recognized and every time I try to use anything from Serial.h, it just does not work.
#ifndef UBXGPS_H_ #define UBXGPS_H_ #include "mbed.h" const unsigned char UBXGPS_HEADER[] = {0xB5, 0x62}; class UbxGps : public Serial{ public: // void begin(long speed); bool ready(); protected: UbxGps(PinName tx, PinName rx); ~UbxGps(); void setLength(unsigned char length); private: int available(); uint8_t read(); void calculateChecksum(); // Class properties unsigned char offsetClassProperties = 8; unsigned char offsetHeaders = 4; unsigned char size; unsigned char carriagePosition; unsigned char checksum[2]; // Headers (common). unsigned char headerClass; unsigned char headerId; unsigned short headerLength; }; #endif
#include "UbxGps.hh" #include "mbed.h" UbxGps::UbxGps(PinName tx, PinName rx):Serial(tx,rx) { this->carriagePosition = 0; }; UbxGps::~UbxGps(){ } // void UbxGps::begin(long speed){ // return this->baud(speed); // }; bool UbxGps::ready(){ unsigned char p = this->carriagePosition; while (this->readable()){ uint8_t c = this->read(); // Carriage is at the first or the second sync byte, should be equals. if (p < 2){ if (c == UBXGPS_HEADER[p]){ p++; } // Reset if not. else{ p = 0; } } // Sync with header after success. else{ // Put the byte read to a particular address of this object which depends on the carriage position. if (p < (this->size + 2)){ ((unsigned char *)(this))[p - 2 + this->offsetClassProperties] = c; } // Move the carriage forward. p++; // Carriage is at the first checksum byte, we can calculate our checksum, but not compare, because this byte is // not read. if (p == (this->size + 2)){ this->calculateChecksum(); } // Carriage is at the second checksum byte, but only the first byte of checksum read, check if it equals to // ours. else if (p == (this->size + 3)){ // Reset if not. if (c != this->checksum[0]){ p = 0; } } // Carriage is after the second checksum byte, which has been read, check if it equals to ours. else if (p == (this->size + 4)){ // Reset the carriage. p = 0; // The readings are correct and filled the object, return true. if (c == this->checksum[1]){ this->carriagePosition = p; return true; } } // Reset the carriage if it is out of a packet. else if (p > (this->size + 4)){ p = 0; } } } this->carriagePosition = p; return false; }; void UbxGps::setLength(unsigned char length){ this->size = length + this->offsetHeaders; }; int UbxGps::available(){ return this->readable(); }; uint8_t UbxGps::read(){ return this->read(); }; void UbxGps::calculateChecksum(){ memset(this->checksum, 0, 2); for (int i = 0; i < this->size; i++){ this->checksum[0] += ((unsigned char *)(this))[i + this->offsetClassProperties]; this->checksum[1] += this->checksum[0]; } };
1 Answer
6 years, 1 month ago.
Hello Guilherme,
The modified code below compiled with success (although with lot of warnings) both online (with Keil Arm toolchain) and offline (with GNU Arm toolchain). The error messages reported when trying to compile the unmodified version can be found in comments.
main.cpp
#include "mbed.h" const unsigned char UBXGPS_HEADER[] = { 0xB5, 0x62 }; class UbxGps : public Serial { public: // void begin(long speed); bool ready(); //protected: Error: "UbxGps::UbxGps(PinName, PinName)" (declared at line 41) is inaccessible in "main.cpp", Line: 143, Col: 16 UbxGps(PinName tx, PinName rx); ~UbxGps(); void setLength(unsigned char length); private: int available(); uint8_t read(); void calculateChecksum(); // Class properties unsigned char offsetClassProperties; // = 8; Error: Data member initializer is not allowed in "main.cpp", Line: 21, Col: 44 unsigned char offsetHeaders; // = 4; Error: Data member initializer is not allowed in "main.cpp", Line: 22, Col: 44 unsigned char size; unsigned char carriagePosition; unsigned char checksum[2]; // Headers (common). unsigned char headerClass; unsigned char headerId; unsigned short headerLength; }; UbxGps::UbxGps(PinName tx, PinName rx) : Serial(tx, rx) { offsetClassProperties = 8; // initializing data member offsetHeaders = 4; // initializing data member this->carriagePosition = 0; }; UbxGps::~UbxGps() { } // void UbxGps::begin(long speed){ // return this->baud(speed); // }; bool UbxGps::ready() { unsigned char p = this->carriagePosition; while (this->readable()) { uint8_t c = this->read(); // Carriage is at the first or the second sync byte, should be equals. if (p < 2) { if (c == UBXGPS_HEADER[p]) { p++; } // Reset if not. else { p = 0; } } // Sync with header after success. else { // Put the byte read to a particular address of this object which depends on the carriage position. if (p < (this->size + 2)) { ((unsigned char*)(this))[p - 2 + this->offsetClassProperties] = c; } // Move the carriage forward. p++; // Carriage is at the first checksum byte, we can calculate our checksum, but not compare, because this byte is // not read. if (p == (this->size + 2)) { this->calculateChecksum(); } // Carriage is at the second checksum byte, but only the first byte of checksum read, check if it equals to // ours. else if (p == (this->size + 3)) { // Reset if not. if (c != this->checksum[0]) { p = 0; } } // Carriage is after the second checksum byte, which has been read, check if it equals to ours. else if (p == (this->size + 4)) { // Reset the carriage. p = 0; // The readings are correct and filled the object, return true. if (c == this->checksum[1]) { this->carriagePosition = p; return true; } } // Reset the carriage if it is out of a packet. else if (p > (this->size + 4)) { p = 0; } } } this->carriagePosition = p; return false; }; void UbxGps::setLength(unsigned char length) { this->size = length + this->offsetHeaders; }; int UbxGps::available() { return this->readable(); }; uint8_t UbxGps::read() { return this->read(); }; void UbxGps::calculateChecksum() { memset(this->checksum, 0, 2); for (int i = 0; i < this->size; i++) { this->checksum[0] += ((unsigned char*)(this))[i + this->offsetClassProperties]; this->checksum[1] += this->checksum[0]; } }; UbxGps ubxGps(USBTX, USBRX); int main() { while (true) { wait(0.5); } }
Advise: You dont have to use the this
pointer (you can delete this->
) in class methods when using data members unless you want to resolve a name clash with other variables.