ATmega32U4 で Serial.write(buff,len) (USB 仮想シリアル ポート経由) を使用して大量のデータを送信しようとしています。私はもともと LUFA を使用してアプリケーションを作成しましたが、うまく機能しました。ただし、Arduinoに移植したところ、データがドロップしています。
関連するコードは
void uartTask() {
static unsigned long timer = 0;
if (Serial) { // does the data have somewhere to go?
uint16_t ct = RingBuffer_GetCount(&serialBuffer);
unsigned long curTime = millis();
if (ct > 64 || (timer-curTime > 100)) { // is there data to send?
timer = curTime;
if (serialBuffer.Out + ct <= serialBuffer.End) { // does it loop in our buffer?
ct = Serial.write(serialBuffer.Out, ct); // dump all the date
serialBuffer.Out += ct;
if (serialBuffer.Out == serialBuffer.End)
serialBuffer.Out = serialBuffer.Start; // loop the buffer
}
else { // it looped the ring buffer
uint8_t* loopend = serialBuffer.Out + ct;
uint16_t ct2 = loopend - serialBuffer.End;
uint16_t ct1 = ct - ct2;
uint16_t ct1s = Serial.write(serialBuffer.Out, ct1); // dump first block
if (ct1s == ct1) {
ct2 = Serial.write(serialBuffer.Start, ct2); // dump second block
serialBuffer.Out = serialBuffer.Start + ct2; // update the pointers
ct = ct1+ct2;
}
else {
ct = ct1s;
serialBuffer.Out += ct;
}
}
uint_reg_t CurrentGlobalInt = GetGlobalInterruptMask();
GlobalInterruptDisable();
serialBuffer.Count -= ct; // update the count
SetGlobalInterruptMask(CurrentGlobalInt);
}
if (RingBuffer_GetCount(&serialBuffer) < 256) {
SET(TX_BUSY, LOW); // re-enable the serial port
serialRXEnable();
}
int16_t w;
while ((w = Serial.read()) >= 0) {
Serial_SendByte(w);
}
}
}
ISR(USART1_RX_vect) { // new serial data!
RingBuffer_Insert(&serialBuffer, UDR1 ); // save it
if (serialBuffer.Count > 1000) // are we almost out of space?
SET(TX_BUSY, HIGH); // signal we can't take any more
if (serialBuffer.Count > 1020)
serialRXDisable(); // if our flag is ignored disable the serial port so it doesn't clog things up
}
LUFA とほぼ同じコードを使用しましたが、データがドロップされることはありません。PCでUbuntuを実行しています。
これは基本的に単なる USB からシリアルへのコンバーターです。シリアルデータが到着すると、データをリングバッファに入れる割り込みを発生させます。リングバッファは後で読み取られ、USB 経由で送信されます。
LUFA ベースのコードが機能する理由がわかりませんが、Arduino は機能しません。Serial.write() の戻り値を確認すると、データが完全に作成されていないかどうかがわかると思います。
何が起こっているのですか?