mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-21 11:30:01 +00:00
Use mg_queue in mip
This commit is contained in:
1 parent
4436093816
commit
910f19fe55
11 files changed
+86
-212
No files matched your search
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user