- blocking FIFO name collision fixed, by prepending BlockingFifo function names with "eth_"

- CMake integration added
- OS calls got tailored to CMSIS OS2 interface
This commit is contained in:
Wiesner András 2024-04-13 16:57:21 +02:00
parent 8a5c800fd3
commit 0a6d007c73
9 changed files with 132 additions and 43 deletions

89
CMakeLists.txt Normal file
View File

@ -0,0 +1,89 @@
target_sources(
${CMAKE_PROJECT_NAME}
PUBLIC
apps/http_server.c
apps/http_server.h
prefab/conn_blocks/arp_connblock.c
prefab/conn_blocks/arp_connblock.h
prefab/conn_blocks/custom_ethertype_connblock.c
prefab/conn_blocks/custom_ethertype_connblock.h
prefab/conn_blocks/ethernet_connblock.c
prefab/conn_blocks/ethernet_connblock.h
prefab/conn_blocks/icmp_connblock.c
prefab/conn_blocks/icmp_connblock.h
prefab/conn_blocks/igmp_connblock.c
prefab/conn_blocks/igmp_connblock.h
prefab/conn_blocks/ipv4/ip_assembler.c
prefab/conn_blocks/ipv4/ip_assembler.h
prefab/conn_blocks/ipv4_connblock.c
prefab/conn_blocks/ipv4_connblock.h
prefab/conn_blocks/tcp/tcp_window.c
prefab/conn_blocks/tcp/tcp_window.h
prefab/conn_blocks/tcp_connblock.c
prefab/conn_blocks/tcp_connblock.h
prefab/conn_blocks/udp_connblock.c
prefab/conn_blocks/udp_connblock.h
prefab/packet_parsers/arp_packet.c
prefab/packet_parsers/arp_packet.h
prefab/packet_parsers/dhcp.c
prefab/packet_parsers/dhcp.h
prefab/packet_parsers/ethernet_frame.c
prefab/packet_parsers/ethernet_frame.h
prefab/packet_parsers/icmp_packet.c
prefab/packet_parsers/icmp_packet.h
prefab/packet_parsers/igmp_packet.c
prefab/packet_parsers/igmp_packet.h
prefab/packet_parsers/ipv4_packet.c
prefab/packet_parsers/ipv4_packet.h
prefab/packet_parsers/ipv4_types.h
prefab/packet_parsers/packet_parsers.c
prefab/packet_parsers/packet_parsers.h
prefab/packet_parsers/tcp_segment.c
prefab/packet_parsers/tcp_segment.h
prefab/packet_parsers/tcp_udp_common.c
prefab/packet_parsers/tcp_udp_common.h
prefab/packet_parsers/udp_packet.c
prefab/packet_parsers/udp_packet.h
prefab/prefab.h
arp_cache.c
arp_cache.h
blocking_fifo.c
blocking_fifo.h
cbd_table.c
cbd_table.h
connection_block.c
connection_block.h
dynmem.c
dynmem.h
etherlib.h
eth_interface.c
eth_interface.h
gen_queue.c
gen_queue.h
global_state.c
global_state.h
memory_pool.c
memory_pool.h
msg_queue.c
msg_queue.h
packet.c
packet.h
packet_registry.c
packet_registry.h
packet_sieve.c
packet_sieve.h
pckt_assembler.c
pckt_assembler.h
timer.c
timer.h
timestamping.c
timestamping.h
utils.c
utils.h
)

View File

