- 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
#include "../cbd_table.h"
#include "etherlib/prefab/packet_parsers/ipv4_types.h"
#include "../prefab/packet_parsers/ipv4_types.h"
typedef struct {
cbd serverConn; ///< Server connection

View File

@ -9,46 +9,46 @@
#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
BlockingFifo * fifo = (BlockingFifo *) dynmem_alloc(allocSize); // allocate data block at the end
ASSERT_NULL(fifo);
memset(fifo, 0, sizeof(BlockingFifo));
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_CREATE(&fifo->notFull, 1);
fifo->notFull = ETHLIB_OS_SEM_CREATE(1);
return fifo;
}
void bfifo_destroy(BlockingFifo * bfifo) {
void eth_bfifo_destroy(BlockingFifo * bfifo) {
ETHLIB_OS_SEM_DESTROY(&bfifo->nonEmpty);
ETHLIB_OS_SEM_DESTROY(&bfifo->notFull);
bfifo->size = 0;
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;
}
uint32_t bfifo_get_free(const BlockingFifo * bfifo) {
return bfifo->size - bfifo_get_used(bfifo);
uint32_t eth_bfifo_get_free(const BlockingFifo * bfifo) {
return bfifo->size - eth_bfifo_get_used(bfifo);
}
uint32_t bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
if (bfifo_get_free(bfifo) == 0) {
uint32_t eth_bfifo_push_try(BlockingFifo * bfifo, const uint8_t * data, uint32_t size) {
if (eth_bfifo_get_free(bfifo) == 0) {
return 0;
} 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
// 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);
// 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->absWriteIdx += copySize;
freeArea = bfifo_get_free(bfifo);
freeArea = eth_bfifo_get_free(bfifo);
if (freeArea > 0) { // FIFO is not full
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;
}
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
uint32_t usedArea = bfifo_get_used(bfifo);
uint32_t usedArea = eth_bfifo_get_used(bfifo);
uint32_t copySize = MIN(size, usedArea);
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;
}
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);
// if destination is given, then also perform a copy
if (dst != NULL) {
bfifo_peek(bfifo, dst, size);
eth_bfifo_peek(bfifo, dst, size);
}
// 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 newReadIdx = bfifo->readIdx + popSize;
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->absReadIdx += popSize;
usedArea = bfifo_get_used(bfifo);
usedArea = eth_bfifo_get_used(bfifo);
if (usedArea > 0) { // FIFO is NOT empty
ETHLIB_OS_SEM_POST(&bfifo->nonEmpty);
}

View File

@ -26,20 +26,20 @@ typedef struct {
* @param size size of the FIFO in bytes
* @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

View File

@ -11,7 +11,7 @@ static uint8_t sDynMemPool[ETHLIB_MEMORY_POOL_TOTAL_SIZE] __attribute__((ETHLIB_
static ETHLIB_OS_MTX_TYPE dynmem_mtx;
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);
ASSERT_NULL(E.mp);
}

View File

@ -55,10 +55,10 @@ EthInterface *ethintf_new(EthIODef *io) {
ethIntf->txQ = 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_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);
@ -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) {
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) {
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
*event_code = cpd & 0xFFFF;

View File

@ -55,8 +55,8 @@ static inline TcpState *tcps_create() {
TcpState *tcps = dynmem_alloc(sizeof(TcpState));
uint32_t winSize = MAX(ETHLIB_DEF_TCP_WINDOW_SIZE, MAX_TCP_WINDOW_SIZE);
tcps->txWin = tcpw_create(winSize); // create transmit window
ETHLIB_OS_SEM_CREATE(&tcps->txBufNotFull, 1); // create transmit buffer not full semaphore
ETHLIB_OS_SEM_CREATE(&tcps->txInProgress, 1); // create transmission in progress semaphore
tcps->txBufNotFull = ETHLIB_OS_SEM_CREATE(1); // create transmit buffer not full semaphore
tcps->txInProgress = ETHLIB_OS_SEM_CREATE(1); // create transmission in progress semaphore
return tcps;
}
@ -65,7 +65,7 @@ static inline void tcps_release_client_related_objects(TcpState *tcps) {
tcpw_destroy(tcps->txWin);
ETHLIB_OS_SEM_DESTROY(&tcps->txBufNotFull);
ETHLIB_OS_SEM_DESTROY(&tcps->txInProgress);
bfifo_destroy(tcps->rxFifo);
eth_bfifo_destroy(tcps->rxFifo);
}
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->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);
@ -263,10 +263,10 @@ int tcp_receive_segment_cb(const Pckt *pckt, PcktSieveLayerTag tag) {
tcps->connState = TCP_STATE_LAST_ACK;
} else if ((dataSize > 0) && (tcps->rxAckNum == tcpProps->SequenceNumber)) { // incoming data segment with integrity in ack/seq
// 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
tcps->localWindow = bfifo_get_free(tcps->rxFifo);
tcps->localWindow = eth_bfifo_get_free(tcps->rxFifo);
// send acknowledge
tcps->rxAckNum += pushSize;
@ -587,7 +587,7 @@ uint32_t tcp_recv(unsigned char d, uint8_t *data, uint32_t size) {
// acquire TCP state
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) {

View File

@ -372,7 +372,7 @@ void dhcp_stop(DhcpState *s) {
void dhcp_initiate(EthInterface *intf) {
DhcpState *s = (DhcpState *)dynmem_alloc(sizeof(DhcpState));
ETHLIB_OS_MTX_CREATE(&s->procMtx);
s->procMtx = ETHLIB_OS_MTX_CREATE();
s->state = DHCP_STOPPED;
s->buf = dynmem_alloc(DHCP_MIN_PACKET_SIZE);
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));
ASSERT_NULL(tmr);
ETHLIB_OS_MTX_CREATE(&tmr->tabMtx);
tmr->tabMtx = ETHLIB_OS_MTX_CREATE();
tmr->maxSched = maxSched;
tmr->nSched = 0;
tmr->nextAlarm = NULL;