我使用eclipse製作arduino.I項目。將Wire.h包含到一個新類中,並且在arduinocore庫項目中,我在Wire.h頭文件中出現錯誤。誤差是在該行 76在其端部:wire.h外部雙線對象錯誤
extern TwoWire Wire;
,它說
描述資源路徑位置類型 類型「兩線」必須實現繼承純虛方法「打印:: write'Wire.h/ArduinoCore/src line 76代碼分析問題
我給你.cpp和頭文件,它們和arduino ide裏面一樣。 我能做些什麼來解決這個問題?
#ifndef TwoWire_h
#define TwoWire_h
#include <inttypes.h>
#include "Stream.h"
#define BUFFER_LENGTH 32
class TwoWire : public Stream
{
private:
static uint8_t rxBuffer[];
static uint8_t rxBufferIndex;
static uint8_t rxBufferLength;
static uint8_t txAddress;
static uint8_t txBuffer[];
static uint8_t txBufferIndex;
static uint8_t txBufferLength;
static uint8_t transmitting;
static void (*user_onRequest)(void);
static void (*user_onReceive)(int);
static void onRequestService(void);
static void onReceiveService(uint8_t*, int);
public:
TwoWire();
void begin();
void begin(uint8_t);
void begin(int);
void beginTransmission(uint8_t);
void beginTransmission(int);
uint8_t endTransmission(void);
uint8_t endTransmission(uint8_t);
uint8_t requestFrom(uint8_t, uint8_t);
uint8_t requestFrom(uint8_t, uint8_t, uint8_t);
uint8_t requestFrom(int, int);
uint8_t requestFrom(int, int, int);
virtual size_t write(uint8_t);
virtual size_t write(const uint8_t *, size_t);
virtual int available(void);
virtual int read(void);
virtual int peek(void);
virtual void flush(void);
void onReceive(void (*)(int));
void onRequest(void (*)(void));
inline size_t write(unsigned long n) { return write((uint8_t)n); }
inline size_t write(long n) { return write((uint8_t)n); }
inline size_t write(unsigned int n) { return write((uint8_t)n); }
inline size_t write(int n) { return write((uint8_t)n); }
using Print::write;
};
extern TwoWire Wire;
#endif
和cpp文件:
extern "C" {
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "twi.h"
}
#include "Wire.h"
// Initialize Class Variables //////////////////////////////////////////////////
uint8_t TwoWire::rxBuffer[BUFFER_LENGTH];
uint8_t TwoWire::rxBufferIndex = 0;
uint8_t TwoWire::rxBufferLength = 0;
uint8_t TwoWire::txAddress = 0;
uint8_t TwoWire::txBuffer[BUFFER_LENGTH];
uint8_t TwoWire::txBufferIndex = 0;
uint8_t TwoWire::txBufferLength = 0;
uint8_t TwoWire::transmitting = 0;
void (*TwoWire::user_onRequest)(void);
void (*TwoWire::user_onReceive)(int);
// Constructors ////////////////////////////////////////////////////////////////
TwoWire::TwoWire()
{
}
// Public Methods //////////////////////////////////////////////////////////////
void TwoWire::begin(void)
{
rxBufferIndex = 0;
rxBufferLength = 0;
txBufferIndex = 0;
txBufferLength = 0;
twi_init();
}
void TwoWire::begin(uint8_t address)
{
twi_setAddress(address);
twi_attachSlaveTxEvent(onRequestService);
twi_attachSlaveRxEvent(onReceiveService);
begin();
}
void TwoWire::begin(int address)
{
begin((uint8_t)address);
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity, uint8_t sendStop)
{
// clamp to buffer length
if(quantity > BUFFER_LENGTH){
quantity = BUFFER_LENGTH;
}
// perform blocking read into buffer
uint8_t read = twi_readFrom(address, rxBuffer, quantity, sendStop);
// set rx buffer iterator vars
rxBufferIndex = 0;
rxBufferLength = read;
return read;
}
uint8_t TwoWire::requestFrom(uint8_t address, uint8_t quantity)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
}
uint8_t TwoWire::requestFrom(int address, int quantity)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)true);
}
uint8_t TwoWire::requestFrom(int address, int quantity, int sendStop)
{
return requestFrom((uint8_t)address, (uint8_t)quantity, (uint8_t)sendStop);
}
void TwoWire::beginTransmission(uint8_t address)
{
// indicate that we are transmitting
transmitting = 1;
// set address of targeted slave
txAddress = address;
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
}
void TwoWire::beginTransmission(int address)
{
beginTransmission((uint8_t)address);
}
//
// Originally, 'endTransmission' was an f(void) function.
// It has been modified to take one parameter indicating
// whether or not a STOP should be performed on the bus.
// Calling endTransmission(false) allows a sketch to
// perform a repeated start.
//
// WARNING: Nothing in the library keeps track of whether
// the bus tenure has been properly ended with a STOP. It
// is very possible to leave the bus in a hung state if
// no call to endTransmission(true) is made. Some I2C
// devices will behave oddly if they do not see a STOP.
//
uint8_t TwoWire::endTransmission(uint8_t sendStop)
{
// transmit buffer (blocking)
int8_t ret = twi_writeTo(txAddress, txBuffer, txBufferLength, 1, sendStop);
// reset tx buffer iterator vars
txBufferIndex = 0;
txBufferLength = 0;
// indicate that we are done transmitting
transmitting = 0;
return ret;
}
// This provides backwards compatibility with the original
// definition, and expected behaviour, of endTransmission
//
uint8_t TwoWire::endTransmission(void)
{
return endTransmission(true);
}
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
size_t TwoWire::write(uint8_t data)
{
if(transmitting){
// in master transmitter mode
// don't bother if buffer is full
if(txBufferLength >= BUFFER_LENGTH){
setWriteError();
return 0;
}
// put byte in tx buffer
txBuffer[txBufferIndex] = data;
++txBufferIndex;
// update amount in buffer
txBufferLength = txBufferIndex;
}else{
// in slave send mode
// reply to master
twi_transmit(&data, 1);
}
return 1;
}
// must be called in:
// slave tx event callback
// or after beginTransmission(address)
size_t TwoWire::write(const uint8_t *data, size_t quantity)
{
if(transmitting){
// in master transmitter mode
for(size_t i = 0; i < quantity; ++i){
write(data[i]);
}
}else{
// in slave send mode
// reply to master
twi_transmit(data, quantity);
}
return quantity;
}
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::available(void)
{
return rxBufferLength - rxBufferIndex;
}
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::read(void)
{
int value = -1;
// get each successive byte on each call
if(rxBufferIndex < rxBufferLength){
value = rxBuffer[rxBufferIndex];
++rxBufferIndex;
}
return value;
}
// must be called in:
// slave rx event callback
// or after requestFrom(address, numBytes)
int TwoWire::peek(void)
{
int value = -1;
if(rxBufferIndex < rxBufferLength){
value = rxBuffer[rxBufferIndex];
}
return value;
}
void TwoWire::flush(void)
{
// XXX: to be implemented.
}
// behind the scenes function that is called when data is received
void TwoWire::onReceiveService(uint8_t* inBytes, int numBytes)
{
// don't bother if user hasn't registered a callback
if(!user_onReceive){
return;
}
// don't bother if rx buffer is in use by a master requestFrom() op
// i know this drops data, but it allows for slight stupidity
// meaning, they may not have read all the master requestFrom() data yet
if(rxBufferIndex < rxBufferLength){
return;
}
// copy twi rx buffer into local read buffer
// this enables new reads to happen in parallel
for(uint8_t i = 0; i < numBytes; ++i){
rxBuffer[i] = inBytes[i];
}
// set rx iterator vars
rxBufferIndex = 0;
rxBufferLength = numBytes;
// alert user program
user_onReceive(numBytes);
}
// behind the scenes function that is called when data is requested
void TwoWire::onRequestService(void)
{
// don't bother if user hasn't registered a callback
if(!user_onRequest){
return;
}
// reset tx buffer iterator vars
// !!! this will kill any pending pre-master sendTo() activity
txBufferIndex = 0;
txBufferLength = 0;
// alert user program
user_onRequest();
}
// sets function called on slave write
void TwoWire::onReceive(void (*function)(int))
{
user_onReceive = function;
}
// sets function called on slave read
void TwoWire::onRequest(void (*function)(void))
{
user_onRequest = function;
}
// Preinstantiate Objects //////////////////////////////////////////////////////
TwoWire Wire = TwoWire();
清楚該錯誤消息說,你所要做的,就是你的問題,你不明白它說什麼?或者你不知道如何遵循它? – PlasmaHH 2013-02-21 11:48:13
我不知道如何跟着它 – kyrpav 2013-02-21 17:04:05
實際上,Arduino TwoWire代碼確實實現了純虛擬Print :: write()方法,而且代碼實際上使用GNU工具鏈編譯得很好。問題在於Eclipse。看到我的回答 – Greycon 2014-02-13 22:13:17