add fifo to usart, test
This commit is contained in:
parent
95b08e26ae
commit
9140ee66f9
2 changed files with 44 additions and 11 deletions
|
@ -19,18 +19,24 @@ static constexpr unsigned Timeout = 5000; // us
|
||||||
* */
|
* */
|
||||||
class Middle : public BaseLayer {
|
class Middle : public BaseLayer {
|
||||||
static constexpr unsigned max = 128;
|
static constexpr unsigned max = 128;
|
||||||
|
FIFO<char,max> rx_ring;
|
||||||
volatile unsigned index;
|
volatile unsigned index;
|
||||||
char buffer [max];
|
char buffer [max];
|
||||||
public:
|
public:
|
||||||
explicit Middle () noexcept : BaseLayer(), index(0u) {}
|
explicit Middle () noexcept : BaseLayer(), rx_ring(), index(0u) {}
|
||||||
/* Up() v původním řetězci volalo fakticky Down() v cdc_class.
|
/* Up() v původním řetězci volalo fakticky Down() v cdc_class.
|
||||||
* Vzhledem k tomu, že len je zde 1 a USB musí vyvolat odeslání
|
* Vzhledem k tomu, že len je zde 1 a USB musí vyvolat odeslání
|
||||||
* paketu, zdržuje to a přerušení zde může být ignorováno.
|
* paketu, zdržuje to a přerušení zde může být ignorováno.
|
||||||
* Tohle ho významně zkrátí, ale zase musí být v hlavní smyčce
|
* Tohle ho významně zkrátí, ale zase musí být v hlavní smyčce
|
||||||
* odeslání dat pomocí metody pass().
|
* odeslání dat pomocí metody pass(). Ukázalo se, že je nutné
|
||||||
|
* předávat data přes další frontu. Pak to funguje full duplex
|
||||||
|
* na rychlosti 4 MBd bez ztráty znaků.
|
||||||
* */
|
* */
|
||||||
uint32_t Up(const char * data, const uint32_t len) override {
|
uint32_t Up(const char * data, const uint32_t len) override {
|
||||||
for (unsigned n=0; n<len; n++) buffer [index++] = data [n];
|
for (unsigned n=0; n<len; n++) {
|
||||||
|
if (!rx_ring.Write (data[n])) break;
|
||||||
|
else index += 1u;
|
||||||
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
// Down je průchozí, bylo by možné toto zcela vypustit.
|
// Down je průchozí, bylo by možné toto zcela vypustit.
|
||||||
|
@ -41,10 +47,16 @@ public:
|
||||||
* */
|
* */
|
||||||
void pass () {
|
void pass () {
|
||||||
/* Je to dost zjednodušeno, odešle se 64 bytový paket,
|
/* Je to dost zjednodušeno, odešle se 64 bytový paket,
|
||||||
* nebo po 5 ms to co zůstalo v bufferu.
|
* nebo po 5 ms to co zůstalo ve frontě.
|
||||||
* */
|
* */
|
||||||
if ((is_timeout() and index) or (index >= 64)) {
|
if ((is_timeout() and index) or (index >= 64)) {
|
||||||
block(buffer, index);
|
unsigned n;
|
||||||
|
for (n=0u; n<max; n++) {
|
||||||
|
if (!rx_ring.Read (buffer[n])) break;
|
||||||
|
}
|
||||||
|
if (!n) return;
|
||||||
|
index = 0u;
|
||||||
|
block(buffer, n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
|
@ -55,7 +67,6 @@ public:
|
||||||
rem -= n;
|
rem -= n;
|
||||||
ofs += n;
|
ofs += n;
|
||||||
}
|
}
|
||||||
index = 0;
|
|
||||||
set_timeout_us(Timeout);
|
set_timeout_us(Timeout);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,45 +1,67 @@
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <chrono>
|
||||||
|
using namespace std::chrono;
|
||||||
|
|
||||||
class Top : public BaseLayer {
|
class Top : public BaseLayer {
|
||||||
static constexpr int max = 1024;
|
static constexpr int max = 1024;
|
||||||
|
unsigned tx_cnt, rx_cnt;
|
||||||
volatile unsigned index;
|
volatile unsigned index;
|
||||||
int passcnt;
|
int passcnt;
|
||||||
char buffer [max];
|
char buffer [max];
|
||||||
public:
|
public:
|
||||||
explicit Top () : BaseLayer(), index(0u), passcnt(0) {}
|
explicit Top () : BaseLayer(), tx_cnt(0u), rx_cnt(0u), index(0u), passcnt(0) {}
|
||||||
void puts (const char * str) {
|
void puts (const char * str) {
|
||||||
const unsigned l = strlen(str);
|
const unsigned l = strlen(str);
|
||||||
Down(str, l);
|
tx_cnt += Down(str, l);
|
||||||
}
|
}
|
||||||
uint32_t Up(const char * data, const uint32_t len) override {
|
uint32_t Up(const char * data, const uint32_t len) override {
|
||||||
|
rx_cnt += len;
|
||||||
for (unsigned n=0; n<len; n++) {
|
for (unsigned n=0; n<len; n++) {
|
||||||
const char c = data [n];
|
const char c = data [n];
|
||||||
buffer [index++] = c;
|
buffer [index++] = c;
|
||||||
if (c == '\n') {
|
if (c == '\n') {
|
||||||
buffer [index - 2] = '\0';
|
buffer [index - 2] = '\0';
|
||||||
printf("Rx (%d) %s\n", passcnt++, buffer);
|
printf("Rx (%d) %s \r", passcnt++, buffer);
|
||||||
|
fflush(stdout);
|
||||||
index = 0u;
|
index = 0u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
void result (const int t) {
|
||||||
|
const double real_br = 1.0e6 * (double) tx_cnt / (double) t;
|
||||||
|
printf("\nTx %d, Rx %d, tx = %g bytes/s\n", tx_cnt, rx_cnt, real_br);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
static const char * TestString = "THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG'S BACK 1234567890\r\n";
|
static const char * TestString = "THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG'S BACK 1234567890\r\n";
|
||||||
static volatile bool loop = false;
|
static volatile bool loop = false;
|
||||||
static void Handler (int) {
|
static void Handler (int) {
|
||||||
loop = false;
|
loop = false;
|
||||||
}
|
}
|
||||||
int main (void) {
|
int main (int argc, char * argv[]) {
|
||||||
|
// 4 MBd je maximum.
|
||||||
|
int baud = 4'000'000;
|
||||||
|
if (argc > 1) {
|
||||||
|
baud = atoi (argv[1]);
|
||||||
|
}
|
||||||
loop = true;
|
loop = true;
|
||||||
signal (SIGINT, Handler);
|
signal (SIGINT, Handler);
|
||||||
UsartClass usart ("/dev/serial/by-id/usb-Kizarm_Labs._USB__=__USART_0002-if00", 1'000'000);
|
//UsartClass usart ("/dev/ttyACM0", baud); // obecně
|
||||||
|
UsartClass usart ("/dev/serial/by-id/usb-Kizarm_Labs._USB__=__USART_0002-if00", baud);
|
||||||
Top top;
|
Top top;
|
||||||
top += usart;
|
top += usart;
|
||||||
|
auto start = high_resolution_clock::now();
|
||||||
while (loop) {
|
while (loop) {
|
||||||
top.puts(TestString);
|
top.puts(TestString);
|
||||||
}
|
}
|
||||||
|
auto stop = high_resolution_clock::now();
|
||||||
|
usleep(100'000);
|
||||||
|
int duration = duration_cast<microseconds>(stop - start).count();
|
||||||
|
top.result(duration);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue