Skip to content

Commit a1fbc88

Browse files
committed
Peer review fixes (thanks Copilot)
1 parent 0fbf34a commit a1fbc88

4 files changed

Lines changed: 101 additions & 32 deletions

File tree

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ CPPCHECK_FLAGS=--enable=warning,performance,portability,missingInclude \
143143
--suppress=comparePointers:src/port/va416xx/syscalls.c \
144144
--suppress=comparePointers:src/port/lpc54s018/startup.c \
145145
--suppress=comparePointers:src/port/lpc54s018/syscalls.c \
146+
--suppress=comparePointers:src/port/stm32f439/startup.c \
147+
--suppress=comparePointers:src/port/stm32f439/syscalls.c \
146148
--disable=style \
147149
--std=c99 --language=c \
148150
--platform=unix64 \

src/port/stm32f4/stm32f4_eth.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@
4040
#define ETH_DEBUG(...) do { } while (0)
4141
#endif
4242

43-
/* Millisecond tick provided by the board port (SysTick handler). */
44-
extern volatile uint64_t HAL_time_ms;
43+
/* HAL_time_ms (declared in stm32f4_eth.h) is the SysTick-driven millisecond
44+
* tick maintained by the board port. Use stm32f4_hal_time_ms() to read it
45+
* tear-free. */
4546

4647
/* HCLK frequency provided by the board port (used to pick MDIO divider). */
4748
extern uint32_t stm32f4_eth_hclk_hz(void);
@@ -284,12 +285,16 @@ static void eth_config_mac(const uint8_t *mac)
284285
* no PS bit (no GMII support). */
285286
ETH_MACCR = MACCR_ACS | MACCR_IPCO | MACCR_DM;
286287

287-
/* Perfect filter, broadcast allowed (DBF=0). */
288-
#ifdef DEBUG_ETH
289-
ETH_MACFFR = (1U << 0); /* PR=1 promiscuous for diag */
290-
#else
291-
ETH_MACFFR = 0U;
292-
#endif
288+
/* Set PM=1 (Promiscuous Mode). On this STM32F4 GMAC IP the hardware
289+
* address filter rejects every incoming frame -- including broadcast
290+
* ARP and multicast -- when PM=0, even with BFD=0 (broadcasts
291+
* supposedly enabled), PAM=1 (pass-all-multicast), or RA=1
292+
* (receive-all) set. Only PM=1 opens the RX path. Verified on
293+
* NUCLEO-F439ZI with all four bits exercised individually. wolfIP
294+
* does its own destination-MAC check in software (wolfip.c
295+
* recv_on()), so accepting extra frames here is benign aside from a
296+
* small CPU cost in the polling loop. */
297+
ETH_MACFFR = (1U << 0);
293298
}
294299

295300
static void eth_config_speed_duplex(void)
@@ -405,10 +410,10 @@ static int eth_phy_init(void)
405410

406411
/* Soft reset and wait. */
407412
(void)mdio_write(STM32F4_ETH_PHY_ADDR, PHY_BCR, BCR_RESET);
408-
deadline = HAL_time_ms + 500U;
413+
deadline = stm32f4_hal_time_ms() + 500U;
409414
do {
410415
bmcr = mdio_read(STM32F4_ETH_PHY_ADDR, PHY_BCR);
411-
} while ((bmcr & BCR_RESET) && (HAL_time_ms < deadline));
416+
} while ((bmcr & BCR_RESET) && (stm32f4_hal_time_ms() < deadline));
412417
if (bmcr & BCR_RESET) {
413418
printf(" PHY: reset did not clear\n");
414419
return -1;
@@ -424,12 +429,13 @@ static int eth_phy_init(void)
424429
BCR_AUTONEG | BCR_RESTART_AN);
425430

426431
/* Wait up to 5s for link up + AN complete. */
427-
deadline = HAL_time_ms + 5000U;
432+
deadline = stm32f4_hal_time_ms() + 5000U;
428433
do {
429434
bsr = mdio_read(STM32F4_ETH_PHY_ADDR, PHY_BSR);
430435
bsr = mdio_read(STM32F4_ETH_PHY_ADDR, PHY_BSR); /* latch-clear */
431436
} while (((bsr & (BSR_LINK | BSR_AN_COMPLETE)) !=
432-
(BSR_LINK | BSR_AN_COMPLETE)) && (HAL_time_ms < deadline));
437+
(BSR_LINK | BSR_AN_COMPLETE)) &&
438+
(stm32f4_hal_time_ms() < deadline));
433439

434440
printf(" PHY link: %s, AN: %s\n",
435441
(bsr & BSR_LINK) ? "UP" : "DOWN",
@@ -620,7 +626,7 @@ int stm32f4_eth_init(struct wolfIP_ll_dev *ll, const uint8_t *mac)
620626
eth_stop();
621627

622628
if (eth_hw_reset() != 0)
623-
return -2;
629+
return -1;
624630

625631
eth_config_dma();
626632
eth_init_desc();

src/port/stm32f4/stm32f4_eth.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@
2727
#include <stdint.h>
2828
#include "wolfip.h"
2929

30+
/* Millisecond tick counter, maintained by SysTick_Handler in the port's
31+
* main.c. Reads on Cortex-M4 are non-atomic (LDRD is interruptible), so
32+
* always read it through stm32f4_hal_time_ms() below to avoid tearing. */
33+
extern volatile uint64_t HAL_time_ms;
34+
35+
/* Tear-free read of HAL_time_ms. Lamport double-read: in the worst case a
36+
* SysTick fires between the two halves and a/b disagree, so re-read. */
37+
static inline uint64_t stm32f4_hal_time_ms(void)
38+
{
39+
uint64_t a, b;
40+
do {
41+
a = HAL_time_ms;
42+
b = HAL_time_ms;
43+
} while (a != b);
44+
return b;
45+
}
46+
3047
/* Initialize the STM32F4 Ethernet MAC + DMA + PHY and hook the driver into
3148
* the wolfIP link-layer device. PHY auto-negotiation is run synchronously
3249
* with a 5-second timeout. Returns 0 on success, -2 if the PHY is reachable

src/port/stm32f439/main.c

Lines changed: 63 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,25 @@
6666
#define RCC_PLLCFGR (*(volatile uint32_t *)(RCC_BASE + 0x04U))
6767
#define RCC_CFGR (*(volatile uint32_t *)(RCC_BASE + 0x08U))
6868
#define RCC_AHB1ENR (*(volatile uint32_t *)(RCC_BASE + 0x30U))
69+
#define RCC_AHB2ENR (*(volatile uint32_t *)(RCC_BASE + 0x34U))
6970
#define RCC_APB1ENR (*(volatile uint32_t *)(RCC_BASE + 0x40U))
7071
#define RCC_APB2ENR (*(volatile uint32_t *)(RCC_BASE + 0x44U))
7172
#define RCC_AHB1RSTR (*(volatile uint32_t *)(RCC_BASE + 0x10U))
7273

74+
#define RCC_AHB2ENR_RNGEN (1U << 6)
75+
76+
/* Hardware RNG (RM0090 sec 24). Clocked from PLL48CLK = 48 MHz (PLLQ=7). */
77+
#define RNG_BASE 0x50060800UL
78+
#define RNG_CR (*(volatile uint32_t *)(RNG_BASE + 0x00U))
79+
#define RNG_SR (*(volatile uint32_t *)(RNG_BASE + 0x04U))
80+
#define RNG_DR (*(volatile uint32_t *)(RNG_BASE + 0x08U))
81+
#define RNG_CR_RNGEN (1U << 2)
82+
#define RNG_SR_DRDY (1U << 0)
83+
#define RNG_SR_CECS (1U << 1)
84+
#define RNG_SR_SECS (1U << 2)
85+
#define RNG_SR_CEIS (1U << 5)
86+
#define RNG_SR_SEIS (1U << 6)
87+
7388
#define RCC_CR_HSEON (1U << 16)
7489
#define RCC_CR_HSERDY (1U << 17)
7590
#define RCC_CR_HSEBYP (1U << 18)
@@ -143,6 +158,8 @@
143158
#define UART_RX_PIN 9U
144159
#define UART_AF 7U
145160
#elif defined(BOARD_STM32439I_EVAL)
161+
/* UART4 PC10(TX)/PC11(RX) AF8 -- STM32437I-EVAL VCP route, matches the
162+
* wolfssl-examples-stm32 BARE F437 reference firmware. */
146163
#define UART_BASE 0x40004C00UL /* UART4 */
147164
#define UART_CLK_BIT RCC_APB1ENR_UART4EN
148165
#define UART_PORT GPIOC_BASE
@@ -505,24 +522,38 @@ static void eth_clk_init(void)
505522
}
506523

507524
/* ===================================================================== */
508-
/* wolfIP random number source */
525+
/* wolfIP random number source - STM32F4 hardware RNG */
509526
/* ===================================================================== */
510527

