bugfixes & use new lwip mempool for FreeRTOS lwip
This commit is contained in:
parent
d34effb278
commit
ff569dd02c
@ -66,9 +66,11 @@ void ObjectFactory::produceGenericObjects() {
|
|||||||
pus::PUS_SERVICE_17);
|
pus::PUS_SERVICE_17);
|
||||||
new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS,
|
new Service20ParameterManagement(objects::PUS_SERVICE_20_PARAMETERS,
|
||||||
apid::APID, pus::PUS_SERVICE_20);
|
apid::APID, pus::PUS_SERVICE_20);
|
||||||
|
#if OBSW_ADD_CORE_COMPONENTS == 1
|
||||||
new Service11TelecommandScheduling<cfg::OBSW_MAX_SCHEDULED_TCS>(
|
new Service11TelecommandScheduling<cfg::OBSW_MAX_SCHEDULED_TCS>(
|
||||||
objects::PUS_SERVICE_11_TC_SCHEDULER, apid::APID, pus::PUS_SERVICE_11,
|
objects::PUS_SERVICE_11_TC_SCHEDULER, apid::APID, pus::PUS_SERVICE_11,
|
||||||
ccsdsDistrib);
|
ccsdsDistrib);
|
||||||
|
#endif
|
||||||
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, apid::APID,
|
new CService200ModeCommanding(objects::PUS_SERVICE_200_MODE_MGMT, apid::APID,
|
||||||
pus::PUS_SERVICE_200);
|
pus::PUS_SERVICE_200);
|
||||||
#endif /* OBSW_ADD_PUS_STACK == 1 */
|
#endif /* OBSW_ADD_PUS_STACK == 1 */
|
||||||
|
@ -11,6 +11,14 @@ STM32TestTask::STM32TestTask(object_id_t objectId, bool enablePrintout,
|
|||||||
BSP_LED_Init(LED3);
|
BSP_LED_Init(LED3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ReturnValue_t STM32TestTask::initialize() {
|
||||||
|
if (testSpi) {
|
||||||
|
spiComIF = new SpiComIF(objects::SPI_COM_IF);
|
||||||
|
spiTest = new SpiTest(*spiComIF);
|
||||||
|
}
|
||||||
|
return TestTask::initialize();
|
||||||
|
}
|
||||||
|
|
||||||
ReturnValue_t STM32TestTask::performPeriodicAction() {
|
ReturnValue_t STM32TestTask::performPeriodicAction() {
|
||||||
if (blinkyLed) {
|
if (blinkyLed) {
|
||||||
#if OBSW_ETHERNET_USE_LEDS == 0
|
#if OBSW_ETHERNET_USE_LEDS == 0
|
||||||
@ -24,11 +32,3 @@ ReturnValue_t STM32TestTask::performPeriodicAction() {
|
|||||||
}
|
}
|
||||||
return TestTask::performPeriodicAction();
|
return TestTask::performPeriodicAction();
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t STM32TestTask::initialize() {
|
|
||||||
if (testSpi) {
|
|
||||||
spiComIF = new SpiComIF(objects::SPI_COM_IF);
|
|
||||||
spiTest = new SpiTest(*spiComIF);
|
|
||||||
}
|
|
||||||
return TestTask::initialize();
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,7 @@ private:
|
|||||||
SpiTest *spiTest = nullptr;
|
SpiTest *spiTest = nullptr;
|
||||||
|
|
||||||
bool blinkyLed = false;
|
bool blinkyLed = false;
|
||||||
bool testSpi = true;
|
bool testSpi = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* BSP_STM32_BOARDTEST_STM32TESTTASK_H_ */
|
#endif /* BSP_STM32_BOARDTEST_STM32TESTTASK_H_ */
|
||||||
|
@ -17,7 +17,7 @@ TmTcLwIpUdpBridge::TmTcLwIpUdpBridge(object_id_t objectId,
|
|||||||
TmTcLwIpUdpBridge::lastAdd.addr = IPADDR_TYPE_ANY;
|
TmTcLwIpUdpBridge::lastAdd.addr = IPADDR_TYPE_ANY;
|
||||||
}
|
}
|
||||||
|
|
||||||
TmTcLwIpUdpBridge::~TmTcLwIpUdpBridge() {}
|
TmTcLwIpUdpBridge::~TmTcLwIpUdpBridge() = default;
|
||||||
|
|
||||||
ReturnValue_t TmTcLwIpUdpBridge::initialize() {
|
ReturnValue_t TmTcLwIpUdpBridge::initialize() {
|
||||||
TmTcBridge::initialize();
|
TmTcBridge::initialize();
|
||||||
@ -29,11 +29,12 @@ ReturnValue_t TmTcLwIpUdpBridge::initialize() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReturnValue_t TmTcLwIpUdpBridge::udp_server_init(void) {
|
ReturnValue_t TmTcLwIpUdpBridge::udp_server_init() {
|
||||||
err_t err;
|
err_t err;
|
||||||
/* Create a new UDP control block */
|
/* Create a new UDP control block */
|
||||||
TmTcLwIpUdpBridge::upcb = udp_new();
|
TmTcLwIpUdpBridge::upcb = udp_new();
|
||||||
if (TmTcLwIpUdpBridge::upcb) {
|
if (TmTcLwIpUdpBridge::upcb) {
|
||||||
|
sif::printInfo("Opening UDP server on port %d\n", UDP_SERVER_PORT);
|
||||||
/* Bind the upcb to the UDP_PORT port */
|
/* Bind the upcb to the UDP_PORT port */
|
||||||
/* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
|
/* Using IP_ADDR_ANY allow the upcb to be used by any local interface */
|
||||||
err = udp_bind(TmTcLwIpUdpBridge::upcb, IP_ADDR_ANY, UDP_SERVER_PORT);
|
err = udp_bind(TmTcLwIpUdpBridge::upcb, IP_ADDR_ANY, UDP_SERVER_PORT);
|
||||||
@ -120,7 +121,6 @@ void TmTcLwIpUdpBridge::udp_server_receive_callback(void *arg,
|
|||||||
struct pbuf *p,
|
struct pbuf *p,
|
||||||
const ip_addr_t *addr,
|
const ip_addr_t *addr,
|
||||||
u16_t port) {
|
u16_t port) {
|
||||||
struct pbuf *p_tx = nullptr;
|
|
||||||
auto udpBridge = reinterpret_cast<TmTcLwIpUdpBridge *>(arg);
|
auto udpBridge = reinterpret_cast<TmTcLwIpUdpBridge *>(arg);
|
||||||
if (udpBridge == nullptr) {
|
if (udpBridge == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
@ -133,9 +133,9 @@ void TmTcLwIpUdpBridge::udp_server_receive_callback(void *arg,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
/* allocate pbuf from RAM*/
|
/* allocate pbuf from RAM*/
|
||||||
p_tx = pbuf_alloc(PBUF_TRANSPORT, p->len, PBUF_RAM);
|
struct pbuf *p_tx = pbuf_alloc(PBUF_TRANSPORT, p->len, PBUF_RAM);
|
||||||
|
|
||||||
if (p_tx != NULL) {
|
if (p_tx != nullptr) {
|
||||||
if (udpBridge != nullptr) {
|
if (udpBridge != nullptr) {
|
||||||
MutexGuard lg(udpBridge->bridgeLock);
|
MutexGuard lg(udpBridge->bridgeLock);
|
||||||
udpBridge->upcb = upcb_;
|
udpBridge->upcb = upcb_;
|
||||||
|
@ -17,9 +17,9 @@ class TmTcLwIpUdpBridge : public TmTcBridge {
|
|||||||
public:
|
public:
|
||||||
TmTcLwIpUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor,
|
TmTcLwIpUdpBridge(object_id_t objectId, object_id_t ccsdsPacketDistributor,
|
||||||
object_id_t tmStoreId, object_id_t tcStoreId);
|
object_id_t tmStoreId, object_id_t tcStoreId);
|
||||||
virtual ~TmTcLwIpUdpBridge();
|
~TmTcLwIpUdpBridge() override;
|
||||||
|
|
||||||
virtual ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
ReturnValue_t udp_server_init();
|
ReturnValue_t udp_server_init();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,14 +27,14 @@ public:
|
|||||||
* @param operationCode
|
* @param operationCode
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||||
|
|
||||||
/** TM Send implementation uses udp_send function from lwIP stack
|
/** TM Send implementation uses udp_send function from lwIP stack
|
||||||
* @param data
|
* @param data
|
||||||
* @param dataLen
|
* @param dataLen
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t sendTm(const uint8_t *data, size_t dataLen) override;
|
ReturnValue_t sendTm(const uint8_t *data, size_t dataLen) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief This function is called when an UDP datagram has been
|
* @brief This function is called when an UDP datagram has been
|
||||||
@ -54,11 +54,11 @@ public:
|
|||||||
* Caller must ensure thread-safety by using the bridge lock.
|
* Caller must ensure thread-safety by using the bridge lock.
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
bool comLinkUp() const;
|
[[nodiscard]] bool comLinkUp() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct udp_pcb *upcb = nullptr;
|
struct udp_pcb *upcb = nullptr;
|
||||||
ip_addr_t lastAdd;
|
ip_addr_t lastAdd{};
|
||||||
u16_t lastPort = 0;
|
u16_t lastPort = 0;
|
||||||
bool physicalConnection = false;
|
bool physicalConnection = false;
|
||||||
MutexIF *bridgeLock = nullptr;
|
MutexIF *bridgeLock = nullptr;
|
||||||
|
@ -18,7 +18,7 @@ UdpTcLwIpPollingTask::UdpTcLwIpPollingTask(object_id_t objectId,
|
|||||||
: SystemObject(objectId), periodicHandleCounter(0), bridgeId(bridgeId),
|
: SystemObject(objectId), periodicHandleCounter(0), bridgeId(bridgeId),
|
||||||
gnetif(gnetif) {}
|
gnetif(gnetif) {}
|
||||||
|
|
||||||
UdpTcLwIpPollingTask::~UdpTcLwIpPollingTask() {}
|
UdpTcLwIpPollingTask::~UdpTcLwIpPollingTask() = default;
|
||||||
|
|
||||||
ReturnValue_t UdpTcLwIpPollingTask::initialize() {
|
ReturnValue_t UdpTcLwIpPollingTask::initialize() {
|
||||||
udpBridge = ObjectManager::instance()->get<TmTcLwIpUdpBridge>(bridgeId);
|
udpBridge = ObjectManager::instance()->get<TmTcLwIpUdpBridge>(bridgeId);
|
||||||
|
@ -18,16 +18,16 @@ class UdpTcLwIpPollingTask : public SystemObject,
|
|||||||
public:
|
public:
|
||||||
UdpTcLwIpPollingTask(object_id_t objectId, object_id_t bridgeId,
|
UdpTcLwIpPollingTask(object_id_t objectId, object_id_t bridgeId,
|
||||||
struct netif *gnetif);
|
struct netif *gnetif);
|
||||||
virtual ~UdpTcLwIpPollingTask();
|
~UdpTcLwIpPollingTask() override;
|
||||||
|
|
||||||
virtual ReturnValue_t initialize() override;
|
ReturnValue_t initialize() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executed periodically.
|
* Executed periodically.
|
||||||
* @param operationCode
|
* @param operationCode
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
virtual ReturnValue_t performOperation(uint8_t operationCode = 0) override;
|
ReturnValue_t performOperation(uint8_t operationCode) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uint8_t PERIODIC_HANDLE_TRIGGER = 5;
|
static const uint8_t PERIODIC_HANDLE_TRIGGER = 5;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
#include "app_dhcp.h"
|
#include "app_dhcp.h"
|
||||||
|
|
||||||
#include "OBSWConfig.h"
|
#include "OBSWConfig.h"
|
||||||
#include "app_ethernet.h"
|
|
||||||
#include "ethernetif.h"
|
|
||||||
#include "lwip/dhcp.h"
|
#include "lwip/dhcp.h"
|
||||||
#include "networking.h"
|
#include "networking.h"
|
||||||
#include "stm32h7xx_nucleo.h"
|
#include "stm32h7xx_nucleo.h"
|
||||||
@ -24,7 +22,7 @@ void handle_dhcp_down(struct netif *netif);
|
|||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void DHCP_Process(struct netif *netif) {
|
void DHCP_Process(struct netif *netif) {
|
||||||
struct dhcp *dhcp = NULL;
|
struct dhcp *dhcp = nullptr;
|
||||||
switch (DHCP_state) {
|
switch (DHCP_state) {
|
||||||
case DHCP_START: {
|
case DHCP_START: {
|
||||||
handle_dhcp_start(netif);
|
handle_dhcp_start(netif);
|
||||||
@ -119,8 +117,8 @@ void handle_dhcp_wait(struct netif *netif, struct dhcp **dhcp) {
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
*dhcp = (struct dhcp *)netif_get_client_data(
|
*dhcp = static_cast<struct dhcp *>(netif_get_client_data(
|
||||||
netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP);
|
netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP));
|
||||||
|
|
||||||
/* DHCP timeout */
|
/* DHCP timeout */
|
||||||
if ((*dhcp)->tries > MAX_DHCP_TRIES) {
|
if ((*dhcp)->tries > MAX_DHCP_TRIES) {
|
||||||
@ -130,6 +128,7 @@ void handle_dhcp_wait(struct netif *netif, struct dhcp **dhcp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void handle_dhcp_down(struct netif *netif) {
|
void handle_dhcp_down(struct netif *netif) {
|
||||||
|
static_cast<void>(netif);
|
||||||
DHCP_state = DHCP_OFF;
|
DHCP_state = DHCP_OFF;
|
||||||
#if OBSW_ETHERNET_TMTC_COMMANDING == 1
|
#if OBSW_ETHERNET_TMTC_COMMANDING == 1
|
||||||
printf("DHCP_Process: The network cable is not connected.\n\r");
|
printf("DHCP_Process: The network cable is not connected.\n\r");
|
||||||
|
@ -44,16 +44,16 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
/* Includes ------------------------------------------------------------------*/
|
||||||
|
#include "stm32h7xx_hal.h"
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/timeouts.h"
|
||||||
|
#include "lwip/netif.h"
|
||||||
|
#include "netif/etharp.h"
|
||||||
#include "ethernetif.h"
|
#include "ethernetif.h"
|
||||||
|
#include "lan8742.h"
|
||||||
#include <lan8742.h>
|
|
||||||
#include <lwip/netif.h>
|
|
||||||
#include <lwip/opt.h>
|
|
||||||
#include <lwip/timeouts.h>
|
|
||||||
#include <netif/etharp.h>
|
|
||||||
#include <stm32h7xx_hal.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "fsfw/FSFW.h"
|
#include "fsfw/FSFW.h"
|
||||||
|
|
||||||
#ifdef FSFW_OSAL_RTEMS
|
#ifdef FSFW_OSAL_RTEMS
|
||||||
@ -66,6 +66,12 @@
|
|||||||
#define IFNAME0 's'
|
#define IFNAME0 's'
|
||||||
#define IFNAME1 't'
|
#define IFNAME1 't'
|
||||||
|
|
||||||
|
#define ETH_DMA_TRANSMIT_TIMEOUT (20U)
|
||||||
|
|
||||||
|
#define ETH_RX_BUFFER_SIZE 1536U
|
||||||
|
#define ETH_RX_BUFFER_CNT 12U
|
||||||
|
#define ETH_TX_BUFFER_MAX ((ETH_TX_DESC_CNT) * 2U)
|
||||||
|
|
||||||
#define DMA_DESCRIPTOR_ALIGNMENT 0x20
|
#define DMA_DESCRIPTOR_ALIGNMENT 0x20
|
||||||
|
|
||||||
/* Private macro -------------------------------------------------------------*/
|
/* Private macro -------------------------------------------------------------*/
|
||||||
@ -87,27 +93,30 @@ stack they will return back to DMA after been processed by the stack.
|
|||||||
2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must
|
2.b. Rx Buffers must have the same size: ETH_RX_BUFFER_SIZE, this value must
|
||||||
passed to ETH DMA in the init field (EthHandle.Init.RxBuffLen)
|
passed to ETH DMA in the init field (EthHandle.Init.RxBuffLen)
|
||||||
*/
|
*/
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
RX_ALLOC_OK = 0x00,
|
||||||
|
RX_ALLOC_ERROR = 0x01
|
||||||
|
} RxAllocStatusTypeDef;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
struct pbuf_custom pbuf_custom;
|
||||||
|
uint8_t buff[(ETH_RX_BUFFER_SIZE + 31) & ~31] __ALIGNED(32);
|
||||||
|
} RxBuff_t;
|
||||||
|
|
||||||
#if defined(__ICCARM__) /*!< IAR Compiler */
|
#if defined(__ICCARM__) /*!< IAR Compiler */
|
||||||
|
|
||||||
#pragma location = 0x30040000
|
#pragma location=0x30000000
|
||||||
ETH_DMADescTypeDef
|
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
|
||||||
DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
|
#pragma location=0x30000200
|
||||||
#pragma location = 0x30040060
|
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
|
||||||
ETH_DMADescTypeDef
|
|
||||||
DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
|
|
||||||
#pragma location = 0x30040200
|
|
||||||
uint8_t Rx_Buff[ETH_RX_DESC_CNT]
|
|
||||||
[ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffers */
|
|
||||||
|
|
||||||
#elif defined(__CC_ARM) /* MDK ARM Compiler */
|
#elif defined(__CC_ARM) /* MDK ARM Compiler */
|
||||||
|
|
||||||
__attribute__((section(".RxDecripSection"))) ETH_DMADescTypeDef
|
__attribute__((section(".RxDecripSection"))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
|
||||||
DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */
|
__attribute__((section(".TxDecripSection"))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
|
||||||
__attribute__((section(".TxDecripSection"))) ETH_DMADescTypeDef
|
|
||||||
DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */
|
|
||||||
__attribute__((section(".RxArraySection"))) uint8_t
|
|
||||||
Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]; /* Ethernet Receive Buffer */
|
|
||||||
|
|
||||||
#elif defined(__GNUC__) /* GNU Compiler */
|
#elif defined(__GNUC__) /* GNU Compiler */
|
||||||
|
|
||||||
@ -124,44 +133,57 @@ ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((
|
|||||||
* placing it */
|
* placing it */
|
||||||
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE];
|
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE];
|
||||||
#elif defined FSFW_OSAL_FREERTOS
|
#elif defined FSFW_OSAL_FREERTOS
|
||||||
/* Placement and alignment specified in linker script here */
|
|
||||||
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((
|
ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT] __attribute__((section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
|
||||||
section(".RxDecripSection"))); /* Ethernet Rx DMA Descriptors */
|
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
|
||||||
ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT] __attribute__((
|
|
||||||
section(".TxDecripSection"))); /* Ethernet Tx DMA Descriptors */
|
#endif /* FSFW_OSAL_RTEMS */
|
||||||
uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE]
|
|
||||||
__attribute__((section(".RxArraySection"))); /* Ethernet Receive Buffers */
|
|
||||||
#endif /* FSFW_FREERTOS */
|
|
||||||
|
|
||||||
#endif /* defined ( __GNUC__ ) */
|
#endif /* defined ( __GNUC__ ) */
|
||||||
|
|
||||||
|
/* Memory Pool Declaration */
|
||||||
|
LWIP_MEMPOOL_DECLARE(RX_POOL, ETH_RX_BUFFER_CNT, sizeof(RxBuff_t), "Zero-copy RX PBUF pool");
|
||||||
|
|
||||||
|
#if defined ( __ICCARM__ ) /*!< IAR Compiler */
|
||||||
|
#pragma location = 0x30000400
|
||||||
|
extern u8_t memp_memory_RX_POOL_base[];
|
||||||
|
|
||||||
|
#elif defined ( __CC_ARM ) /* MDK ARM Compiler */
|
||||||
|
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
|
||||||
|
|
||||||
|
#elif defined ( __GNUC__ ) /* GNU Compiler */
|
||||||
|
__attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Global boolean to track ethernet connection */
|
/* Global boolean to track ethernet connection */
|
||||||
bool ethernet_cable_connected;
|
bool ethernet_cable_connected;
|
||||||
|
|
||||||
struct pbuf_custom rx_pbuf[ETH_RX_DESC_CNT];
|
/* Variable Definitions */
|
||||||
uint32_t current_pbuf_idx = 0;
|
static uint8_t RxAllocStatus;
|
||||||
|
|
||||||
|
/* Global Ethernet handle*/
|
||||||
ETH_HandleTypeDef EthHandle;
|
ETH_HandleTypeDef EthHandle;
|
||||||
ETH_TxPacketConfig TxConfig;
|
ETH_TxPacketConfig TxConfig;
|
||||||
|
|
||||||
lan8742_Object_t LAN8742;
|
|
||||||
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
u32_t sys_now(void);
|
u32_t sys_now(void);
|
||||||
void pbuf_free_custom(struct pbuf *p);
|
extern void Error_Handler(void);
|
||||||
|
|
||||||
int32_t ETH_PHY_IO_Init(void);
|
int32_t ETH_PHY_IO_Init(void);
|
||||||
int32_t ETH_PHY_IO_DeInit(void);
|
int32_t ETH_PHY_IO_DeInit (void);
|
||||||
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr,
|
int32_t ETH_PHY_IO_ReadReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t *pRegVal);
|
||||||
uint32_t *pRegVal);
|
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr, uint32_t RegVal);
|
||||||
int32_t ETH_PHY_IO_WriteReg(uint32_t DevAddr, uint32_t RegAddr,
|
|
||||||
uint32_t RegVal);
|
|
||||||
int32_t ETH_PHY_IO_GetTick(void);
|
int32_t ETH_PHY_IO_GetTick(void);
|
||||||
|
|
||||||
lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init, ETH_PHY_IO_DeInit,
|
lan8742_Object_t LAN8742;
|
||||||
ETH_PHY_IO_WriteReg, ETH_PHY_IO_ReadReg,
|
lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init,
|
||||||
|
ETH_PHY_IO_DeInit,
|
||||||
|
ETH_PHY_IO_WriteReg,
|
||||||
|
ETH_PHY_IO_ReadReg,
|
||||||
ETH_PHY_IO_GetTick};
|
ETH_PHY_IO_GetTick};
|
||||||
|
|
||||||
/* Private functions ---------------------------------------------------------*/
|
/* Private functions ---------------------------------------------------------*/
|
||||||
|
void pbuf_free_custom(struct pbuf *p);
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
LL Driver Interface ( LwIP stack --> ETH)
|
LL Driver Interface ( LwIP stack --> ETH)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@ -173,9 +195,7 @@ lan8742_IOCtx_t LAN8742_IOCtx = {ETH_PHY_IO_Init, ETH_PHY_IO_DeInit,
|
|||||||
* for this ethernetif
|
* for this ethernetif
|
||||||
*/
|
*/
|
||||||
static void low_level_init(struct netif *netif) {
|
static void low_level_init(struct netif *netif) {
|
||||||
uint32_t idx = 0;
|
uint8_t macaddress[6]= {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2, ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
|
||||||
uint8_t macaddress[6] = {ETH_MAC_ADDR0, ETH_MAC_ADDR1, ETH_MAC_ADDR2,
|
|
||||||
ETH_MAC_ADDR3, ETH_MAC_ADDR4, ETH_MAC_ADDR5};
|
|
||||||
|
|
||||||
EthHandle.Instance = ETH;
|
EthHandle.Instance = ETH;
|
||||||
EthHandle.Init.MACAddr = macaddress;
|
EthHandle.Init.MACAddr = macaddress;
|
||||||
@ -188,15 +208,15 @@ static void low_level_init(struct netif *netif) {
|
|||||||
HAL_ETH_Init(&EthHandle);
|
HAL_ETH_Init(&EthHandle);
|
||||||
|
|
||||||
/* set MAC hardware address length */
|
/* set MAC hardware address length */
|
||||||
netif->hwaddr_len = ETHARP_HWADDR_LEN;
|
netif->hwaddr_len = ETH_HWADDR_LEN;
|
||||||
|
|
||||||
/* set MAC hardware address */
|
/* set MAC hardware address */
|
||||||
netif->hwaddr[0] = 0x02;
|
netif->hwaddr[0] = ETH_MAC_ADDR0;
|
||||||
netif->hwaddr[1] = 0x00;
|
netif->hwaddr[1] = ETH_MAC_ADDR1;
|
||||||
netif->hwaddr[2] = 0x00;
|
netif->hwaddr[2] = ETH_MAC_ADDR2;
|
||||||
netif->hwaddr[3] = 0x00;
|
netif->hwaddr[3] = ETH_MAC_ADDR3;
|
||||||
netif->hwaddr[4] = 0x00;
|
netif->hwaddr[4] = ETH_MAC_ADDR4;
|
||||||
netif->hwaddr[5] = 0x00;
|
netif->hwaddr[5] = ETH_MAC_ADDR5;
|
||||||
|
|
||||||
/* maximum transfer unit */
|
/* maximum transfer unit */
|
||||||
netif->mtu = ETH_MAX_PAYLOAD;
|
netif->mtu = ETH_MAX_PAYLOAD;
|
||||||
@ -205,17 +225,12 @@ static void low_level_init(struct netif *netif) {
|
|||||||
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
|
||||||
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP;
|
||||||
|
|
||||||
for (idx = 0; idx < ETH_RX_DESC_CNT; idx++) {
|
/* Initialize the RX POOL */
|
||||||
HAL_ETH_DescAssignMemory(&EthHandle, idx, Rx_Buff[idx], NULL);
|
LWIP_MEMPOOL_INIT(RX_POOL);
|
||||||
|
|
||||||
/* Set Custom pbuf free function */
|
|
||||||
rx_pbuf[idx].custom_free_function = pbuf_free_custom;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set Tx packet config common parameters */
|
/* Set Tx packet config common parameters */
|
||||||
memset(&TxConfig, 0, sizeof(ETH_TxPacketConfig));
|
memset(&TxConfig, 0 , sizeof(ETH_TxPacketConfig));
|
||||||
TxConfig.Attributes =
|
TxConfig.Attributes = ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
|
||||||
ETH_TX_PACKETS_FEATURES_CSUM | ETH_TX_PACKETS_FEATURES_CRCPAD;
|
|
||||||
TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
|
TxConfig.ChecksumCtrl = ETH_CHECKSUM_IPHDR_PAYLOAD_INSERT_PHDR_CALC;
|
||||||
TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
|
TxConfig.CRCPadCtrl = ETH_CRC_PAD_INSERT;
|
||||||
|
|
||||||
@ -245,40 +260,43 @@ static void low_level_init(struct netif *netif) {
|
|||||||
* dropped because of memory failure (except for the TCP timers).
|
* dropped because of memory failure (except for the TCP timers).
|
||||||
*/
|
*/
|
||||||
static err_t low_level_output(struct netif *netif, struct pbuf *p) {
|
static err_t low_level_output(struct netif *netif, struct pbuf *p) {
|
||||||
uint32_t i = 0, framelen = 0;
|
uint32_t i = 0U;
|
||||||
struct pbuf *q;
|
struct pbuf *q = NULL;
|
||||||
err_t errval = ERR_OK;
|
err_t errval = ERR_OK;
|
||||||
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT];
|
ETH_BufferTypeDef Txbuffer[ETH_TX_DESC_CNT] = {0};
|
||||||
|
|
||||||
for (q = p; q != NULL; q = q->next) {
|
memset(Txbuffer, 0 , ETH_TX_DESC_CNT*sizeof(ETH_BufferTypeDef));
|
||||||
if (i >= ETH_TX_DESC_CNT)
|
|
||||||
|
for(q = p; q != NULL; q = q->next)
|
||||||
|
{
|
||||||
|
if(i >= ETH_TX_DESC_CNT)
|
||||||
return ERR_IF;
|
return ERR_IF;
|
||||||
|
|
||||||
Txbuffer[i].buffer = q->payload;
|
Txbuffer[i].buffer = q->payload;
|
||||||
Txbuffer[i].len = q->len;
|
Txbuffer[i].len = q->len;
|
||||||
framelen += q->len;
|
|
||||||
|
|
||||||
if (i > 0) {
|
if(i>0)
|
||||||
Txbuffer[i - 1].next = &Txbuffer[i];
|
{
|
||||||
|
Txbuffer[i-1].next = &Txbuffer[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->next == NULL) {
|
if(q->next == NULL)
|
||||||
|
{
|
||||||
Txbuffer[i].next = NULL;
|
Txbuffer[i].next = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
TxConfig.Length = framelen;
|
TxConfig.Length = p->tot_len;
|
||||||
TxConfig.TxBuffer = Txbuffer;
|
TxConfig.TxBuffer = Txbuffer;
|
||||||
|
TxConfig.pData = p;
|
||||||
|
|
||||||
HAL_StatusTypeDef ret = HAL_ETH_Transmit(&EthHandle, &TxConfig, 20);
|
HAL_StatusTypeDef ret = HAL_ETH_Transmit(&EthHandle, &TxConfig, ETH_DMA_TRANSMIT_TIMEOUT);
|
||||||
|
|
||||||
if (ret != HAL_OK) {
|
if (ret != HAL_OK) {
|
||||||
printf("low_level_output: Could not transmit ethernet packet, code %d!\n\r",
|
printf("low_level_output: Could not transmit ethernet packet, code %d!\n\r",
|
||||||
ret);
|
ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return errval;
|
return errval;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,30 +310,13 @@ static err_t low_level_output(struct netif *netif, struct pbuf *p) {
|
|||||||
*/
|
*/
|
||||||
static struct pbuf *low_level_input(struct netif *netif) {
|
static struct pbuf *low_level_input(struct netif *netif) {
|
||||||
struct pbuf *p = NULL;
|
struct pbuf *p = NULL;
|
||||||
ETH_BufferTypeDef RxBuff;
|
|
||||||
uint32_t framelength = 0;
|
|
||||||
|
|
||||||
if (HAL_ETH_IsRxDataAvailable(&EthHandle)) {
|
if(RxAllocStatus == RX_ALLOC_OK)
|
||||||
HAL_ETH_GetRxDataBuffer(&EthHandle, &RxBuff);
|
{
|
||||||
HAL_ETH_GetRxDataLength(&EthHandle, &framelength);
|
HAL_ETH_ReadData(&EthHandle, (void **)&p);
|
||||||
|
|
||||||
/* Invalidate data cache for ETH Rx Buffers */
|
|
||||||
SCB_InvalidateDCache_by_Addr((uint32_t *)Rx_Buff,
|
|
||||||
(ETH_RX_DESC_CNT * ETH_RX_BUFFER_SIZE));
|
|
||||||
|
|
||||||
p = pbuf_alloced_custom(PBUF_RAW, framelength, PBUF_POOL,
|
|
||||||
&rx_pbuf[current_pbuf_idx], RxBuff.buffer,
|
|
||||||
ETH_RX_BUFFER_SIZE);
|
|
||||||
if (current_pbuf_idx < (ETH_RX_DESC_CNT - 1)) {
|
|
||||||
current_pbuf_idx++;
|
|
||||||
} else {
|
|
||||||
current_pbuf_idx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return p;
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -328,26 +329,21 @@ static struct pbuf *low_level_input(struct netif *netif) {
|
|||||||
* @param netif the lwip network interface structure for this ethernetif
|
* @param netif the lwip network interface structure for this ethernetif
|
||||||
*/
|
*/
|
||||||
void ethernetif_input(struct netif *netif) {
|
void ethernetif_input(struct netif *netif) {
|
||||||
err_t err;
|
struct pbuf *p = NULL;
|
||||||
struct pbuf *p;
|
|
||||||
|
|
||||||
/* move received packet into a new pbuf */
|
do
|
||||||
p = low_level_input(netif);
|
{
|
||||||
|
p = low_level_input( netif );
|
||||||
|
if (p != NULL)
|
||||||
|
{
|
||||||
|
if (netif->input( p, netif) != ERR_OK )
|
||||||
|
{
|
||||||
|
pbuf_free(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* no packet could be read, silently ignore this */
|
} while(p!=NULL);
|
||||||
if (p == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* entry point to the LwIP stack */
|
|
||||||
err = netif->input(p, netif);
|
|
||||||
|
|
||||||
if (err != ERR_OK) {
|
|
||||||
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
|
|
||||||
pbuf_free(p);
|
|
||||||
p = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HAL_ETH_BuildRxDescriptors(&EthHandle);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -372,6 +368,7 @@ err_t ethernetif_init(struct netif *netif) {
|
|||||||
|
|
||||||
netif->name[0] = IFNAME0;
|
netif->name[0] = IFNAME0;
|
||||||
netif->name[1] = IFNAME1;
|
netif->name[1] = IFNAME1;
|
||||||
|
|
||||||
/* We directly use etharp_output() here to save a function call.
|
/* We directly use etharp_output() here to save a function call.
|
||||||
* You can instead declare your own function an call etharp_output()
|
* You can instead declare your own function an call etharp_output()
|
||||||
* from it if you have to do some checks before sending (e.g. if link
|
* from it if you have to do some checks before sending (e.g. if link
|
||||||
@ -391,12 +388,13 @@ err_t ethernetif_init(struct netif *netif) {
|
|||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void pbuf_free_custom(struct pbuf *p) {
|
void pbuf_free_custom(struct pbuf *p) {
|
||||||
if (p != NULL) {
|
struct pbuf_custom* custom_pbuf = (struct pbuf_custom*)p;
|
||||||
p->flags = 0;
|
LWIP_MEMPOOL_FREE(RX_POOL, custom_pbuf);
|
||||||
p->next = NULL;
|
/* If the Rx Buffer Pool was exhausted, signal the ethernetif_input task to
|
||||||
p->len = p->tot_len = 0;
|
* call HAL_ETH_GetRxDataBuffer to rebuild the Rx descriptors. */
|
||||||
p->ref = 0;
|
if (RxAllocStatus == RX_ALLOC_ERROR)
|
||||||
p->payload = NULL;
|
{
|
||||||
|
RxAllocStatus = RX_ALLOC_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -545,19 +543,22 @@ int32_t ETH_PHY_IO_GetTick(void) { return HAL_GetTick(); }
|
|||||||
* @retval None
|
* @retval None
|
||||||
*/
|
*/
|
||||||
void ethernet_link_check_state(struct netif *netif) {
|
void ethernet_link_check_state(struct netif *netif) {
|
||||||
ETH_MACConfigTypeDef MACConf;
|
ETH_MACConfigTypeDef MACConf = {0};
|
||||||
uint32_t PHYLinkState;
|
int32_t PHYLinkState = 0U;
|
||||||
uint32_t linkchanged = 0, speed = 0, duplex = 0;
|
uint32_t linkchanged = 0U, speed = 0U, duplex = 0U;
|
||||||
|
|
||||||
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
|
PHYLinkState = LAN8742_GetLinkState(&LAN8742);
|
||||||
|
|
||||||
if (netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN)) {
|
if(netif_is_link_up(netif) && (PHYLinkState <= LAN8742_STATUS_LINK_DOWN))
|
||||||
HAL_ETH_Stop(&EthHandle);
|
{
|
||||||
|
HAL_ETH_Stop_IT(&EthHandle);
|
||||||
netif_set_down(netif);
|
netif_set_down(netif);
|
||||||
netif_set_link_down(netif);
|
netif_set_link_down(netif);
|
||||||
} else if (!netif_is_link_up(netif) &&
|
}
|
||||||
(PHYLinkState > LAN8742_STATUS_LINK_DOWN)) {
|
else if(!netif_is_link_up(netif) && (PHYLinkState > LAN8742_STATUS_LINK_DOWN))
|
||||||
switch (PHYLinkState) {
|
{
|
||||||
|
switch (PHYLinkState)
|
||||||
|
{
|
||||||
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
|
case LAN8742_STATUS_100MBITS_FULLDUPLEX:
|
||||||
duplex = ETH_FULLDUPLEX_MODE;
|
duplex = ETH_FULLDUPLEX_MODE;
|
||||||
speed = ETH_SPEED_100M;
|
speed = ETH_SPEED_100M;
|
||||||
@ -582,13 +583,14 @@ void ethernet_link_check_state(struct netif *netif) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linkchanged) {
|
if(linkchanged)
|
||||||
|
{
|
||||||
/* Get MAC Config MAC */
|
/* Get MAC Config MAC */
|
||||||
HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
|
HAL_ETH_GetMACConfig(&EthHandle, &MACConf);
|
||||||
MACConf.DuplexMode = duplex;
|
MACConf.DuplexMode = duplex;
|
||||||
MACConf.Speed = speed;
|
MACConf.Speed = speed;
|
||||||
HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
|
HAL_ETH_SetMACConfig(&EthHandle, &MACConf);
|
||||||
HAL_ETH_Start(&EthHandle);
|
HAL_ETH_Start_IT(&EthHandle);
|
||||||
netif_set_up(netif);
|
netif_set_up(netif);
|
||||||
netif_set_link_up(netif);
|
netif_set_link_up(netif);
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
#ifndef __ETHERNETIF_H__
|
#ifndef __ETHERNETIF_H__
|
||||||
#define __ETHERNETIF_H__
|
#define __ETHERNETIF_H__
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stm32h7xx_hal.h>
|
#include <stm32h7xx_hal.h>
|
||||||
|
|
||||||
#include "lwip/err.h"
|
#include "lwip/err.h"
|
||||||
@ -56,8 +55,6 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ETH_RX_BUFFER_SIZE (1536UL)
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
/* Exported types ------------------------------------------------------------*/
|
||||||
|
|
||||||
ETH_HandleTypeDef *getEthernetHandle();
|
ETH_HandleTypeDef *getEthernetHandle();
|
||||||
@ -67,7 +64,6 @@ void ethernet_link_check_state(struct netif *netif);
|
|||||||
|
|
||||||
extern ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT];
|
extern ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT];
|
||||||
extern ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT];
|
extern ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT];
|
||||||
extern uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_RX_BUFFER_SIZE];
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user