@ -2,7 +2,7 @@
#define ETHERLIB_TEST_HTTP_SERVER_H #define ETHERLIB_TEST_HTTP_SERVER_H
#include "../cbd_table.h" #include "../cbd_table.h"
#include "etherlib/prefab/packet_parsers/ipv4_types.h" #include "../prefab/packet_parsers/ipv4_types.h"
typedef struct { typedef struct {
cbd serverConn; ///< Server connection cbd serverConn; ///< Server connection

View File

@ -9,46 +9,46 @@
#define MIN(a,b) (((a) < (b)) ? (a) : (b)) #define MIN(a,b) (((a) < (b)) ? (a) : (b))
BlockingFifo *bfifo_new(uint32_t size) { BlockingFifo *eth_bfifo_new(uint32_t size) {
uint32_t allocSize = sizeof(BlockingFifo) + size; // calculate full allocation size uint32_t allocSize = sizeof(BlockingFifo) + size; // calculate full allocation size
BlockingFifo * fifo = (BlockingFifo *) dynmem_alloc(allocSize); // allocate data block at the end BlockingFifo * fifo = (BlockingFifo *) dynmem_alloc(allocSize); // allocate data block at the end
ASSERT_NULL(fifo); ASSERT_NULL(fifo);
memset(fifo, 0, sizeof(BlockingFifo)); memset(fifo, 0, sizeof(BlockingFifo));
fifo->size = size; fifo->size = size;
ETHLIB_OS_SEM_CREATE(&fifo->nonEmpty, 1); fifo->nonEmpty = ETHLIB_OS_SEM_CREATE(1);
ETHLIB_OS_SEM_WAIT(&fifo->nonEmpty); // FIFO is empty ETHLIB_OS_SEM_WAIT(&fifo->nonEmpty); // FIFO is empty
ETHLIB_OS_SEM_CREATE(&fifo->notFull, 1); fifo->notFull = ETHLIB_OS_SEM_CREATE(1);
return fifo; return fifo;
} }
void bfifo_destroy(BlockingFifo * bfifo) { void eth_bfifo_destroy(BlockingFifo * bfifo) {
ETHLIB_OS_SEM_DESTROY(&bfifo->nonEmpty); ETHLIB_OS_SEM_DESTROY(&bfifo->nonEmpty);
ETHLIB_OS_SEM_DESTROY(&bfifo->notFull); ETHLIB_OS_SEM_DESTROY(&bfifo->notFull);
bfifo->size = 0; bfifo->size = 0;
dynmem_free(bfifo); dynmem_free(bfifo);
} }
uint32_t bfifo_get_used(const BlockingFifo *bfifo) { uint32_t eth_bfifo_get_used(const BlockingFifo *bfifo) {
return bfifo->absWriteIdx - bfifo->absReadIdx; return bfifo->absWriteIdx - bfifo->absReadIdx;
} }
uint32_t bfifo_get_free(const BlockingFifo * bfifo) { uint32_t eth_bfifo_get_free(const BlockingFifo * bfifo) {
return bfifo->size - bfifo_get_used(bfifo); return bfifo->size - eth_bfifo_get_used(bfifo);
} }
uint32_t bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) { uint32_t eth_bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
if (bfifo_get_free(bfifo) == 0) { if (eth_bfifo_get_free(bfifo) == 0) {
return 0; return 0;
} else { } else {
return bfifo_push(bfifo, data, size); return eth_bfifo_push(bfifo, data, size);
} }
} }
uint32_t bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) { uint32_t eth_bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
ETHLIB_OS_SEM_WAIT(&bfifo->notFull); // take not full semaphore ETHLIB_OS_SEM_WAIT(&bfifo->notFull); // take not full semaphore
// calculate copy size, limit if required // calculate copy size, limit if required
uint32_t freeArea = bfifo_get_free(bfifo); uint32_t freeArea = eth_bfifo_get_free(bfifo);
uint32_t copySize = MIN(size, freeArea); uint32_t copySize = MIN(size, freeArea);
// determine first block size // determine first block size
@ -68,7 +68,7 @@ uint32_t bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
bfifo->writeIdx = newWriteIdx; // replace... bfifo->writeIdx = newWriteIdx; // replace...
bfifo->absWriteIdx += copySize; bfifo->absWriteIdx += copySize;
freeArea = bfifo_get_free(bfifo); freeArea = eth_bfifo_get_free(bfifo);
if (freeArea > 0) { // FIFO is not full if (freeArea > 0) { // FIFO is not full
ETHLIB_OS_SEM_POST(&bfifo->notFull); ETHLIB_OS_SEM_POST(&bfifo->notFull);
} }
@ -79,9 +79,9 @@ uint32_t bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
return copySize; return copySize;
} }
uint32_t bfifo_peek(BlockingFifo * bfifo, uint8_t * dst, uint32_t size) { uint32_t eth_bfifo_peek(BlockingFifo * bfifo, uint8_t * dst, uint32_t size) {
// determine copy size // determine copy size
uint32_t usedArea = bfifo_get_used(bfifo); uint32_t usedArea = eth_bfifo_get_used(bfifo);
uint32_t copySize = MIN(size, usedArea); uint32_t copySize = MIN(size, usedArea);
uint32_t spaceToBufEnd = bfifo->size - bfifo->readIdx; // space to buffer end uint32_t spaceToBufEnd = bfifo->size - bfifo->readIdx; // space to buffer end
@ -94,16 +94,16 @@ uint32_t bfifo_peek(BlockingFifo * bfifo, uint8_t * dst, uint32_t size) {
return copySize; return copySize;
} }
uint32_t bfifo_pop(BlockingFifo *bfifo, uint8_t *dst, uint32_t size) { uint32_t eth_bfifo_pop(BlockingFifo *bfifo, uint8_t *dst, uint32_t size) {
ETHLIB_OS_SEM_WAIT(&bfifo->nonEmpty); ETHLIB_OS_SEM_WAIT(&bfifo->nonEmpty);
// if destination is given, then also perform a copy // if destination is given, then also perform a copy
if (dst != NULL) { if (dst != NULL) {
bfifo_peek(bfifo, dst, size); eth_bfifo_peek(bfifo, dst, size);
} }
// adjust indices // adjust indices
uint32_t usedArea = bfifo_get_used(bfifo); uint32_t usedArea = eth_bfifo_get_used(bfifo);
uint32_t popSize = MIN(size, usedArea); // advance next written uint32_t popSize = MIN(size, usedArea); // advance next written
uint32_t newReadIdx = bfifo->readIdx + popSize; uint32_t newReadIdx = bfifo->readIdx + popSize;
if (newReadIdx >= bfifo->size) { if (newReadIdx >= bfifo->size) {
@ -112,7 +112,7 @@ uint32_t bfifo_pop(BlockingFifo *bfifo, uint8_t *dst, uint32_t size) {
bfifo->readIdx = newReadIdx; // replace it instead of performing an in-place change bfifo->readIdx = newReadIdx; // replace it instead of performing an in-place change
bfifo->absReadIdx += popSize; bfifo->absReadIdx += popSize;
usedArea = bfifo_get_used(bfifo); usedArea = eth_bfifo_get_used(bfifo);
if (usedArea > 0) { // FIFO is NOT empty if (usedArea > 0) { // FIFO is NOT empty
ETHLIB_OS_SEM_POST(&bfifo->nonEmpty); ETHLIB_OS_SEM_POST(&bfifo->nonEmpty);
} }

View File

@ -26,20 +26,20 @@ typedef struct {
* @param size size of the FIFO in bytes * @param size size of the FIFO in bytes
* @return newly allocated FIFO * @return newly allocated FIFO
*/ */
BlockingFifo * bfifo_new(uint32_t size); BlockingFifo * eth_bfifo_new(uint32_t size);
void bfifo_destroy(BlockingFifo * bfifo); void eth_bfifo_destroy(BlockingFifo * bfifo);
uint32_t bfifo_get_used(const BlockingFifo * bfifo); uint32_t eth_bfifo_get_used(const BlockingFifo * bfifo);
uint32_t bfifo_get_free(const BlockingFifo * bfifo); uint32_t eth_bfifo_get_free(const BlockingFifo * bfifo);
uint32_t bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t size); uint32_t eth_bfifo_push(BlockingFifo * bfifo, const uint8_t * data, uint32_t size);
uint32_t bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t size); uint32_t eth_bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t size);
uint32_t bfifo_peek(BlockingFifo * bfifo, uint8_t * dst, uint32_t size); uint32_t eth_bfifo_peek(BlockingFifo * bfifo, uint8_t * dst, uint32_t size);
uint32_t bfifo_pop(BlockingFifo *bfifo, uint8_t *dst, uint32_t size); uint32_t eth_bfifo_pop(BlockingFifo *bfifo, uint8_t *dst, uint32_t size);
#endif //ETHERLIB_TEST_BLOCKING_FIFO_H #endif //ETHERLIB_TEST_BLOCKING_FIFO_H

View File

@ -11,7 +11,7 @@ static uint8_t sDynMemPool[ETHLIB_MEMORY_POOL_TOTAL_SIZE] __attribute__((ETHLIB_
static ETHLIB_OS_MTX_TYPE dynmem_mtx; static ETHLIB_OS_MTX_TYPE dynmem_mtx;
void dynmem_init() { void dynmem_init() {
ETHLIB_OS_MTX_CREATE(&dynmem_mtx); dynmem_mtx = ETHLIB_OS_MTX_CREATE();
E.mp = mp_init(sDynMemPool, ETHLIB_MEMORY_POOL_TOTAL_SIZE); E.mp = mp_init(sDynMemPool, ETHLIB_MEMORY_POOL_TOTAL_SIZE);
ASSERT_NULL(E.mp); ASSERT_NULL(E.mp);
} }

View File

@ -55,10 +55,10 @@ EthInterface *ethintf_new(EthIODef *io) {
ethIntf->txQ = mq_create(ETHLIB_DEF_MQ_SIZE); ethIntf->txQ = mq_create(ETHLIB_DEF_MQ_SIZE);
ethIntf->rxQ = mq_create(ETHLIB_DEF_MQ_SIZE); ethIntf->rxQ = mq_create(ETHLIB_DEF_MQ_SIZE);
ETHLIB_OS_QUEUE_CREATE(ethIntf->eventQ, ETHLIB_DEF_MQ_SIZE, uint32_t); ethIntf->eventQ = ETHLIB_OS_QUEUE_CREATE(ETHLIB_DEF_MQ_SIZE, uint32_t);
// ETHLIB_OS_SEM_CREATE(&ethIntf->eventSem, ETHLIB_DEF_MQ_SIZE); // ETHLIB_OS_SEM_CREATE(&ethIntf->eventSem, ETHLIB_DEF_MQ_SIZE);
ETHLIB_OS_THREAD_DEFINE(task_ethintf, osPriorityHigh, 512, ethIntf);
ETHLIB_OS_THREAD_CREATE(task_ethintf, ethIntf); ETHLIB_OS_THREAD_CREATE(task_ethintf, "eth", ethIntf, osPriorityHigh, 512);
ethIntf->ipra = ipra_new(ethIntf); ethIntf->ipra = ipra_new(ethIntf);
@ -131,12 +131,12 @@ void ethinf_transmit(EthInterface *intf, const RawPckt *rawPckt) {
void ethinf_push_notification(EthInterface *intf, uint16_t event_code, uint16_t event_data) { void ethinf_push_notification(EthInterface *intf, uint16_t event_code, uint16_t event_data) {
uint32_t cpd = (event_data << 16) | event_code; // create event compound uint32_t cpd = (event_data << 16) | event_code; // create event compound
ETHLIB_OS_QUEUE_PUSH(intf->eventQ, cpd); ETHLIB_OS_QUEUE_PUSH(intf->eventQ, &cpd);
} }
void ethinf_pull_notification(EthInterface *intf, uint16_t *event_code, uint16_t *event_data) { void ethinf_pull_notification(EthInterface *intf, uint16_t *event_code, uint16_t *event_data) {
uint32_t cpd; uint32_t cpd;
cpd = ETHLIB_OS_QUEUE_POP(intf->eventQ); // wait for event semaphore ETHLIB_OS_QUEUE_POP(intf->eventQ, &cpd); // wait for event semaphore
// retrieve event code and data // retrieve event code and data
*event_code = cpd & 0xFFFF; *event_code = cpd & 0xFFFF;

View File

@ -55,8 +55,8 @@ static inline TcpState *tcps_create() {
TcpState *tcps = dynmem_alloc(sizeof(TcpState)); TcpState *tcps = dynmem_alloc(sizeof(TcpState));
uint32_t winSize = MAX(ETHLIB_DEF_TCP_WINDOW_SIZE, MAX_TCP_WINDOW_SIZE); uint32_t winSize = MAX(ETHLIB_DEF_TCP_WINDOW_SIZE, MAX_TCP_WINDOW_SIZE);
tcps->txWin = tcpw_create(winSize); // create transmit window tcps->txWin = tcpw_create(winSize); // create transmit window
ETHLIB_OS_SEM_CREATE(&tcps->txBufNotFull, 1); // create transmit buffer not full semaphore tcps->txBufNotFull = ETHLIB_OS_SEM_CREATE(1); // create transmit buffer not full semaphore
ETHLIB_OS_SEM_CREATE(&tcps->txInProgress, 1); // create transmission in progress semaphore tcps->txInProgress = ETHLIB_OS_SEM_CREATE(1); // create transmission in progress semaphore
return tcps; return tcps;
} }
@ -65,7 +65,7 @@ static inline void tcps_release_client_related_objects(TcpState *tcps) {
tcpw_destroy(tcps->txWin); tcpw_destroy(tcps->txWin);
ETHLIB_OS_SEM_DESTROY(&tcps->txBufNotFull); ETHLIB_OS_SEM_DESTROY(&tcps->txBufNotFull);
ETHLIB_OS_SEM_DESTROY(&tcps->txInProgress); ETHLIB_OS_SEM_DESTROY(&tcps->txInProgress);
bfifo_destroy(tcps->rxFifo); eth_bfifo_destroy(tcps->rxFifo);
} }
static inline void tcps_remove_and_cleanup(TcpState *tcps) { static inline void tcps_remove_and_cleanup(TcpState *tcps) {
@ -108,7 +108,7 @@ void tcps_init(TcpState *tcps, uint16_t localPort) {
tcps->acceptCb = NULL; tcps->acceptCb = NULL;
tcps->isServer = false; tcps->isServer = false;
tcps->rxFifo = bfifo_new(ETHLIB_DEF_FIFO_SIZE); tcps->rxFifo = eth_bfifo_new(ETHLIB_DEF_FIFO_SIZE);
} }
void tcp_init_connection(ConnBlock *connBlock); void tcp_init_connection(ConnBlock *connBlock);
@ -263,10 +263,10 @@ int tcp_receive_segment_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
tcps->connState = TCP_STATE_LAST_ACK; tcps->connState = TCP_STATE_LAST_ACK;
} else if ((dataSize > 0) && (tcps->rxAckNum == tcpProps->SequenceNumber)) { // incoming data segment with integrity in ack/seq } else if ((dataSize > 0) && (tcps->rxAckNum == tcpProps->SequenceNumber)) { // incoming data segment with integrity in ack/seq
// try to store packet content into the FIFO // try to store packet content into the FIFO
uint32_t pushSize = bfifo_push_try(tcps->rxFifo, pckt->payload, pckt->payloadSize); uint32_t pushSize = eth_bfifo_push_try(tcps->rxFifo, pckt->payload, pckt->payloadSize);
// adjust receive window size // adjust receive window size
tcps->localWindow = bfifo_get_free(tcps->rxFifo); tcps->localWindow = eth_bfifo_get_free(tcps->rxFifo);
// send acknowledge // send acknowledge
tcps->rxAckNum += pushSize; tcps->rxAckNum += pushSize;
@ -587,7 +587,7 @@ uint32_t tcp_recv(unsigned char d, uint8_t *data, uint32_t size) {
// acquire TCP state // acquire TCP state
TcpState *tcps = TCP_FETCH_STATE_FROM_CONNBLOCK(&connBlock); TcpState *tcps = TCP_FETCH_STATE_FROM_CONNBLOCK(&connBlock);
return bfifo_pop(tcps->rxFifo, data, size); return eth_bfifo_pop(tcps->rxFifo, data, size);
} }
void tcp_print_report(const ConnBlock *connBlock) { void tcp_print_report(const ConnBlock *connBlock) {

View File

@ -372,7 +372,7 @@ void dhcp_stop(DhcpState *s) {
void dhcp_initiate(EthInterface *intf) { void dhcp_initiate(EthInterface *intf) {
DhcpState *s = (DhcpState *)dynmem_alloc(sizeof(DhcpState)); DhcpState *s = (DhcpState *)dynmem_alloc(sizeof(DhcpState));
ETHLIB_OS_MTX_CREATE(&s->procMtx); s->procMtx = ETHLIB_OS_MTX_CREATE();
s->state = DHCP_STOPPED; s->state = DHCP_STOPPED;
s->buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE); s->buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE);
s->desc = udp_new_connblock(intf, IPv4_ANY_ADDR, DHCP_CLIENT_PORT, dhcp_resp_cb); s->desc = udp_new_connblock(intf, IPv4_ANY_ADDR, DHCP_CLIENT_PORT, dhcp_resp_cb);

View File

@ -26,7 +26,7 @@ Timer *timer_new(uint32_t maxSched) {
Timer *tmr = (Timer *)dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment)); Timer *tmr = (Timer *)dynmem_alloc(sizeof(Timer) + maxSched * sizeof(AlarmAssignment));
ASSERT_NULL(tmr); ASSERT_NULL(tmr);
ETHLIB_OS_MTX_CREATE(&tmr->tabMtx); tmr->tabMtx = ETHLIB_OS_MTX_CREATE();
tmr->maxSched = maxSched; tmr->maxSched = maxSched;
tmr->nSched = 0; tmr->nSched = 0;
tmr->nextAlarm = NULL; tmr->nextAlarm = NULL;