528+
static void rng_init(void)
529+
{
530+
RCC_AHB2ENR |= RCC_AHB2ENR_RNGEN;
531+
(void)RCC_AHB2ENR;
532+
RNG_CR = RNG_CR_RNGEN;
533+
}
534+
511535
uint32_t wolfIP_getrandom(void)
512536
{
513-
static uint32_t lfsr;
514-
static int seeded;
515-
516-
if (!seeded) {
517-
lfsr = (uint32_t)HAL_time_ms;
518-
if (lfsr == 0U)
519-
lfsr = 0xC0FFEE01U;
520-
seeded = 1;
537+
uint32_t sr;
538+
uint32_t retries = 100U;
539+
540+
while (retries-- > 0U) {
541+
sr = RNG_SR;
542+
if (sr & (RNG_SR_CEIS | RNG_SR_SEIS)) {
543+
/* Clear error flags and restart the RNG. CEIS indicates
544+
* PLL48CLK trouble; SEIS indicates a seed-quality failure.
545+
* Both are recoverable per RM0090. */
546+
RNG_SR = sr & ~(RNG_SR_CEIS | RNG_SR_SEIS);
547+
RNG_CR = 0U;
548+
RNG_CR = RNG_CR_RNGEN;
549+
continue;
550+
}
551+
if (sr & RNG_SR_DRDY)
552+
return RNG_DR;
521553
}
522-
lfsr ^= lfsr << 13;
523-
lfsr ^= lfsr >> 17;
524-
lfsr ^= lfsr << 5;
525-
return lfsr;
554+
/* RNG never produced data - fall back to a fixed value rather than
555+
* hanging the stack. This should not happen on a healthy board. */
556+
return 0xDEADBEEFU;
526557
}
527558

528559
/* ===================================================================== */
@@ -596,6 +627,7 @@ int main(void)
596627

597628
systick_init();
598629
uart_init();
630+
rng_init();
599631

600632
printf("\n\n=== wolfIP STM32F437/F439 (" BOARD_NAME ") ===\n");
601633
printf("Build: " __DATE__ " " __TIME__ "\n");
@@ -620,7 +652,7 @@ int main(void)
620652

621653
#ifdef DHCP
622654
printf("Starting DHCP...\n");
623-
(void)wolfIP_poll(IPStack, HAL_time_ms);
655+
(void)wolfIP_poll(IPStack, stm32f4_hal_time_ms());
624656
(void)dhcp_client_init(IPStack);
625657
#else
626658
{
@@ -642,10 +674,22 @@ int main(void)
642674

643675
printf("TCP echo server on port %d\n", ECHO_PORT);
644676
listen_fd = wolfIP_sock_socket(IPStack, AF_INET, IPSTACK_SOCK_STREAM, 0);
677+
if (listen_fd < 0) {
678+
printf(" ERROR: wolfIP_sock_socket failed (%d)\n", listen_fd);
679+
for (;;) { __asm volatile ("wfi"); }
680+
}
645681
wolfIP_register_callback(IPStack, listen_fd, echo_cb, IPStack);
646-
(void)wolfIP_sock_bind(IPStack, listen_fd,
682+
ret = wolfIP_sock_bind(IPStack, listen_fd,
647683
(struct wolfIP_sockaddr *)&addr, sizeof(addr));
648-
(void)wolfIP_sock_listen(IPStack, listen_fd, 1);
684+
if (ret < 0) {
685+
printf(" ERROR: wolfIP_sock_bind failed (%d)\n", ret);
686+
for (;;) { __asm volatile ("wfi"); }
687+
}
688+
ret = wolfIP_sock_listen(IPStack, listen_fd, 1);
689+
if (ret < 0) {
690+
printf(" ERROR: wolfIP_sock_listen failed (%d)\n", ret);
691+
for (;;) { __asm volatile ("wfi"); }
692+
}
649693

650694
printf("Ready! Test with:\n");
651695
printf(" ping <ip>\n");
@@ -654,13 +698,13 @@ int main(void)
654698
{
655699
uint64_t last_diag_ms = 0;
656700
#ifdef DHCP
657-
uint64_t dhcp_start_ms = HAL_time_ms;
658-
uint64_t dhcp_reinit_ms = HAL_time_ms;
701+
uint64_t dhcp_start_ms = stm32f4_hal_time_ms();
702+
uint64_t dhcp_reinit_ms = dhcp_start_ms;
659703
int dhcp_done = 0;
660704
#endif
661705

662706
for (;;) {
663-
uint64_t now = HAL_time_ms;
707+
uint64_t now = stm32f4_hal_time_ms();
664708
(void)wolfIP_poll(IPStack, now);
665709

666710
#ifdef DHCP

0 commit comments

Comments
 (0)