Use mg_queue in mip

This commit is contained in:
cpq committed 2023-02-24 19:40:31 +00:00
1 parent 4436093816
commit 910f19fe55
11 files changed
+86 -212

No files matched your search

+1 -3
View File
@@ -184,8 +184,6 @@ static bool mg_tcpip_driver_imxrt1020_init(struct mg_tcpip_if *ifp) {
// RX Descriptor activation
ENET->RDAR = BIT(24); // Activate Receive Descriptor
if (ifp->queue.len == 0) ifp->queue.len = 8192;
return true;
}
@@ -260,7 +258,7 @@ static bool mg_tcpip_driver_imxrt1020_up(struct mg_tcpip_if *ifp) {
// API
struct mg_tcpip_driver mg_tcpip_driver_imxrt1020 = {
mg_tcpip_driver_imxrt1020_init, mg_tcpip_driver_imxrt1020_tx, mg_tcpip_driver_rx,
mg_tcpip_driver_imxrt1020_init, mg_tcpip_driver_imxrt1020_tx, NULL,
mg_tcpip_driver_imxrt1020_up};
#endif
+3 -4
View File
@@ -150,7 +150,6 @@ static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
((uint32_t) ifp->mac[2] << 16) |
((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
if (ifp->queue.len == 0) ifp->queue.len = 8192;
return true;
}
@@ -212,7 +211,7 @@ void ETH_IRQHandler(void) {
ETH->DMARPDR = 0; // and resume RX
}
struct mg_tcpip_driver mg_tcpip_driver_stm32 = {
mg_tcpip_driver_stm32_init, mg_tcpip_driver_stm32_tx, mg_tcpip_driver_rx,
mg_tcpip_driver_stm32_up};
struct mg_tcpip_driver mg_tcpip_driver_stm32 = {mg_tcpip_driver_stm32_init,
mg_tcpip_driver_stm32_tx, NULL,
mg_tcpip_driver_stm32_up};
#endif
+1 -2
View File
@@ -203,7 +203,6 @@ static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
ETH->MACA0LR = (uint32_t) (ifp->mac[3] << 24) |
((uint32_t) ifp->mac[2] << 16) |
((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
if (ifp->queue.len == 0) ifp->queue.len = 8192;
return true;
}
@@ -271,6 +270,6 @@ void ETH_IRQHandler(void) {
}
struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, mg_tcpip_driver_rx,
mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, NULL,
mg_tcpip_driver_stm32h_up};
#endif
+3 -5
View File
@@ -178,8 +178,6 @@ static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
((uint32_t) ifp->mac[1] << 8) | ifp->mac[0];
// NOTE(scaprile) There are 3 additional slots for filtering, disabled by
// default. This also applies to the STM32 driver (at least for F7)
if (ifp->queue.len == 0) ifp->queue.len = 8192;
return true;
}
@@ -245,7 +243,7 @@ void EMAC0_IRQHandler(void) {
EMAC->EMACRXPOLLD = 0; // and resume RX
}
struct mg_tcpip_driver mg_tcpip_driver_tm4c = {
mg_tcpip_driver_tm4c_init, mg_tcpip_driver_tm4c_tx, mg_tcpip_driver_rx,
mg_tcpip_driver_tm4c_up};
struct mg_tcpip_driver mg_tcpip_driver_tm4c = {mg_tcpip_driver_tm4c_init,
mg_tcpip_driver_tm4c_tx, NULL,
mg_tcpip_driver_tm4c_up};
#endif
+24 -61
View File
@@ -128,53 +128,9 @@ struct pkt {
struct dhcp *dhcp;
};
static void q_copyin(struct queue *q, const uint8_t *buf, size_t len,
size_t head) {
size_t left = q->len - head;
memcpy(&q->buf[head], buf, left < len ? left : len);
if (left < len) memcpy(q->buf, &buf[left], len - left);
}
static void q_copyout(struct queue *q, uint8_t *buf, size_t len, size_t tail) {
size_t left = q->len - tail;
memcpy(buf, &q->buf[tail], left < len ? left : len);
if (left < len) memcpy(&buf[left], q->buf, len - left);
}
static bool q_write(struct queue *q, const void *buf, size_t len) {
bool success = false;
size_t left = (q->len - q->head + q->tail - 1) % q->len;
if (len + sizeof(size_t) <= left) {
q_copyin(q, (uint8_t *) &len, sizeof(len), q->head);
q_copyin(q, (uint8_t *) buf, len, (q->head + sizeof(size_t)) % q->len);
q->head = (q->head + sizeof(len) + len) % q->len;
success = true;
}
return success;
}
static inline size_t q_avail(struct queue *q) {
size_t n = 0;
if (q->tail != q->head) q_copyout(q, (uint8_t *) &n, sizeof(n), q->tail);
return n;
}
static size_t q_read(struct queue *q, void *buf) {
size_t n = q_avail(q);
if (n > 0) {
q_copyout(q, (uint8_t *) buf, n, (q->tail + sizeof(n)) % q->len);
q->tail = (q->tail + sizeof(n) + n) % q->len;
}
return n;
}
static struct mg_str mkstr(void *buf, size_t len) {
struct mg_str str = {(char *) buf, len};
return str;
}
static void mkpay(struct pkt *pkt, void *p) {
pkt->pay = mkstr(p, (size_t) (&pkt->raw.ptr[pkt->raw.len] - (char *) p));
pkt->pay =
mg_str_n((char *) p, (size_t) (&pkt->raw.ptr[pkt->raw.len] - (char *) p));
}
static uint32_t csumup(uint32_t sum, const void *buf, size_t len) {
@@ -790,9 +746,17 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) {
if (ifp->ip == 0 && expired_1000ms) tx_dhcp_discover(ifp);
// Read data from the network
size_t len = ifp->driver->rx((void *) ifp->rx.ptr, ifp->rx.len, ifp);
if (len) {
mg_tcpip_rx(ifp, (void *) ifp->rx.ptr, len);
if (ifp->driver->rx != NULL) { // Polling driver. We must call it
size_t len =
ifp->driver->rx(ifp->recv_queue.buf, ifp->recv_queue.size, ifp);
if (len > 0) mg_tcpip_rx(ifp, ifp->recv_queue.buf, len);
} else { // Interrupt-based driver. Fills recv queue itself
char *buf;
size_t len = mg_queue_next(&ifp->recv_queue, &buf);
if (len > 0) {
mg_tcpip_rx(ifp, buf, len);
mg_queue_del(&ifp->recv_queue, len);
}
}
// Process timeouts
@@ -823,20 +787,19 @@ static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) {
// somewhere fast. Note that newlib's malloc is not thread safe, thus use
// our lock-free queue with preallocated buffer to copy data and return asap
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp) {
if (q_write(&ifp->queue, buf, len)) {
char *p;
if (mg_queue_book(&ifp->recv_queue, &p, len) >= len) {
memcpy(p, buf, len);
mg_queue_add(&ifp->recv_queue, len);
ifp->nrecv++;
} else {
ifp->ndrop++;
}
}
size_t mg_tcpip_qread(void *buf, struct mg_tcpip_if *ifp) {
return q_read(&ifp->queue, buf);
}
size_t mg_tcpip_driver_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
return mg_tcpip_qread((void *) ifp->rx.ptr, ifp);
(void) len, (void) buf;
(void) buf, (void) len, (void) ifp;
return 0;
}
void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
@@ -851,10 +814,10 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
if (ifp->driver->init && !ifp->driver->init(ifp)) {
MG_ERROR(("driver init failed"));
} else {
size_t maxpktsize = 1540;
ifp->rx.ptr = (char *) calloc(1, maxpktsize), ifp->rx.len = maxpktsize;
ifp->tx.ptr = (char *) calloc(1, maxpktsize), ifp->tx.len = maxpktsize;
if (ifp->queue.len) ifp->queue.buf = (uint8_t *) calloc(1, ifp->queue.len);
size_t framesize = 1540;
ifp->tx.ptr = (char *) calloc(1, framesize), ifp->tx.len = framesize;
ifp->recv_queue.size = ifp->driver->rx ? framesize : 8192;
ifp->recv_queue.buf = (char *) calloc(1, ifp->recv_queue.size);
ifp->timer_1000ms = mg_millis();
mgr->priv = ifp;
ifp->mgr = mgr;
@@ -868,7 +831,7 @@ void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
}
void mg_tcpip_free(struct mg_tcpip_if *ifp) {
free((char *) ifp->rx.ptr);
free(ifp->recv_queue.buf);
free((char *) ifp->tx.ptr);
}
+4 -13
View File
@@ -2,6 +2,7 @@
#include "arch.h"
#include "net.h"
#include "queue.h"
struct mg_tcpip_if; // MIP network interface
@@ -12,27 +13,17 @@ struct mg_tcpip_driver {
bool (*up)(struct mg_tcpip_if *); // Up/down status
};
// Receive queue - single producer, single consumer queue. Interrupt-based
// drivers copy received frames to the queue in interrupt context.
// mg_tcpip_poll() function runs in event loop context, reads from the queue
struct queue {
uint8_t *buf;
size_t len;
volatile size_t tail, head;
};
// Network interface
struct mg_tcpip_if {
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
uint32_t ip, mask, gw; // IP address, mask, default gateway
struct mg_str rx; // Output (TX) buffer
struct mg_str tx; // Input (RX) buffer
struct mg_str tx; // Output (TX) buffer
bool enable_dhcp_client; // Enable DCHP client
bool enable_dhcp_server; // Enable DCHP server
struct mg_tcpip_driver *driver; // Low level driver
void *driver_data; // Driver-specific data
struct mg_mgr *mgr; // Mongoose event manager
struct queue queue; // Set queue.len for interrupt based drivers
struct mg_queue recv_queue; // Receive queue
// Internal state, user can use it but should not change it
uint8_t gwmac[6]; // Router's MAC
@@ -61,7 +52,7 @@ extern struct mg_tcpip_driver mg_tcpip_driver_stm32;
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
extern struct mg_tcpip_driver mg_tcpip_driver_imxrt1020;
extern struct mg_tcpip_driver mg_tcpip_driver_imxrt;
// Drivers that require SPI, can use this SPI abstraction
struct mg_tcpip_spi {