diff --git a/.github/workflows/Continuous-Integration.yml b/.github/workflows/Continuous-Integration.yml index 982a286..b324ceb 100644 --- a/.github/workflows/Continuous-Integration.yml +++ b/.github/workflows/Continuous-Integration.yml @@ -2,7 +2,7 @@ name: STM32Ethernet Continuous Integration on: push: branches: - - master + - main paths-ignore: - '*' - '**.md' @@ -19,11 +19,11 @@ jobs: steps: # First of all, clone the repo using the checkout action. - name: Checkout - uses: actions/checkout@master + uses: actions/checkout@main - name: Astyle check id: Astyle - uses: stm32duino/actions/astyle-check@master + uses: stm32duino/actions/astyle-check@main # Use the output from the `Astyle` step - name: Astyle Errors @@ -35,7 +35,7 @@ jobs: runs-on: ubuntu-latest name: Spell check steps: - - uses: actions/checkout@master + - uses: actions/checkout@main - uses: arduino/actions/libraries/spell-check@master # with: # ignore-words-list: "./extras/codespell-ignore-words-list.txt" @@ -45,18 +45,18 @@ jobs: steps: # First of all, clone the repo using the checkout action. - name: Checkout - uses: actions/checkout@master + uses: actions/checkout@main - name: Compilation id: Compile - uses: stm32duino/actions/compile-examples@master + uses: stm32duino/actions/compile-examples@main with: board-pattern: "DISCO_F746NG|NUCLEO_F429ZI|NUCLEO_F767ZI" - libraries: "STM32duino LwIP" + libraries: "STM32duino LwIP, STM32duino FreeRTOS" # Use the output from the `Compile` step - name: Compilation Errors if: failure() run: | cat ${{ steps.Compile.outputs.compile-result }} - exit 1 \ No newline at end of file + exit 1 diff --git a/examples/WebClientFreeRTOS/WebClientFreeRTOS.ino b/examples/WebClientFreeRTOS/WebClientFreeRTOS.ino new file mode 100644 index 0000000..842f244 --- /dev/null +++ b/examples/WebClientFreeRTOS/WebClientFreeRTOS.ino @@ -0,0 +1,104 @@ +/* + Port of WebClient on FreeRTOS + + This sketch connects to a website (http://www.google.com) + + Circuit: + * STM32 board with Ethernet support + + created 18 Dec 2009 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe, based on work by Adrian McEwen + modified 23 Jun 2017 + by Wi6Labs + modified 1 Jun 2018 + by sstaub + */ + +#include +#include +#include + +// if you don't want to use DNS (and reduce your sketch size) +// use the numeric IP instead of the name for the server: +//IPAddress server(74,125,232,128); // numeric IP for Google (no DNS) +char server[] = "www.google.com"; // name address for Google (using DNS) + +// Set the static IP address to use if the DHCP fails to assign +IPAddress ip(192, 168, 0, 177); + +// Initialize the Ethernet client library +// with the IP address and port of the server +// that you want to connect to (port 80 is default for HTTP): +EthernetClient client; + + +// task code +void taskETH(void* arg) { + UNUSED(arg); + // start the Ethernet connection: + if (Ethernet.begin() == 0) { + Serial.println("Failed to configure Ethernet using DHCP"); + // try to configure using IP address instead of DHCP: + Ethernet.begin(ip); + } + // give the Ethernet shield a second to initialize: + delay(1000); + Serial.println("connecting..."); + + // if you get a connection, report back via serial: + if (client.connect(server, 80)) { + Serial.println("connected"); + // Make a HTTP request: + client.println("GET /search?q=arduino HTTP/1.1"); + client.println("Host: www.google.com"); + client.println("Connection: close"); + client.println(); + } else { + // if you didn't get a connection to the server: + Serial.println("connection failed"); + } + + while(1){ + // if there are incoming bytes available + // from the server, read them and print them: + if (client.available()) { + char c = client.read(); + Serial.print(c); + } + + // if the server's disconnected, stop the client: + if (!client.connected()) { + Serial.println(); + Serial.println("disconnecting."); + client.stop(); + + // do nothing forevermore: + while (true); + } + } +} + + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + portBASE_TYPE s = xTaskCreate(taskETH, NULL, 200, NULL, 1, NULL); + if (s != pdPASS) { + printf("Ethernet task creation failed\n"); + while (1); + } + + vTaskStartScheduler(); + Serial.println("Scheduler failed"); + while (1); +} + +void loop() { + // Not used. +} diff --git a/examples/WebServerFreeRTOS/WebServerFreeRTOS.ino b/examples/WebServerFreeRTOS/WebServerFreeRTOS.ino new file mode 100644 index 0000000..f69b68b --- /dev/null +++ b/examples/WebServerFreeRTOS/WebServerFreeRTOS.ino @@ -0,0 +1,139 @@ +/* + Port of WebServer on FreeRTOS + + A simple web server that shows the value of the analog input pins. + 2 task are created: + Ethernet: to manage the server + Analog to read input values + + Circuit: + STM32 board with Ethernet support + Analog inputs attached to pins A0 through A5 (optional) + + created 18 Dec 2009 + by David A. Mellis + modified 9 Apr 2012 + by Tom Igoe + modified 02 Sept 2015 + by Arturo Guadalupi + modified 23 Jun 2017 + by Wi6Labs + modified 1 Jun 2018 + by sstaub +*/ + +#include +#include +#include + +// Enter an IP address for your controller below. +// The IP address will be dependent on your local network: +IPAddress ip(192, 168, 0, 177); + +// Initialize the Ethernet server library +// with the IP address and port you want to use +// (port 80 is default for HTTP): +EthernetServer server(80); + +#define ANALOG_CHANEL_NUMBER 6 +int sensorReading[ANALOG_CHANEL_NUMBER]; + +void taskAnalog(void* arg) { + UNUSED(arg); + while (1) { + for (int analogChannel = 0; analogChannel < ANALOG_CHANEL_NUMBER; analogChannel++) { + sensorReading[analogChannel] = analogRead(analogChannel); + } + vTaskDelay(1000); // read Analog every seconds + } +} + +// task code +void taskETH(void* arg) { + UNUSED(arg); + // start the Ethernet connection and the server: + Ethernet.begin(ip); + server.begin(); + Serial.print("server is at "); + Serial.println(Ethernet.localIP()); + + while (1) { + // listen for incoming clients + EthernetClient client = server.available(); + if (client) { + Serial.println("new client"); + // an http request ends with a blank line + bool currentLineIsBlank = true; + while (client.connected()) { + if (client.available()) { + char c = client.read(); + Serial.write(c); + // if you've gotten to the end of the line (received a newline + // character) and the line is blank, the http request has ended, + // so you can send a reply + if (c == '\n' && currentLineIsBlank) { + // send a standard http response header + client.println("HTTP/1.1 200 OK"); + client.println("Content-Type: text/html"); + client.println("Connection: close"); // the connection will be closed after completion of the response + client.println("Refresh: 5"); // refresh the page automatically every 5 sec + client.println(); + client.println(""); + client.println(""); + // output the value of each analog input pin + for (int analogChannel = 0; analogChannel < ANALOG_CHANEL_NUMBER; analogChannel++) { + client.print("analog input "); + client.print(analogChannel); + client.print(" is "); + client.print(sensorReading[analogChannel]); + client.println("
"); + } + client.println(""); + break; + } + if (c == '\n') { + // you're starting a new line + currentLineIsBlank = true; + } else if (c != '\r') { + // you've gotten a character on the current line + currentLineIsBlank = false; + } + } + } + // give the web browser time to receive the data + delay(1); + // close the connection: + client.stop(); + Serial.println("client disconnected"); + } + } +} + +void setup() { + // Open serial communications and wait for port to open: + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + + portBASE_TYPE s = xTaskCreate(taskETH, NULL, 200, NULL, 1, NULL); + if (s != pdPASS) { + printf("Ethernet task creation failed\n"); + while (1); + } + + s = xTaskCreate(taskAnalog, NULL, 200, NULL, 2, NULL); + if (s != pdPASS) { + printf("Analog task creation failed\n"); + while (1); + } + + vTaskStartScheduler(); + Serial.println("Scheduler failed"); + while (1); +} + + +void loop() { + // Not used. +} \ No newline at end of file diff --git a/library.json b/library.json index d6b7529..f4f202c 100755 --- a/library.json +++ b/library.json @@ -7,7 +7,7 @@ "type": "git", "url": "https://github.com/stm32duino/STM32Ethernet" }, - "version": "1.2.0", + "version": "1.3.0", "frameworks": "arduino", "platforms": "ststm32", "build": { diff --git a/library.properties b/library.properties index da4cf0a..3a4aaee 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=STM32duino STM32Ethernet -version=1.2.0 +version=1.3.0 author=Various maintainer=STMicroelectronics sentence=Enables network connection (local and Internet) using the STM32 Board. diff --git a/src/EthernetClient.cpp b/src/EthernetClient.cpp index 5db2e47..4fd0a7f 100644 --- a/src/EthernetClient.cpp +++ b/src/EthernetClient.cpp @@ -65,6 +65,7 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) _tcp_client->data.available = 0; _tcp_client->state = TCP_NONE; + uint32_t startTime = millis(); ip_addr_t ipaddr; tcp_arg(_tcp_client->pcb, _tcp_client); if (ERR_OK != tcp_connect(_tcp_client->pcb, u8_to_ip_addr(rawIPAddress(ip), &ipaddr), port, &tcp_connected_callback)) { @@ -72,10 +73,10 @@ int EthernetClient::connect(IPAddress ip, uint16_t port) return 0; } - uint32_t startTime = millis(); + startTime = millis(); while (_tcp_client->state == TCP_NONE) { stm32_eth_scheduler(); - if ((_tcp_client->state == TCP_CLOSING) || ((millis() - startTime) >= 10000)) { + if ((_tcp_client->state == TCP_CLOSING) || ((millis() - startTime) >= _timeout)) { stop(); return 0; } diff --git a/src/EthernetClient.h b/src/EthernetClient.h index 251b580..c937a05 100644 --- a/src/EthernetClient.h +++ b/src/EthernetClient.h @@ -52,6 +52,10 @@ class EthernetClient : public Client { { return (_tcp_client->pcb->remote_port); }; + void setTimeout(uint16_t timeout) + { + _timeout = timeout; + } friend class EthernetServer; @@ -59,6 +63,7 @@ class EthernetClient : public Client { private: struct tcp_struct *_tcp_client; + uint16_t _timeout = 10000; }; #endif diff --git a/src/EthernetServer.cpp b/src/EthernetServer.cpp index e006b83..386ae9d 100644 --- a/src/EthernetServer.cpp +++ b/src/EthernetServer.cpp @@ -9,7 +9,9 @@ extern "C" { EthernetServer::EthernetServer(uint16_t port) { _port = port; - _tcp_client[MAX_CLIENT] = {}; + for (int i = 0; i < MAX_CLIENT; i++) { + _tcp_client[i] = {}; + } _tcp_server = {}; } @@ -38,6 +40,12 @@ void EthernetServer::begin() tcp_accept(_tcp_server.pcb, tcp_accept_callback); } +void EthernetServer::begin(uint16_t port) +{ + _port = port; + begin(); +} + void EthernetServer::accept() { /* Free client if disconnected */ diff --git a/src/EthernetServer.h b/src/EthernetServer.h index 60fac5b..3a218d4 100644 --- a/src/EthernetServer.h +++ b/src/EthernetServer.h @@ -17,6 +17,7 @@ class EthernetServer : EthernetServer(uint16_t port = 80); EthernetClient available(); virtual void begin(); + virtual void begin(uint16_t port); virtual size_t write(uint8_t); virtual size_t write(const uint8_t *buf, size_t size); using Print::write; diff --git a/src/STM32Ethernet.cpp b/src/STM32Ethernet.cpp index 77313a6..a0753de 100644 --- a/src/STM32Ethernet.cpp +++ b/src/STM32Ethernet.cpp @@ -33,11 +33,8 @@ void EthernetClass::begin(IPAddress local_ip, IPAddress subnet) void EthernetClass::begin(IPAddress local_ip, IPAddress subnet, IPAddress gateway) { - // Assume the DNS server will be the machine on the same network as the local IP - // but with last octet being '1' - IPAddress dns_server = local_ip; - dns_server[3] = 1; - begin(local_ip, subnet, gateway, dns_server); + // Assume the DNS server will be the same machine than gateway + begin(local_ip, subnet, gateway, gateway); } void EthernetClass::begin(IPAddress local_ip, IPAddress subnet, IPAddress gateway, IPAddress dns_server) diff --git a/src/lwipopts.h b/src/lwipopts.h index 09bcbde..0cf3278 100644 --- a/src/lwipopts.h +++ b/src/lwipopts.h @@ -9,12 +9,12 @@ /* LwIP specific configuration options. */ #if __has_include("STM32lwipopts.h") -#include "STM32lwipopts.h" + #include "STM32lwipopts.h" #else -#if __has_include("lwipopts_extra.h") -#include "lwipopts_extra.h" -#endif -#include "lwipopts_default.h" + #if __has_include("lwipopts_extra.h") + #include "lwipopts_extra.h" + #endif + #include "lwipopts_default.h" #endif #endif /* _ARDUINO_LWIPOPTS_H */ diff --git a/src/lwipopts_default.h b/src/lwipopts_default.h index f13b274..d7fae2d 100644 --- a/src/lwipopts_default.h +++ b/src/lwipopts_default.h @@ -151,35 +151,35 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums #ifdef CHECKSUM_BY_HARDWARE -/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ -#define CHECKSUM_GEN_IP 0 -/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/ -#define CHECKSUM_GEN_UDP 0 -/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/ -#define CHECKSUM_GEN_TCP 0 -/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/ -#define CHECKSUM_CHECK_IP 0 -/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/ -#define CHECKSUM_CHECK_UDP 0 -/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/ -#define CHECKSUM_CHECK_TCP 0 -/* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/ -#define CHECKSUM_GEN_ICMP 0 + /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ + #define CHECKSUM_GEN_IP 0 + /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/ + #define CHECKSUM_GEN_UDP 0 + /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/ + #define CHECKSUM_GEN_TCP 0 + /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/ + #define CHECKSUM_CHECK_IP 0 + /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/ + #define CHECKSUM_CHECK_UDP 0 + /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/ + #define CHECKSUM_CHECK_TCP 0 + /* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/ + #define CHECKSUM_GEN_ICMP 0 #else -/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/ -#define CHECKSUM_GEN_IP 1 -/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/ -#define CHECKSUM_GEN_UDP 1 -/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/ -#define CHECKSUM_GEN_TCP 1 -/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/ -#define CHECKSUM_CHECK_IP 1 -/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/ -#define CHECKSUM_CHECK_UDP 1 -/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/ -#define CHECKSUM_CHECK_TCP 1 -/* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/ -#define CHECKSUM_GEN_ICMP 1 + /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/ + #define CHECKSUM_GEN_IP 1 + /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/ + #define CHECKSUM_GEN_UDP 1 + /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/ + #define CHECKSUM_GEN_TCP 1 + /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/ + #define CHECKSUM_CHECK_IP 1 + /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/ + #define CHECKSUM_CHECK_UDP 1 + /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/ + #define CHECKSUM_CHECK_TCP 1 + /* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/ + #define CHECKSUM_GEN_ICMP 1 #endif diff --git a/src/utility/ethernetif.cpp b/src/utility/ethernetif.cpp index 31aa806..d254ece 100644 --- a/src/utility/ethernetif.cpp +++ b/src/utility/ethernetif.cpp @@ -54,7 +54,7 @@ #include "lwip/igmp.h" #include "stm32_eth.h" #if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01050000) -#include "variant.h" + #include "variant.h" #endif #ifdef __cplusplus diff --git a/src/utility/stm32_eth.cpp b/src/utility/stm32_eth.cpp index 28ad2ba..937a297 100644 --- a/src/utility/stm32_eth.cpp +++ b/src/utility/stm32_eth.cpp @@ -63,8 +63,8 @@ * They could be used for this library when available */ #ifndef DEFAULT_ETHERNET_TIMER -#define DEFAULT_ETHERNET_TIMER TIM14 -#warning "Default timer used to call ethernet scheduler at regular interval: TIM14" + #define DEFAULT_ETHERNET_TIMER TIM14 + #warning "Default timer used to call ethernet scheduler at regular interval: TIM14" #endif /* Ethernet configuration: user parameters */ @@ -93,8 +93,10 @@ static uint8_t DHCP_Started_by_user = 0; static uint32_t gEhtLinkTickStart = 0; #if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01060100) -/* Handler for stimer */ -static stimer_t TimHandle; + /* Handler for stimer */ + static stimer_t TimHandle; +#else + HardwareTimer *EthTim = NULL; #endif /*************************** Function prototype *******************************/ @@ -103,6 +105,9 @@ static err_t tcp_recv_callback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, static err_t tcp_sent_callback(void *arg, struct tcp_pcb *tpcb, u16_t len); static void tcp_err_callback(void *arg, err_t err); static void TIM_scheduler_Config(void); +#if defined(STM32_CORE_VERSION) && (STM32_CORE_VERSION > 0x01060100) + void _stm32_eth_scheduler(void); +#endif /** * @brief Configurates the network interface @@ -111,6 +116,7 @@ static void TIM_scheduler_Config(void); */ static void Netif_Config(void) { + netif_remove(&gnetif); /* Add the network interface */ netif_add(&gnetif, &(gconfig.ipaddr), &(gconfig.netmask), &(gconfig.gw), NULL, ðernetif_init, ðernet_input); @@ -137,17 +143,17 @@ static void Netif_Config(void) * @retval None */ #if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01060100) -static void scheduler_callback(stimer_t *htim) + static void scheduler_callback(stimer_t *htim) #elif (STM32_CORE_VERSION <= 0x01080000) -static void scheduler_callback(HardwareTimer *htim) + static void scheduler_callback(HardwareTimer *htim) #else -static void scheduler_callback(void) + static void scheduler_callback(void) #endif { #if (STM32_CORE_VERSION <= 0x01080000) UNUSED(htim); #endif - stm32_eth_scheduler(); + _stm32_eth_scheduler(); } #if !defined(STM32_CORE_VERSION) || (STM32_CORE_VERSION <= 0x01060100) @@ -175,7 +181,7 @@ static void TIM_scheduler_Config(void) static void TIM_scheduler_Config(void) { /* Configure HardwareTimer */ - HardwareTimer *EthTim = new HardwareTimer(DEFAULT_ETHERNET_TIMER); + EthTim = new HardwareTimer(DEFAULT_ETHERNET_TIMER); EthTim->setMode(1, TIMER_OUTPUT_COMPARE); /* Timer set to 1ms */ @@ -192,47 +198,48 @@ void stm32_eth_init(const uint8_t *mac, const uint8_t *ip, const uint8_t *gw, co if (!initDone) { /* Initialize the LwIP stack */ lwip_init(); + } - if (mac != NULL) { - ethernetif_set_mac_addr(mac); - } // else default value is used: MAC_ADDR0 ... MAC_ADDR5 + if (mac != NULL) { + ethernetif_set_mac_addr(mac); + } // else default value is used: MAC_ADDR0 ... MAC_ADDR5 - if (ip != NULL) { - IP_ADDR4(&(gconfig.ipaddr), ip[0], ip[1], ip[2], ip[3]); - } else { + if (ip != NULL) { + IP_ADDR4(&(gconfig.ipaddr), ip[0], ip[1], ip[2], ip[3]); + } else { #if LWIP_DHCP - ip_addr_set_zero_ip4(&(gconfig.ipaddr)); + ip_addr_set_zero_ip4(&(gconfig.ipaddr)); #else - IP_ADDR4(&(gconfig.ipaddr), IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); + IP_ADDR4(&(gconfig.ipaddr), IP_ADDR0, IP_ADDR1, IP_ADDR2, IP_ADDR3); #endif /* LWIP_DHCP */ - } + } - if (gw != NULL) { - IP_ADDR4(&(gconfig.gw), gw[0], gw[1], gw[2], gw[3]); - } else { + if (gw != NULL) { + IP_ADDR4(&(gconfig.gw), gw[0], gw[1], gw[2], gw[3]); + } else { #if LWIP_DHCP - ip_addr_set_zero_ip4(&(gconfig.gw)); + ip_addr_set_zero_ip4(&(gconfig.gw)); #else - IP_ADDR4(&(gconfig.gw), GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); + IP_ADDR4(&(gconfig.gw), GW_ADDR0, GW_ADDR1, GW_ADDR2, GW_ADDR3); #endif /* LWIP_DHCP */ - } + } - if (netmask != NULL) { - IP_ADDR4(&(gconfig.netmask), netmask[0], netmask[1], netmask[2], netmask[3]); - } else { + if (netmask != NULL) { + IP_ADDR4(&(gconfig.netmask), netmask[0], netmask[1], netmask[2], netmask[3]); + } else { #if LWIP_DHCP - ip_addr_set_zero_ip4(&(gconfig.netmask)); + ip_addr_set_zero_ip4(&(gconfig.netmask)); #else - IP_ADDR4(&(gconfig.netmask), NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); + IP_ADDR4(&(gconfig.netmask), NETMASK_ADDR0, NETMASK_ADDR1, NETMASK_ADDR2, NETMASK_ADDR3); #endif /* LWIP_DHCP */ - } + } - /* Configure the Network interface */ - Netif_Config(); + /* Configure the Network interface */ + Netif_Config(); + if (!initDone) { // stm32_eth_scheduler() will be called every 1ms. TIM_scheduler_Config(); - initDone = 1; } @@ -263,12 +270,33 @@ uint8_t stm32_eth_link_up(void) return netif_is_link_up(&gnetif); } +#if defined(STM32_CORE_VERSION) && (STM32_CORE_VERSION > 0x01060100) +/** + * @brief This function generates Timer Update event to force call to _stm32_eth_scheduler(). + * @param None + * @retval None + */ +void stm32_eth_scheduler(void) +{ + if (EthTim != NULL) { + EthTim->refresh(); + } +} + +/** + * @brief This function is called solely by Timer callback to avoid race condition. + * @param None + * @retval None + */ +void _stm32_eth_scheduler(void) +#else /** - * @brief This function must be called in main loop in standalone mode. + * @brief This function is called solely by Timer callback to avoid race condition. * @param None * @retval None */ void stm32_eth_scheduler(void) +#endif { /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */ diff --git a/src/utility/stm32_eth.h b/src/utility/stm32_eth.h index 4866be6..d4c3ff2 100644 --- a/src/utility/stm32_eth.h +++ b/src/utility/stm32_eth.h @@ -112,7 +112,7 @@ struct tcp_struct { #define MAX_CLIENT 32 #ifdef ETH_INPUT_USE_IT -extern struct netif gnetif; + extern struct netif gnetif; #endif @@ -125,22 +125,22 @@ void stm32_eth_scheduler(void); void User_notification(struct netif *netif); #if LWIP_DHCP -void stm32_DHCP_Process(struct netif *netif); -void stm32_DHCP_Periodic_Handle(struct netif *netif); -void stm32_DHCP_manual_config(void); -uint8_t stm32_get_DHCP_lease_state(void); -void stm32_set_DHCP_state(uint8_t state); -uint8_t stm32_get_DHCP_state(void); -uint8_t stm32_dhcp_started(void); + void stm32_DHCP_Process(struct netif *netif); + void stm32_DHCP_Periodic_Handle(struct netif *netif); + void stm32_DHCP_manual_config(void); + uint8_t stm32_get_DHCP_lease_state(void); + void stm32_set_DHCP_state(uint8_t state); + uint8_t stm32_get_DHCP_state(void); + uint8_t stm32_dhcp_started(void); #else -#error "LWIP_DHCP must be enabled in lwipopts.h" + #error "LWIP_DHCP must be enabled in lwipopts.h" #endif #if LWIP_DNS -void stm32_dns_init(const uint8_t *dnsaddr); -int8_t stm32_dns_gethostbyname(const char *hostname, uint32_t *ipaddr); + void stm32_dns_init(const uint8_t *dnsaddr); + int8_t stm32_dns_gethostbyname(const char *hostname, uint32_t *ipaddr); #else -#error "LWIP_DNS must be enabled in lwipopts.h" + #error "LWIP_DNS must be enabled in lwipopts.h" #endif #if LWIP_UDP @@ -164,11 +164,11 @@ ip_addr_t *u8_to_ip_addr(uint8_t *ipu8, ip_addr_t *ipaddr); uint32_t ip_addr_to_u32(ip_addr_t *ipaddr); #if LWIP_TCP -err_t tcp_connected_callback(void *arg, struct tcp_pcb *tpcb, err_t err); -err_t tcp_accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err); -void tcp_connection_close(struct tcp_pcb *tpcb, struct tcp_struct *tcp); + err_t tcp_connected_callback(void *arg, struct tcp_pcb *tpcb, err_t err); + err_t tcp_accept_callback(void *arg, struct tcp_pcb *newpcb, err_t err); + void tcp_connection_close(struct tcp_pcb *tpcb, struct tcp_struct *tcp); #else -#error "LWIP_TCP must be enabled in lwipopts.h" + #error "LWIP_TCP must be enabled in lwipopts.h" #endif #endif /* __STM32_ETH_H__ */