Add STM32 NUCLEO-F429ZI sample - #47

Open
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI
Open

Add STM32 NUCLEO-F429ZI sample#47
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI

Conversation

@Jaxc

@JaxcJaxc commented Aug 5, 2026

Copy link
Copy Markdown

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It uses the same tasks and IO but for STM32F4 peripherals.

@Jaxc

Jaxc commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hello

I've been wanting to try out ThreadX but didn't know where to start. So I though I could "Port" a sample to a new devboard as that could be helpful to someone.

I also added some extras that I found useful in the tools folder, but I'm very unsure if they should be merged or not.

@Jaxc
Jaxcforce-pushed the Nucleo-F429ZI branch 2 times, most recently from ba1a16d to 2082837CompareAugust 7, 2026 15:11
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Jaxc.

Thank you for this contribution! I somehow did not notice your PR before today. I will review it this week. Thanks again!

@fdesbiensfdesbiens self-assigned this Aug 24, 2026
@fdesbiensfdesbiens moved this to In review in ThreadX RoadmapAug 24, 2026
@fdesbiens
fdesbiens self-requested a review August 24, 2026 18:25
@Jaxc

Jaxc commented Aug 25, 2026

Copy link
Copy Markdown
Author

Hello @fdesbiens

Absolutely no worries!

I also pushed my code a bit further and managed to get USBx up with a MSC device. I plan to push that too but it needs cleanup. Would you want that as a separate PR or should I amend this one?

@fdesbiens

Copy link
Copy Markdown
Contributor

Thank you, @Jaxc. I would prefer a separate PR. I will aim to review this one today.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaxc — thanks again for this, and sorry for the slow start. I checked it out and built it locally, and the overall shape is good: the port is faithful, the console/ring-buffer thread is a nice touch, and it compiles with -Werror and no warnings once one path is fixed. A few things to sort out before I can merge.

Three things that need fixing

1. The build doesn't configure on Linux. In cmake/FindSTM32HAL.cmake, the find_path hint on line 70 is Drivers/stm32${STM32_FAMILY}xx_hal_Driver/Inc (lowercase stm32), but fetch_sdk.sh creates Drivers/STM32F4xx_hal_Driver. CMake bails with Could NOT find STM32HAL (missing: STM32HAL_INCLUDE_DIR). It only works on Windows because NTFS is case-insensitive. Could you align everything on STM32F4xx_HAL_Driver — both HINTS lines, fetch_sdk.sh, and fetch_sdk.ps1? That's the spelling both STM32F767ZI-Nucleo and NUCLEO_F401RE already use. With just that change the build finishes cleanly here (GCC 13.2, CMake 4.4, Ninja).

2. Wrong FPU for the part.cmake/arm-gcc-cortex-m4.cmake sets -mfpu=fpv5-d16, which is the Cortex-M7 unit — that got carried over from the F767 toolchain file. The F429's Cortex-M4F has FPv4-SP-D16, single precision only. GCC accepts -mcpu=cortex-m4 -mfpu=fpv5-d16 without complaint and will happily emit vdiv.f64, which the hardware doesn't implement. The current demo contains no double-precision instructions so it won't fault today, but readelf -A on the ELF does report Tag_FP_arch: FPv5/FP-D16 for ARMv8, and the first bit of double math anyone adds would hard-fault. Please use -mfpu=fpv4-sp-d16NUCLEO_F401RE already does.

3. The __HAL_UART_CLEAR_PEFLAG call in USART3_IRQHandler drops characters. This one is subtle and entirely the F7's fault. On the F7 that macro writes to ICR. On the F4 it expands to a read of SR followed by a read of DR — a destructive read. Since it runs unconditionally at the end of every interrupt, any byte that arrives between your RXNE read and that line gets consumed and thrown away, and no further interrupt fires for it. Rare at 115200, but real. I'd handle the error flags explicitly instead, e.g. only run the SR/DR clear sequence when ORE/FE/NE/PE is actually set, and push the recovered byte into the ring buffer.

Please retarget to dev

We take PRs against dev rather than main. That matters more than usual here: dev has a refactored F767 sample that moved the app into app/demos/<demo>/ with an ACTIVE_DEMO CMake cache variable and now carries a NetX Duo echo demo and a network station demo. So the layout you copied from main no longer exists upstream. Rebasing onto dev and matching that structure (app/demos/threadx_basic/main.c) would save us a painful reconciliation later — and it's the structure your USBX demo will want to slot into anyway.

Dead hardware init

ethernet_phy_init() and MX_USB_OTG_FS_PCD_Init() are both commented out in board_init(), MPU_Config() is declared but never defined or called, and ethernet_phy.c is compiled but unreachable. Its .RxDecripSection / .TxDecripSection descriptors aren't in the linker script either — that only goes unnoticed because --gc-sections discards them. For this PR I'd drop ethernet_phy.c, the eth component from find_package, and HAL_ETH_MODULE_ENABLED / HAL_PCD_MODULE_ENABLED from stm32f4xx_hal_conf.h, then bring Ethernet in properly when there's a demo that uses it. (Some of this is inherited from the F767 original — not your doing, but I'd rather not propagate it to a third board.)

On the tools/ folder — you asked, so:

  • The .ioc I'd definitely keep. None of the other boards have one, and documenting how the pin configuration was produced is genuinely useful. Good precedent to set.
  • The Ozone .jdebug I'm happy to take too. I checked and it only uses relative paths (./STM32F429.svd, ../build/stm32f429_threadx.elf), so it's portable. Please add a line about it to the README so people know it's there.
  • The 2.1 MB STM32F429.svd is the one I'd rather not commit. It's not reachable from any build, and most people get it from their IDE or ST's CMSIS pack. Could you fetch it in fetch_sdk.sh alongside the HAL and CMSIS clones instead? If that turns out to be awkward, I won't block the PR over it — but then it needs a NOTICE entry.

Which brings me to: NOTICE.md needs updating for the third-party files this PR vendors in. The SVD is ST, Apache-2.0. The .jdebug is SEGGER. And the CubeIDE-generated files committed under app/syscalls.c, sysmem.c, startup_stm32f429xx.s, system_stm32f4xx.c, main.h, and the linker script — all carry ST copyright with no accompanying licence text. Right now NOTICE only covers the components fetch_sdk.sh downloads.

Smaller things

  • board_init(): the comment above SystemClock_Config() still says "Configure the system clock to 216 MHz". It's 168.
  • README: the binary is build/stm32f429_threadx.bin, not stm32F429_threadx.bin — the capital F will send Linux users looking for a file that isn't there.
  • README: 250 ms on plus 250 ms off is a 1 Hz blink (2 Hz toggle rate). Worth rewording.
  • MX_GPIO_Init() configures the user button as GPIO_MODE_IT_RISING, but the EXTI line is never enabled and the button is polled. GPIO_MODE_INPUT is what you want.
  • int __io_getchar(void); is declared in main.c and never used.
  • Three threads call printf concurrently and it funnels into an unguarded HAL_UART_Transmit, so output can interleave. Same in the F767 sample, so not a blocker — but a TX_MUTEX around the console would be a real improvement if you feel like it.
  • Header attribution: you credited yourself in main.c and board_init.c but not in console.c, ethernet_phy.c/h, CMakeLists.txt, the cmake modules, or the scripts. Please add yourself to everything you touched. Also, new-file headers here should read "Eclipse ThreadX contributors" — console.c says "Eclipse Foundation", inherited from the original.
  • Commit style: our short descriptions start with a past-tense verb, so "Added the STM32 NUCLEO-F429ZI sample". And the PR body says F676 where it means F767. 😄

None of this is hard to fix and the foundation is solid. Looking forward to the USBX one as a separate PR.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes-requested to reflect the state accurately — the details are in my review just above. The three blockers are the Linux build break in FindSTM32HAL.cmake, the -mfpu=fpv5-d16 Cortex-M7 flag on an M4, and the destructive __HAL_UART_CLEAR_PEFLAG read in USART3_IRQHandler. Retargeting onto dev is the other must-do. Happy to re-review as soon as you've had a pass at them.

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It
uses the same tasks and IO but for STM32F4 peripherals.
@Jaxc

Jaxc commented Aug 31, 2026

Copy link
Copy Markdown
Author

I fixed most things, and pushed just for me to check how it looks now. I will do another amend to fix the last things.

This brings me to:

How should I update the NOTICE.md? Some files was copied from F767 and it doesn't have the needed info there either :)

Oh and about the .svd: It feels a bit wrong to add it to the fetch_sdk as it is "optional". But it also feels a bit redundant to add a new script to fetch only that file. But maybe there are more optional debug focused files that could be fetched? For now I removed the file from the commit

@Jaxc
Jaxc changed the base branch from main to devAugust 31, 2026 15:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants

@Jaxc@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add STM32 NUCLEO-F429ZI sample - #47

Open
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI
Open

Add STM32 NUCLEO-F429ZI sample#47
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI

Conversation

@Jaxc

@JaxcJaxc commented Aug 5, 2026

Copy link
Copy Markdown

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It uses the same tasks and IO but for STM32F4 peripherals.

@Jaxc

Jaxc commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hello

I've been wanting to try out ThreadX but didn't know where to start. So I though I could "Port" a sample to a new devboard as that could be helpful to someone.

I also added some extras that I found useful in the tools folder, but I'm very unsure if they should be merged or not.

@Jaxc
Jaxcforce-pushed the Nucleo-F429ZI branch 2 times, most recently from ba1a16d to 2082837CompareAugust 7, 2026 15:11
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Jaxc.

Thank you for this contribution! I somehow did not notice your PR before today. I will review it this week. Thanks again!

@fdesbiensfdesbiens self-assigned this Aug 24, 2026
@fdesbiensfdesbiens moved this to In review in ThreadX RoadmapAug 24, 2026
@fdesbiens
fdesbiens self-requested a review August 24, 2026 18:25
@Jaxc

Jaxc commented Aug 25, 2026

Copy link
Copy Markdown
Author

Hello @fdesbiens

Absolutely no worries!

I also pushed my code a bit further and managed to get USBx up with a MSC device. I plan to push that too but it needs cleanup. Would you want that as a separate PR or should I amend this one?

@fdesbiens

Copy link
Copy Markdown
Contributor

Thank you, @Jaxc. I would prefer a separate PR. I will aim to review this one today.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaxc — thanks again for this, and sorry for the slow start. I checked it out and built it locally, and the overall shape is good: the port is faithful, the console/ring-buffer thread is a nice touch, and it compiles with -Werror and no warnings once one path is fixed. A few things to sort out before I can merge.

Three things that need fixing

1. The build doesn't configure on Linux. In cmake/FindSTM32HAL.cmake, the find_path hint on line 70 is Drivers/stm32${STM32_FAMILY}xx_hal_Driver/Inc (lowercase stm32), but fetch_sdk.sh creates Drivers/STM32F4xx_hal_Driver. CMake bails with Could NOT find STM32HAL (missing: STM32HAL_INCLUDE_DIR). It only works on Windows because NTFS is case-insensitive. Could you align everything on STM32F4xx_HAL_Driver — both HINTS lines, fetch_sdk.sh, and fetch_sdk.ps1? That's the spelling both STM32F767ZI-Nucleo and NUCLEO_F401RE already use. With just that change the build finishes cleanly here (GCC 13.2, CMake 4.4, Ninja).

2. Wrong FPU for the part.cmake/arm-gcc-cortex-m4.cmake sets -mfpu=fpv5-d16, which is the Cortex-M7 unit — that got carried over from the F767 toolchain file. The F429's Cortex-M4F has FPv4-SP-D16, single precision only. GCC accepts -mcpu=cortex-m4 -mfpu=fpv5-d16 without complaint and will happily emit vdiv.f64, which the hardware doesn't implement. The current demo contains no double-precision instructions so it won't fault today, but readelf -A on the ELF does report Tag_FP_arch: FPv5/FP-D16 for ARMv8, and the first bit of double math anyone adds would hard-fault. Please use -mfpu=fpv4-sp-d16NUCLEO_F401RE already does.

3. The __HAL_UART_CLEAR_PEFLAG call in USART3_IRQHandler drops characters. This one is subtle and entirely the F7's fault. On the F7 that macro writes to ICR. On the F4 it expands to a read of SR followed by a read of DR — a destructive read. Since it runs unconditionally at the end of every interrupt, any byte that arrives between your RXNE read and that line gets consumed and thrown away, and no further interrupt fires for it. Rare at 115200, but real. I'd handle the error flags explicitly instead, e.g. only run the SR/DR clear sequence when ORE/FE/NE/PE is actually set, and push the recovered byte into the ring buffer.

Please retarget to dev

We take PRs against dev rather than main. That matters more than usual here: dev has a refactored F767 sample that moved the app into app/demos/<demo>/ with an ACTIVE_DEMO CMake cache variable and now carries a NetX Duo echo demo and a network station demo. So the layout you copied from main no longer exists upstream. Rebasing onto dev and matching that structure (app/demos/threadx_basic/main.c) would save us a painful reconciliation later — and it's the structure your USBX demo will want to slot into anyway.

Dead hardware init

ethernet_phy_init() and MX_USB_OTG_FS_PCD_Init() are both commented out in board_init(), MPU_Config() is declared but never defined or called, and ethernet_phy.c is compiled but unreachable. Its .RxDecripSection / .TxDecripSection descriptors aren't in the linker script either — that only goes unnoticed because --gc-sections discards them. For this PR I'd drop ethernet_phy.c, the eth component from find_package, and HAL_ETH_MODULE_ENABLED / HAL_PCD_MODULE_ENABLED from stm32f4xx_hal_conf.h, then bring Ethernet in properly when there's a demo that uses it. (Some of this is inherited from the F767 original — not your doing, but I'd rather not propagate it to a third board.)

On the tools/ folder — you asked, so:

  • The .ioc I'd definitely keep. None of the other boards have one, and documenting how the pin configuration was produced is genuinely useful. Good precedent to set.
  • The Ozone .jdebug I'm happy to take too. I checked and it only uses relative paths (./STM32F429.svd, ../build/stm32f429_threadx.elf), so it's portable. Please add a line about it to the README so people know it's there.
  • The 2.1 MB STM32F429.svd is the one I'd rather not commit. It's not reachable from any build, and most people get it from their IDE or ST's CMSIS pack. Could you fetch it in fetch_sdk.sh alongside the HAL and CMSIS clones instead? If that turns out to be awkward, I won't block the PR over it — but then it needs a NOTICE entry.

Which brings me to: NOTICE.md needs updating for the third-party files this PR vendors in. The SVD is ST, Apache-2.0. The .jdebug is SEGGER. And the CubeIDE-generated files committed under app/syscalls.c, sysmem.c, startup_stm32f429xx.s, system_stm32f4xx.c, main.h, and the linker script — all carry ST copyright with no accompanying licence text. Right now NOTICE only covers the components fetch_sdk.sh downloads.

Smaller things

  • board_init(): the comment above SystemClock_Config() still says "Configure the system clock to 216 MHz". It's 168.
  • README: the binary is build/stm32f429_threadx.bin, not stm32F429_threadx.bin — the capital F will send Linux users looking for a file that isn't there.
  • README: 250 ms on plus 250 ms off is a 1 Hz blink (2 Hz toggle rate). Worth rewording.
  • MX_GPIO_Init() configures the user button as GPIO_MODE_IT_RISING, but the EXTI line is never enabled and the button is polled. GPIO_MODE_INPUT is what you want.
  • int __io_getchar(void); is declared in main.c and never used.
  • Three threads call printf concurrently and it funnels into an unguarded HAL_UART_Transmit, so output can interleave. Same in the F767 sample, so not a blocker — but a TX_MUTEX around the console would be a real improvement if you feel like it.
  • Header attribution: you credited yourself in main.c and board_init.c but not in console.c, ethernet_phy.c/h, CMakeLists.txt, the cmake modules, or the scripts. Please add yourself to everything you touched. Also, new-file headers here should read "Eclipse ThreadX contributors" — console.c says "Eclipse Foundation", inherited from the original.
  • Commit style: our short descriptions start with a past-tense verb, so "Added the STM32 NUCLEO-F429ZI sample". And the PR body says F676 where it means F767. 😄

None of this is hard to fix and the foundation is solid. Looking forward to the USBX one as a separate PR.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes-requested to reflect the state accurately — the details are in my review just above. The three blockers are the Linux build break in FindSTM32HAL.cmake, the -mfpu=fpv5-d16 Cortex-M7 flag on an M4, and the destructive __HAL_UART_CLEAR_PEFLAG read in USART3_IRQHandler. Retargeting onto dev is the other must-do. Happy to re-review as soon as you've had a pass at them.

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It
uses the same tasks and IO but for STM32F4 peripherals.
@Jaxc

Jaxc commented Aug 31, 2026

Copy link
Copy Markdown
Author

I fixed most things, and pushed just for me to check how it looks now. I will do another amend to fix the last things.

This brings me to:

How should I update the NOTICE.md? Some files was copied from F767 and it doesn't have the needed info there either :)

Oh and about the .svd: It feels a bit wrong to add it to the fetch_sdk as it is "optional". But it also feels a bit redundant to add a new script to fetch only that file. But maybe there are more optional debug focused files that could be fetched? For now I removed the file from the commit

@Jaxc
Jaxc changed the base branch from main to devAugust 31, 2026 15:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants

@Jaxc@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add STM32 NUCLEO-F429ZI sample - #47

Open
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI
Open

Add STM32 NUCLEO-F429ZI sample#47
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI

Conversation

@Jaxc

@JaxcJaxc commented Aug 5, 2026

Copy link
Copy Markdown

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It uses the same tasks and IO but for STM32F4 peripherals.

@Jaxc

Jaxc commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hello

I've been wanting to try out ThreadX but didn't know where to start. So I though I could "Port" a sample to a new devboard as that could be helpful to someone.

I also added some extras that I found useful in the tools folder, but I'm very unsure if they should be merged or not.

@Jaxc
Jaxcforce-pushed the Nucleo-F429ZI branch 2 times, most recently from ba1a16d to 2082837CompareAugust 7, 2026 15:11
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Jaxc.

Thank you for this contribution! I somehow did not notice your PR before today. I will review it this week. Thanks again!

@fdesbiensfdesbiens self-assigned this Aug 24, 2026
@fdesbiensfdesbiens moved this to In review in ThreadX RoadmapAug 24, 2026
@fdesbiens
fdesbiens self-requested a review August 24, 2026 18:25
@Jaxc

Jaxc commented Aug 25, 2026

Copy link
Copy Markdown
Author

Hello @fdesbiens

Absolutely no worries!

I also pushed my code a bit further and managed to get USBx up with a MSC device. I plan to push that too but it needs cleanup. Would you want that as a separate PR or should I amend this one?

@fdesbiens

Copy link
Copy Markdown
Contributor

Thank you, @Jaxc. I would prefer a separate PR. I will aim to review this one today.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaxc — thanks again for this, and sorry for the slow start. I checked it out and built it locally, and the overall shape is good: the port is faithful, the console/ring-buffer thread is a nice touch, and it compiles with -Werror and no warnings once one path is fixed. A few things to sort out before I can merge.

Three things that need fixing

1. The build doesn't configure on Linux. In cmake/FindSTM32HAL.cmake, the find_path hint on line 70 is Drivers/stm32${STM32_FAMILY}xx_hal_Driver/Inc (lowercase stm32), but fetch_sdk.sh creates Drivers/STM32F4xx_hal_Driver. CMake bails with Could NOT find STM32HAL (missing: STM32HAL_INCLUDE_DIR). It only works on Windows because NTFS is case-insensitive. Could you align everything on STM32F4xx_HAL_Driver — both HINTS lines, fetch_sdk.sh, and fetch_sdk.ps1? That's the spelling both STM32F767ZI-Nucleo and NUCLEO_F401RE already use. With just that change the build finishes cleanly here (GCC 13.2, CMake 4.4, Ninja).

2. Wrong FPU for the part.cmake/arm-gcc-cortex-m4.cmake sets -mfpu=fpv5-d16, which is the Cortex-M7 unit — that got carried over from the F767 toolchain file. The F429's Cortex-M4F has FPv4-SP-D16, single precision only. GCC accepts -mcpu=cortex-m4 -mfpu=fpv5-d16 without complaint and will happily emit vdiv.f64, which the hardware doesn't implement. The current demo contains no double-precision instructions so it won't fault today, but readelf -A on the ELF does report Tag_FP_arch: FPv5/FP-D16 for ARMv8, and the first bit of double math anyone adds would hard-fault. Please use -mfpu=fpv4-sp-d16NUCLEO_F401RE already does.

3. The __HAL_UART_CLEAR_PEFLAG call in USART3_IRQHandler drops characters. This one is subtle and entirely the F7's fault. On the F7 that macro writes to ICR. On the F4 it expands to a read of SR followed by a read of DR — a destructive read. Since it runs unconditionally at the end of every interrupt, any byte that arrives between your RXNE read and that line gets consumed and thrown away, and no further interrupt fires for it. Rare at 115200, but real. I'd handle the error flags explicitly instead, e.g. only run the SR/DR clear sequence when ORE/FE/NE/PE is actually set, and push the recovered byte into the ring buffer.

Please retarget to dev

We take PRs against dev rather than main. That matters more than usual here: dev has a refactored F767 sample that moved the app into app/demos/<demo>/ with an ACTIVE_DEMO CMake cache variable and now carries a NetX Duo echo demo and a network station demo. So the layout you copied from main no longer exists upstream. Rebasing onto dev and matching that structure (app/demos/threadx_basic/main.c) would save us a painful reconciliation later — and it's the structure your USBX demo will want to slot into anyway.

Dead hardware init

ethernet_phy_init() and MX_USB_OTG_FS_PCD_Init() are both commented out in board_init(), MPU_Config() is declared but never defined or called, and ethernet_phy.c is compiled but unreachable. Its .RxDecripSection / .TxDecripSection descriptors aren't in the linker script either — that only goes unnoticed because --gc-sections discards them. For this PR I'd drop ethernet_phy.c, the eth component from find_package, and HAL_ETH_MODULE_ENABLED / HAL_PCD_MODULE_ENABLED from stm32f4xx_hal_conf.h, then bring Ethernet in properly when there's a demo that uses it. (Some of this is inherited from the F767 original — not your doing, but I'd rather not propagate it to a third board.)

On the tools/ folder — you asked, so:

  • The .ioc I'd definitely keep. None of the other boards have one, and documenting how the pin configuration was produced is genuinely useful. Good precedent to set.
  • The Ozone .jdebug I'm happy to take too. I checked and it only uses relative paths (./STM32F429.svd, ../build/stm32f429_threadx.elf), so it's portable. Please add a line about it to the README so people know it's there.
  • The 2.1 MB STM32F429.svd is the one I'd rather not commit. It's not reachable from any build, and most people get it from their IDE or ST's CMSIS pack. Could you fetch it in fetch_sdk.sh alongside the HAL and CMSIS clones instead? If that turns out to be awkward, I won't block the PR over it — but then it needs a NOTICE entry.

Which brings me to: NOTICE.md needs updating for the third-party files this PR vendors in. The SVD is ST, Apache-2.0. The .jdebug is SEGGER. And the CubeIDE-generated files committed under app/syscalls.c, sysmem.c, startup_stm32f429xx.s, system_stm32f4xx.c, main.h, and the linker script — all carry ST copyright with no accompanying licence text. Right now NOTICE only covers the components fetch_sdk.sh downloads.

Smaller things

  • board_init(): the comment above SystemClock_Config() still says "Configure the system clock to 216 MHz". It's 168.
  • README: the binary is build/stm32f429_threadx.bin, not stm32F429_threadx.bin — the capital F will send Linux users looking for a file that isn't there.
  • README: 250 ms on plus 250 ms off is a 1 Hz blink (2 Hz toggle rate). Worth rewording.
  • MX_GPIO_Init() configures the user button as GPIO_MODE_IT_RISING, but the EXTI line is never enabled and the button is polled. GPIO_MODE_INPUT is what you want.
  • int __io_getchar(void); is declared in main.c and never used.
  • Three threads call printf concurrently and it funnels into an unguarded HAL_UART_Transmit, so output can interleave. Same in the F767 sample, so not a blocker — but a TX_MUTEX around the console would be a real improvement if you feel like it.
  • Header attribution: you credited yourself in main.c and board_init.c but not in console.c, ethernet_phy.c/h, CMakeLists.txt, the cmake modules, or the scripts. Please add yourself to everything you touched. Also, new-file headers here should read "Eclipse ThreadX contributors" — console.c says "Eclipse Foundation", inherited from the original.
  • Commit style: our short descriptions start with a past-tense verb, so "Added the STM32 NUCLEO-F429ZI sample". And the PR body says F676 where it means F767. 😄

None of this is hard to fix and the foundation is solid. Looking forward to the USBX one as a separate PR.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes-requested to reflect the state accurately — the details are in my review just above. The three blockers are the Linux build break in FindSTM32HAL.cmake, the -mfpu=fpv5-d16 Cortex-M7 flag on an M4, and the destructive __HAL_UART_CLEAR_PEFLAG read in USART3_IRQHandler. Retargeting onto dev is the other must-do. Happy to re-review as soon as you've had a pass at them.

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It
uses the same tasks and IO but for STM32F4 peripherals.
@Jaxc

Jaxc commented Aug 31, 2026

Copy link
Copy Markdown
Author

I fixed most things, and pushed just for me to check how it looks now. I will do another amend to fix the last things.

This brings me to:

How should I update the NOTICE.md? Some files was copied from F767 and it doesn't have the needed info there either :)

Oh and about the .svd: It feels a bit wrong to add it to the fetch_sdk as it is "optional". But it also feels a bit redundant to add a new script to fetch only that file. But maybe there are more optional debug focused files that could be fetched? For now I removed the file from the commit

@Jaxc
Jaxc changed the base branch from main to devAugust 31, 2026 15:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants

@Jaxc@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add STM32 NUCLEO-F429ZI sample - #47

Open
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI
Open

Add STM32 NUCLEO-F429ZI sample#47
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI

Conversation

@Jaxc

@JaxcJaxc commented Aug 5, 2026

Copy link
Copy Markdown

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It uses the same tasks and IO but for STM32F4 peripherals.

@Jaxc

Jaxc commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hello

I've been wanting to try out ThreadX but didn't know where to start. So I though I could "Port" a sample to a new devboard as that could be helpful to someone.

I also added some extras that I found useful in the tools folder, but I'm very unsure if they should be merged or not.

@Jaxc
Jaxcforce-pushed the Nucleo-F429ZI branch 2 times, most recently from ba1a16d to 2082837CompareAugust 7, 2026 15:11
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Jaxc.

Thank you for this contribution! I somehow did not notice your PR before today. I will review it this week. Thanks again!

@fdesbiensfdesbiens self-assigned this Aug 24, 2026
@fdesbiensfdesbiens moved this to In review in ThreadX RoadmapAug 24, 2026
@fdesbiens
fdesbiens self-requested a review August 24, 2026 18:25
@Jaxc

Jaxc commented Aug 25, 2026

Copy link
Copy Markdown
Author

Hello @fdesbiens

Absolutely no worries!

I also pushed my code a bit further and managed to get USBx up with a MSC device. I plan to push that too but it needs cleanup. Would you want that as a separate PR or should I amend this one?

@fdesbiens

Copy link
Copy Markdown
Contributor

Thank you, @Jaxc. I would prefer a separate PR. I will aim to review this one today.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaxc — thanks again for this, and sorry for the slow start. I checked it out and built it locally, and the overall shape is good: the port is faithful, the console/ring-buffer thread is a nice touch, and it compiles with -Werror and no warnings once one path is fixed. A few things to sort out before I can merge.

Three things that need fixing

1. The build doesn't configure on Linux. In cmake/FindSTM32HAL.cmake, the find_path hint on line 70 is Drivers/stm32${STM32_FAMILY}xx_hal_Driver/Inc (lowercase stm32), but fetch_sdk.sh creates Drivers/STM32F4xx_hal_Driver. CMake bails with Could NOT find STM32HAL (missing: STM32HAL_INCLUDE_DIR). It only works on Windows because NTFS is case-insensitive. Could you align everything on STM32F4xx_HAL_Driver — both HINTS lines, fetch_sdk.sh, and fetch_sdk.ps1? That's the spelling both STM32F767ZI-Nucleo and NUCLEO_F401RE already use. With just that change the build finishes cleanly here (GCC 13.2, CMake 4.4, Ninja).

2. Wrong FPU for the part.cmake/arm-gcc-cortex-m4.cmake sets -mfpu=fpv5-d16, which is the Cortex-M7 unit — that got carried over from the F767 toolchain file. The F429's Cortex-M4F has FPv4-SP-D16, single precision only. GCC accepts -mcpu=cortex-m4 -mfpu=fpv5-d16 without complaint and will happily emit vdiv.f64, which the hardware doesn't implement. The current demo contains no double-precision instructions so it won't fault today, but readelf -A on the ELF does report Tag_FP_arch: FPv5/FP-D16 for ARMv8, and the first bit of double math anyone adds would hard-fault. Please use -mfpu=fpv4-sp-d16NUCLEO_F401RE already does.

3. The __HAL_UART_CLEAR_PEFLAG call in USART3_IRQHandler drops characters. This one is subtle and entirely the F7's fault. On the F7 that macro writes to ICR. On the F4 it expands to a read of SR followed by a read of DR — a destructive read. Since it runs unconditionally at the end of every interrupt, any byte that arrives between your RXNE read and that line gets consumed and thrown away, and no further interrupt fires for it. Rare at 115200, but real. I'd handle the error flags explicitly instead, e.g. only run the SR/DR clear sequence when ORE/FE/NE/PE is actually set, and push the recovered byte into the ring buffer.

Please retarget to dev

We take PRs against dev rather than main. That matters more than usual here: dev has a refactored F767 sample that moved the app into app/demos/<demo>/ with an ACTIVE_DEMO CMake cache variable and now carries a NetX Duo echo demo and a network station demo. So the layout you copied from main no longer exists upstream. Rebasing onto dev and matching that structure (app/demos/threadx_basic/main.c) would save us a painful reconciliation later — and it's the structure your USBX demo will want to slot into anyway.

Dead hardware init

ethernet_phy_init() and MX_USB_OTG_FS_PCD_Init() are both commented out in board_init(), MPU_Config() is declared but never defined or called, and ethernet_phy.c is compiled but unreachable. Its .RxDecripSection / .TxDecripSection descriptors aren't in the linker script either — that only goes unnoticed because --gc-sections discards them. For this PR I'd drop ethernet_phy.c, the eth component from find_package, and HAL_ETH_MODULE_ENABLED / HAL_PCD_MODULE_ENABLED from stm32f4xx_hal_conf.h, then bring Ethernet in properly when there's a demo that uses it. (Some of this is inherited from the F767 original — not your doing, but I'd rather not propagate it to a third board.)

On the tools/ folder — you asked, so:

  • The .ioc I'd definitely keep. None of the other boards have one, and documenting how the pin configuration was produced is genuinely useful. Good precedent to set.
  • The Ozone .jdebug I'm happy to take too. I checked and it only uses relative paths (./STM32F429.svd, ../build/stm32f429_threadx.elf), so it's portable. Please add a line about it to the README so people know it's there.
  • The 2.1 MB STM32F429.svd is the one I'd rather not commit. It's not reachable from any build, and most people get it from their IDE or ST's CMSIS pack. Could you fetch it in fetch_sdk.sh alongside the HAL and CMSIS clones instead? If that turns out to be awkward, I won't block the PR over it — but then it needs a NOTICE entry.

Which brings me to: NOTICE.md needs updating for the third-party files this PR vendors in. The SVD is ST, Apache-2.0. The .jdebug is SEGGER. And the CubeIDE-generated files committed under app/syscalls.c, sysmem.c, startup_stm32f429xx.s, system_stm32f4xx.c, main.h, and the linker script — all carry ST copyright with no accompanying licence text. Right now NOTICE only covers the components fetch_sdk.sh downloads.

Smaller things

  • board_init(): the comment above SystemClock_Config() still says "Configure the system clock to 216 MHz". It's 168.
  • README: the binary is build/stm32f429_threadx.bin, not stm32F429_threadx.bin — the capital F will send Linux users looking for a file that isn't there.
  • README: 250 ms on plus 250 ms off is a 1 Hz blink (2 Hz toggle rate). Worth rewording.
  • MX_GPIO_Init() configures the user button as GPIO_MODE_IT_RISING, but the EXTI line is never enabled and the button is polled. GPIO_MODE_INPUT is what you want.
  • int __io_getchar(void); is declared in main.c and never used.
  • Three threads call printf concurrently and it funnels into an unguarded HAL_UART_Transmit, so output can interleave. Same in the F767 sample, so not a blocker — but a TX_MUTEX around the console would be a real improvement if you feel like it.
  • Header attribution: you credited yourself in main.c and board_init.c but not in console.c, ethernet_phy.c/h, CMakeLists.txt, the cmake modules, or the scripts. Please add yourself to everything you touched. Also, new-file headers here should read "Eclipse ThreadX contributors" — console.c says "Eclipse Foundation", inherited from the original.
  • Commit style: our short descriptions start with a past-tense verb, so "Added the STM32 NUCLEO-F429ZI sample". And the PR body says F676 where it means F767. 😄

None of this is hard to fix and the foundation is solid. Looking forward to the USBX one as a separate PR.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes-requested to reflect the state accurately — the details are in my review just above. The three blockers are the Linux build break in FindSTM32HAL.cmake, the -mfpu=fpv5-d16 Cortex-M7 flag on an M4, and the destructive __HAL_UART_CLEAR_PEFLAG read in USART3_IRQHandler. Retargeting onto dev is the other must-do. Happy to re-review as soon as you've had a pass at them.

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It
uses the same tasks and IO but for STM32F4 peripherals.
@Jaxc

Jaxc commented Aug 31, 2026

Copy link
Copy Markdown
Author

I fixed most things, and pushed just for me to check how it looks now. I will do another amend to fix the last things.

This brings me to:

How should I update the NOTICE.md? Some files was copied from F767 and it doesn't have the needed info there either :)

Oh and about the .svd: It feels a bit wrong to add it to the fetch_sdk as it is "optional". But it also feels a bit redundant to add a new script to fetch only that file. But maybe there are more optional debug focused files that could be fetched? For now I removed the file from the commit

@Jaxc
Jaxc changed the base branch from main to devAugust 31, 2026 15:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants

@Jaxc@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add STM32 NUCLEO-F429ZI sample - #47

Open
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI
Open

Add STM32 NUCLEO-F429ZI sample#47
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI

Conversation

@Jaxc

@JaxcJaxc commented Aug 5, 2026

Copy link
Copy Markdown

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It uses the same tasks and IO but for STM32F4 peripherals.

@Jaxc

Jaxc commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hello

I've been wanting to try out ThreadX but didn't know where to start. So I though I could "Port" a sample to a new devboard as that could be helpful to someone.

I also added some extras that I found useful in the tools folder, but I'm very unsure if they should be merged or not.

@Jaxc
Jaxcforce-pushed the Nucleo-F429ZI branch 2 times, most recently from ba1a16d to 2082837CompareAugust 7, 2026 15:11
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Jaxc.

Thank you for this contribution! I somehow did not notice your PR before today. I will review it this week. Thanks again!

@fdesbiensfdesbiens self-assigned this Aug 24, 2026
@fdesbiensfdesbiens moved this to In review in ThreadX RoadmapAug 24, 2026
@fdesbiens
fdesbiens self-requested a review August 24, 2026 18:25
@Jaxc

Jaxc commented Aug 25, 2026

Copy link
Copy Markdown
Author

Hello @fdesbiens

Absolutely no worries!

I also pushed my code a bit further and managed to get USBx up with a MSC device. I plan to push that too but it needs cleanup. Would you want that as a separate PR or should I amend this one?

@fdesbiens

Copy link
Copy Markdown
Contributor

Thank you, @Jaxc. I would prefer a separate PR. I will aim to review this one today.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaxc — thanks again for this, and sorry for the slow start. I checked it out and built it locally, and the overall shape is good: the port is faithful, the console/ring-buffer thread is a nice touch, and it compiles with -Werror and no warnings once one path is fixed. A few things to sort out before I can merge.

Three things that need fixing

1. The build doesn't configure on Linux. In cmake/FindSTM32HAL.cmake, the find_path hint on line 70 is Drivers/stm32${STM32_FAMILY}xx_hal_Driver/Inc (lowercase stm32), but fetch_sdk.sh creates Drivers/STM32F4xx_hal_Driver. CMake bails with Could NOT find STM32HAL (missing: STM32HAL_INCLUDE_DIR). It only works on Windows because NTFS is case-insensitive. Could you align everything on STM32F4xx_HAL_Driver — both HINTS lines, fetch_sdk.sh, and fetch_sdk.ps1? That's the spelling both STM32F767ZI-Nucleo and NUCLEO_F401RE already use. With just that change the build finishes cleanly here (GCC 13.2, CMake 4.4, Ninja).

2. Wrong FPU for the part.cmake/arm-gcc-cortex-m4.cmake sets -mfpu=fpv5-d16, which is the Cortex-M7 unit — that got carried over from the F767 toolchain file. The F429's Cortex-M4F has FPv4-SP-D16, single precision only. GCC accepts -mcpu=cortex-m4 -mfpu=fpv5-d16 without complaint and will happily emit vdiv.f64, which the hardware doesn't implement. The current demo contains no double-precision instructions so it won't fault today, but readelf -A on the ELF does report Tag_FP_arch: FPv5/FP-D16 for ARMv8, and the first bit of double math anyone adds would hard-fault. Please use -mfpu=fpv4-sp-d16NUCLEO_F401RE already does.

3. The __HAL_UART_CLEAR_PEFLAG call in USART3_IRQHandler drops characters. This one is subtle and entirely the F7's fault. On the F7 that macro writes to ICR. On the F4 it expands to a read of SR followed by a read of DR — a destructive read. Since it runs unconditionally at the end of every interrupt, any byte that arrives between your RXNE read and that line gets consumed and thrown away, and no further interrupt fires for it. Rare at 115200, but real. I'd handle the error flags explicitly instead, e.g. only run the SR/DR clear sequence when ORE/FE/NE/PE is actually set, and push the recovered byte into the ring buffer.

Please retarget to dev

We take PRs against dev rather than main. That matters more than usual here: dev has a refactored F767 sample that moved the app into app/demos/<demo>/ with an ACTIVE_DEMO CMake cache variable and now carries a NetX Duo echo demo and a network station demo. So the layout you copied from main no longer exists upstream. Rebasing onto dev and matching that structure (app/demos/threadx_basic/main.c) would save us a painful reconciliation later — and it's the structure your USBX demo will want to slot into anyway.

Dead hardware init

ethernet_phy_init() and MX_USB_OTG_FS_PCD_Init() are both commented out in board_init(), MPU_Config() is declared but never defined or called, and ethernet_phy.c is compiled but unreachable. Its .RxDecripSection / .TxDecripSection descriptors aren't in the linker script either — that only goes unnoticed because --gc-sections discards them. For this PR I'd drop ethernet_phy.c, the eth component from find_package, and HAL_ETH_MODULE_ENABLED / HAL_PCD_MODULE_ENABLED from stm32f4xx_hal_conf.h, then bring Ethernet in properly when there's a demo that uses it. (Some of this is inherited from the F767 original — not your doing, but I'd rather not propagate it to a third board.)

On the tools/ folder — you asked, so:

  • The .ioc I'd definitely keep. None of the other boards have one, and documenting how the pin configuration was produced is genuinely useful. Good precedent to set.
  • The Ozone .jdebug I'm happy to take too. I checked and it only uses relative paths (./STM32F429.svd, ../build/stm32f429_threadx.elf), so it's portable. Please add a line about it to the README so people know it's there.
  • The 2.1 MB STM32F429.svd is the one I'd rather not commit. It's not reachable from any build, and most people get it from their IDE or ST's CMSIS pack. Could you fetch it in fetch_sdk.sh alongside the HAL and CMSIS clones instead? If that turns out to be awkward, I won't block the PR over it — but then it needs a NOTICE entry.

Which brings me to: NOTICE.md needs updating for the third-party files this PR vendors in. The SVD is ST, Apache-2.0. The .jdebug is SEGGER. And the CubeIDE-generated files committed under app/syscalls.c, sysmem.c, startup_stm32f429xx.s, system_stm32f4xx.c, main.h, and the linker script — all carry ST copyright with no accompanying licence text. Right now NOTICE only covers the components fetch_sdk.sh downloads.

Smaller things

  • board_init(): the comment above SystemClock_Config() still says "Configure the system clock to 216 MHz". It's 168.
  • README: the binary is build/stm32f429_threadx.bin, not stm32F429_threadx.bin — the capital F will send Linux users looking for a file that isn't there.
  • README: 250 ms on plus 250 ms off is a 1 Hz blink (2 Hz toggle rate). Worth rewording.
  • MX_GPIO_Init() configures the user button as GPIO_MODE_IT_RISING, but the EXTI line is never enabled and the button is polled. GPIO_MODE_INPUT is what you want.
  • int __io_getchar(void); is declared in main.c and never used.
  • Three threads call printf concurrently and it funnels into an unguarded HAL_UART_Transmit, so output can interleave. Same in the F767 sample, so not a blocker — but a TX_MUTEX around the console would be a real improvement if you feel like it.
  • Header attribution: you credited yourself in main.c and board_init.c but not in console.c, ethernet_phy.c/h, CMakeLists.txt, the cmake modules, or the scripts. Please add yourself to everything you touched. Also, new-file headers here should read "Eclipse ThreadX contributors" — console.c says "Eclipse Foundation", inherited from the original.
  • Commit style: our short descriptions start with a past-tense verb, so "Added the STM32 NUCLEO-F429ZI sample". And the PR body says F676 where it means F767. 😄

None of this is hard to fix and the foundation is solid. Looking forward to the USBX one as a separate PR.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes-requested to reflect the state accurately — the details are in my review just above. The three blockers are the Linux build break in FindSTM32HAL.cmake, the -mfpu=fpv5-d16 Cortex-M7 flag on an M4, and the destructive __HAL_UART_CLEAR_PEFLAG read in USART3_IRQHandler. Retargeting onto dev is the other must-do. Happy to re-review as soon as you've had a pass at them.

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It
uses the same tasks and IO but for STM32F4 peripherals.
@Jaxc

Jaxc commented Aug 31, 2026

Copy link
Copy Markdown
Author

I fixed most things, and pushed just for me to check how it looks now. I will do another amend to fix the last things.

This brings me to:

How should I update the NOTICE.md? Some files was copied from F767 and it doesn't have the needed info there either :)

Oh and about the .svd: It feels a bit wrong to add it to the fetch_sdk as it is "optional". But it also feels a bit redundant to add a new script to fetch only that file. But maybe there are more optional debug focused files that could be fetched? For now I removed the file from the commit

@Jaxc
Jaxc changed the base branch from main to devAugust 31, 2026 15:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants

@Jaxc@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add STM32 NUCLEO-F429ZI sample - #47

Open
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI
Open

Add STM32 NUCLEO-F429ZI sample#47
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI

Conversation

@Jaxc

@JaxcJaxc commented Aug 5, 2026

Copy link
Copy Markdown

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It uses the same tasks and IO but for STM32F4 peripherals.

@Jaxc

Jaxc commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hello

I've been wanting to try out ThreadX but didn't know where to start. So I though I could "Port" a sample to a new devboard as that could be helpful to someone.

I also added some extras that I found useful in the tools folder, but I'm very unsure if they should be merged or not.

@Jaxc
Jaxcforce-pushed the Nucleo-F429ZI branch 2 times, most recently from ba1a16d to 2082837CompareAugust 7, 2026 15:11
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Jaxc.

Thank you for this contribution! I somehow did not notice your PR before today. I will review it this week. Thanks again!

@fdesbiensfdesbiens self-assigned this Aug 24, 2026
@fdesbiensfdesbiens moved this to In review in ThreadX RoadmapAug 24, 2026
@fdesbiens
fdesbiens self-requested a review August 24, 2026 18:25
@Jaxc

Jaxc commented Aug 25, 2026

Copy link
Copy Markdown
Author

Hello @fdesbiens

Absolutely no worries!

I also pushed my code a bit further and managed to get USBx up with a MSC device. I plan to push that too but it needs cleanup. Would you want that as a separate PR or should I amend this one?

@fdesbiens

Copy link
Copy Markdown
Contributor

Thank you, @Jaxc. I would prefer a separate PR. I will aim to review this one today.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaxc — thanks again for this, and sorry for the slow start. I checked it out and built it locally, and the overall shape is good: the port is faithful, the console/ring-buffer thread is a nice touch, and it compiles with -Werror and no warnings once one path is fixed. A few things to sort out before I can merge.

Three things that need fixing

1. The build doesn't configure on Linux. In cmake/FindSTM32HAL.cmake, the find_path hint on line 70 is Drivers/stm32${STM32_FAMILY}xx_hal_Driver/Inc (lowercase stm32), but fetch_sdk.sh creates Drivers/STM32F4xx_hal_Driver. CMake bails with Could NOT find STM32HAL (missing: STM32HAL_INCLUDE_DIR). It only works on Windows because NTFS is case-insensitive. Could you align everything on STM32F4xx_HAL_Driver — both HINTS lines, fetch_sdk.sh, and fetch_sdk.ps1? That's the spelling both STM32F767ZI-Nucleo and NUCLEO_F401RE already use. With just that change the build finishes cleanly here (GCC 13.2, CMake 4.4, Ninja).

2. Wrong FPU for the part.cmake/arm-gcc-cortex-m4.cmake sets -mfpu=fpv5-d16, which is the Cortex-M7 unit — that got carried over from the F767 toolchain file. The F429's Cortex-M4F has FPv4-SP-D16, single precision only. GCC accepts -mcpu=cortex-m4 -mfpu=fpv5-d16 without complaint and will happily emit vdiv.f64, which the hardware doesn't implement. The current demo contains no double-precision instructions so it won't fault today, but readelf -A on the ELF does report Tag_FP_arch: FPv5/FP-D16 for ARMv8, and the first bit of double math anyone adds would hard-fault. Please use -mfpu=fpv4-sp-d16NUCLEO_F401RE already does.

3. The __HAL_UART_CLEAR_PEFLAG call in USART3_IRQHandler drops characters. This one is subtle and entirely the F7's fault. On the F7 that macro writes to ICR. On the F4 it expands to a read of SR followed by a read of DR — a destructive read. Since it runs unconditionally at the end of every interrupt, any byte that arrives between your RXNE read and that line gets consumed and thrown away, and no further interrupt fires for it. Rare at 115200, but real. I'd handle the error flags explicitly instead, e.g. only run the SR/DR clear sequence when ORE/FE/NE/PE is actually set, and push the recovered byte into the ring buffer.

Please retarget to dev

We take PRs against dev rather than main. That matters more than usual here: dev has a refactored F767 sample that moved the app into app/demos/<demo>/ with an ACTIVE_DEMO CMake cache variable and now carries a NetX Duo echo demo and a network station demo. So the layout you copied from main no longer exists upstream. Rebasing onto dev and matching that structure (app/demos/threadx_basic/main.c) would save us a painful reconciliation later — and it's the structure your USBX demo will want to slot into anyway.

Dead hardware init

ethernet_phy_init() and MX_USB_OTG_FS_PCD_Init() are both commented out in board_init(), MPU_Config() is declared but never defined or called, and ethernet_phy.c is compiled but unreachable. Its .RxDecripSection / .TxDecripSection descriptors aren't in the linker script either — that only goes unnoticed because --gc-sections discards them. For this PR I'd drop ethernet_phy.c, the eth component from find_package, and HAL_ETH_MODULE_ENABLED / HAL_PCD_MODULE_ENABLED from stm32f4xx_hal_conf.h, then bring Ethernet in properly when there's a demo that uses it. (Some of this is inherited from the F767 original — not your doing, but I'd rather not propagate it to a third board.)

On the tools/ folder — you asked, so:

  • The .ioc I'd definitely keep. None of the other boards have one, and documenting how the pin configuration was produced is genuinely useful. Good precedent to set.
  • The Ozone .jdebug I'm happy to take too. I checked and it only uses relative paths (./STM32F429.svd, ../build/stm32f429_threadx.elf), so it's portable. Please add a line about it to the README so people know it's there.
  • The 2.1 MB STM32F429.svd is the one I'd rather not commit. It's not reachable from any build, and most people get it from their IDE or ST's CMSIS pack. Could you fetch it in fetch_sdk.sh alongside the HAL and CMSIS clones instead? If that turns out to be awkward, I won't block the PR over it — but then it needs a NOTICE entry.

Which brings me to: NOTICE.md needs updating for the third-party files this PR vendors in. The SVD is ST, Apache-2.0. The .jdebug is SEGGER. And the CubeIDE-generated files committed under app/syscalls.c, sysmem.c, startup_stm32f429xx.s, system_stm32f4xx.c, main.h, and the linker script — all carry ST copyright with no accompanying licence text. Right now NOTICE only covers the components fetch_sdk.sh downloads.

Smaller things

  • board_init(): the comment above SystemClock_Config() still says "Configure the system clock to 216 MHz". It's 168.
  • README: the binary is build/stm32f429_threadx.bin, not stm32F429_threadx.bin — the capital F will send Linux users looking for a file that isn't there.
  • README: 250 ms on plus 250 ms off is a 1 Hz blink (2 Hz toggle rate). Worth rewording.
  • MX_GPIO_Init() configures the user button as GPIO_MODE_IT_RISING, but the EXTI line is never enabled and the button is polled. GPIO_MODE_INPUT is what you want.
  • int __io_getchar(void); is declared in main.c and never used.
  • Three threads call printf concurrently and it funnels into an unguarded HAL_UART_Transmit, so output can interleave. Same in the F767 sample, so not a blocker — but a TX_MUTEX around the console would be a real improvement if you feel like it.
  • Header attribution: you credited yourself in main.c and board_init.c but not in console.c, ethernet_phy.c/h, CMakeLists.txt, the cmake modules, or the scripts. Please add yourself to everything you touched. Also, new-file headers here should read "Eclipse ThreadX contributors" — console.c says "Eclipse Foundation", inherited from the original.
  • Commit style: our short descriptions start with a past-tense verb, so "Added the STM32 NUCLEO-F429ZI sample". And the PR body says F676 where it means F767. 😄

None of this is hard to fix and the foundation is solid. Looking forward to the USBX one as a separate PR.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes-requested to reflect the state accurately — the details are in my review just above. The three blockers are the Linux build break in FindSTM32HAL.cmake, the -mfpu=fpv5-d16 Cortex-M7 flag on an M4, and the destructive __HAL_UART_CLEAR_PEFLAG read in USART3_IRQHandler. Retargeting onto dev is the other must-do. Happy to re-review as soon as you've had a pass at them.

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It
uses the same tasks and IO but for STM32F4 peripherals.
@Jaxc

Jaxc commented Aug 31, 2026

Copy link
Copy Markdown
Author

I fixed most things, and pushed just for me to check how it looks now. I will do another amend to fix the last things.

This brings me to:

How should I update the NOTICE.md? Some files was copied from F767 and it doesn't have the needed info there either :)

Oh and about the .svd: It feels a bit wrong to add it to the fetch_sdk as it is "optional". But it also feels a bit redundant to add a new script to fetch only that file. But maybe there are more optional debug focused files that could be fetched? For now I removed the file from the commit

@Jaxc
Jaxc changed the base branch from main to devAugust 31, 2026 15:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants

@Jaxc@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add STM32 NUCLEO-F429ZI sample - #47

Open
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI
Open

Add STM32 NUCLEO-F429ZI sample#47
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI

Conversation

@Jaxc

@JaxcJaxc commented Aug 5, 2026

Copy link
Copy Markdown

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It uses the same tasks and IO but for STM32F4 peripherals.

@Jaxc

Jaxc commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hello

I've been wanting to try out ThreadX but didn't know where to start. So I though I could "Port" a sample to a new devboard as that could be helpful to someone.

I also added some extras that I found useful in the tools folder, but I'm very unsure if they should be merged or not.

@Jaxc
Jaxcforce-pushed the Nucleo-F429ZI branch 2 times, most recently from ba1a16d to 2082837CompareAugust 7, 2026 15:11
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Jaxc.

Thank you for this contribution! I somehow did not notice your PR before today. I will review it this week. Thanks again!

@fdesbiensfdesbiens self-assigned this Aug 24, 2026
@fdesbiensfdesbiens moved this to In review in ThreadX RoadmapAug 24, 2026
@fdesbiens
fdesbiens self-requested a review August 24, 2026 18:25
@Jaxc

Jaxc commented Aug 25, 2026

Copy link
Copy Markdown
Author

Hello @fdesbiens

Absolutely no worries!

I also pushed my code a bit further and managed to get USBx up with a MSC device. I plan to push that too but it needs cleanup. Would you want that as a separate PR or should I amend this one?

@fdesbiens

Copy link
Copy Markdown
Contributor

Thank you, @Jaxc. I would prefer a separate PR. I will aim to review this one today.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaxc — thanks again for this, and sorry for the slow start. I checked it out and built it locally, and the overall shape is good: the port is faithful, the console/ring-buffer thread is a nice touch, and it compiles with -Werror and no warnings once one path is fixed. A few things to sort out before I can merge.

Three things that need fixing

1. The build doesn't configure on Linux. In cmake/FindSTM32HAL.cmake, the find_path hint on line 70 is Drivers/stm32${STM32_FAMILY}xx_hal_Driver/Inc (lowercase stm32), but fetch_sdk.sh creates Drivers/STM32F4xx_hal_Driver. CMake bails with Could NOT find STM32HAL (missing: STM32HAL_INCLUDE_DIR). It only works on Windows because NTFS is case-insensitive. Could you align everything on STM32F4xx_HAL_Driver — both HINTS lines, fetch_sdk.sh, and fetch_sdk.ps1? That's the spelling both STM32F767ZI-Nucleo and NUCLEO_F401RE already use. With just that change the build finishes cleanly here (GCC 13.2, CMake 4.4, Ninja).

2. Wrong FPU for the part.cmake/arm-gcc-cortex-m4.cmake sets -mfpu=fpv5-d16, which is the Cortex-M7 unit — that got carried over from the F767 toolchain file. The F429's Cortex-M4F has FPv4-SP-D16, single precision only. GCC accepts -mcpu=cortex-m4 -mfpu=fpv5-d16 without complaint and will happily emit vdiv.f64, which the hardware doesn't implement. The current demo contains no double-precision instructions so it won't fault today, but readelf -A on the ELF does report Tag_FP_arch: FPv5/FP-D16 for ARMv8, and the first bit of double math anyone adds would hard-fault. Please use -mfpu=fpv4-sp-d16NUCLEO_F401RE already does.

3. The __HAL_UART_CLEAR_PEFLAG call in USART3_IRQHandler drops characters. This one is subtle and entirely the F7's fault. On the F7 that macro writes to ICR. On the F4 it expands to a read of SR followed by a read of DR — a destructive read. Since it runs unconditionally at the end of every interrupt, any byte that arrives between your RXNE read and that line gets consumed and thrown away, and no further interrupt fires for it. Rare at 115200, but real. I'd handle the error flags explicitly instead, e.g. only run the SR/DR clear sequence when ORE/FE/NE/PE is actually set, and push the recovered byte into the ring buffer.

Please retarget to dev

We take PRs against dev rather than main. That matters more than usual here: dev has a refactored F767 sample that moved the app into app/demos/<demo>/ with an ACTIVE_DEMO CMake cache variable and now carries a NetX Duo echo demo and a network station demo. So the layout you copied from main no longer exists upstream. Rebasing onto dev and matching that structure (app/demos/threadx_basic/main.c) would save us a painful reconciliation later — and it's the structure your USBX demo will want to slot into anyway.

Dead hardware init

ethernet_phy_init() and MX_USB_OTG_FS_PCD_Init() are both commented out in board_init(), MPU_Config() is declared but never defined or called, and ethernet_phy.c is compiled but unreachable. Its .RxDecripSection / .TxDecripSection descriptors aren't in the linker script either — that only goes unnoticed because --gc-sections discards them. For this PR I'd drop ethernet_phy.c, the eth component from find_package, and HAL_ETH_MODULE_ENABLED / HAL_PCD_MODULE_ENABLED from stm32f4xx_hal_conf.h, then bring Ethernet in properly when there's a demo that uses it. (Some of this is inherited from the F767 original — not your doing, but I'd rather not propagate it to a third board.)

On the tools/ folder — you asked, so:

  • The .ioc I'd definitely keep. None of the other boards have one, and documenting how the pin configuration was produced is genuinely useful. Good precedent to set.
  • The Ozone .jdebug I'm happy to take too. I checked and it only uses relative paths (./STM32F429.svd, ../build/stm32f429_threadx.elf), so it's portable. Please add a line about it to the README so people know it's there.
  • The 2.1 MB STM32F429.svd is the one I'd rather not commit. It's not reachable from any build, and most people get it from their IDE or ST's CMSIS pack. Could you fetch it in fetch_sdk.sh alongside the HAL and CMSIS clones instead? If that turns out to be awkward, I won't block the PR over it — but then it needs a NOTICE entry.

Which brings me to: NOTICE.md needs updating for the third-party files this PR vendors in. The SVD is ST, Apache-2.0. The .jdebug is SEGGER. And the CubeIDE-generated files committed under app/syscalls.c, sysmem.c, startup_stm32f429xx.s, system_stm32f4xx.c, main.h, and the linker script — all carry ST copyright with no accompanying licence text. Right now NOTICE only covers the components fetch_sdk.sh downloads.

Smaller things

  • board_init(): the comment above SystemClock_Config() still says "Configure the system clock to 216 MHz". It's 168.
  • README: the binary is build/stm32f429_threadx.bin, not stm32F429_threadx.bin — the capital F will send Linux users looking for a file that isn't there.
  • README: 250 ms on plus 250 ms off is a 1 Hz blink (2 Hz toggle rate). Worth rewording.
  • MX_GPIO_Init() configures the user button as GPIO_MODE_IT_RISING, but the EXTI line is never enabled and the button is polled. GPIO_MODE_INPUT is what you want.
  • int __io_getchar(void); is declared in main.c and never used.
  • Three threads call printf concurrently and it funnels into an unguarded HAL_UART_Transmit, so output can interleave. Same in the F767 sample, so not a blocker — but a TX_MUTEX around the console would be a real improvement if you feel like it.
  • Header attribution: you credited yourself in main.c and board_init.c but not in console.c, ethernet_phy.c/h, CMakeLists.txt, the cmake modules, or the scripts. Please add yourself to everything you touched. Also, new-file headers here should read "Eclipse ThreadX contributors" — console.c says "Eclipse Foundation", inherited from the original.
  • Commit style: our short descriptions start with a past-tense verb, so "Added the STM32 NUCLEO-F429ZI sample". And the PR body says F676 where it means F767. 😄

None of this is hard to fix and the foundation is solid. Looking forward to the USBX one as a separate PR.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes-requested to reflect the state accurately — the details are in my review just above. The three blockers are the Linux build break in FindSTM32HAL.cmake, the -mfpu=fpv5-d16 Cortex-M7 flag on an M4, and the destructive __HAL_UART_CLEAR_PEFLAG read in USART3_IRQHandler. Retargeting onto dev is the other must-do. Happy to re-review as soon as you've had a pass at them.

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It
uses the same tasks and IO but for STM32F4 peripherals.
@Jaxc

Jaxc commented Aug 31, 2026

Copy link
Copy Markdown
Author

I fixed most things, and pushed just for me to check how it looks now. I will do another amend to fix the last things.

This brings me to:

How should I update the NOTICE.md? Some files was copied from F767 and it doesn't have the needed info there either :)

Oh and about the .svd: It feels a bit wrong to add it to the fetch_sdk as it is "optional". But it also feels a bit redundant to add a new script to fetch only that file. But maybe there are more optional debug focused files that could be fetched? For now I removed the file from the commit

@Jaxc
Jaxc changed the base branch from main to devAugust 31, 2026 15:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants

@Jaxc@fdesbiens
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add STM32 NUCLEO-F429ZI sample - #47

Open
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI
Open

Add STM32 NUCLEO-F429ZI sample#47
Jaxc wants to merge 1 commit into
eclipse-threadx:devfrom
Jaxc:Nucleo-F429ZI

Conversation

@Jaxc

@JaxcJaxc commented Aug 5, 2026

Copy link
Copy Markdown

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It uses the same tasks and IO but for STM32F4 peripherals.

@Jaxc

Jaxc commented Aug 5, 2026

Copy link
Copy Markdown
Author

Hello

I've been wanting to try out ThreadX but didn't know where to start. So I though I could "Port" a sample to a new devboard as that could be helpful to someone.

I also added some extras that I found useful in the tools folder, but I'm very unsure if they should be merged or not.

@Jaxc
Jaxcforce-pushed the Nucleo-F429ZI branch 2 times, most recently from ba1a16d to 2082837CompareAugust 7, 2026 15:11
@fdesbiens

Copy link
Copy Markdown
Contributor

Hi @Jaxc.

Thank you for this contribution! I somehow did not notice your PR before today. I will review it this week. Thanks again!

@fdesbiensfdesbiens self-assigned this Aug 24, 2026
@fdesbiensfdesbiens moved this to In review in ThreadX RoadmapAug 24, 2026
@fdesbiens
fdesbiens self-requested a review August 24, 2026 18:25
@Jaxc

Jaxc commented Aug 25, 2026

Copy link
Copy Markdown
Author

Hello @fdesbiens

Absolutely no worries!

I also pushed my code a bit further and managed to get USBx up with a MSC device. I plan to push that too but it needs cleanup. Would you want that as a separate PR or should I amend this one?

@fdesbiens

Copy link
Copy Markdown
Contributor

Thank you, @Jaxc. I would prefer a separate PR. I will aim to review this one today.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Jaxc — thanks again for this, and sorry for the slow start. I checked it out and built it locally, and the overall shape is good: the port is faithful, the console/ring-buffer thread is a nice touch, and it compiles with -Werror and no warnings once one path is fixed. A few things to sort out before I can merge.

Three things that need fixing

1. The build doesn't configure on Linux. In cmake/FindSTM32HAL.cmake, the find_path hint on line 70 is Drivers/stm32${STM32_FAMILY}xx_hal_Driver/Inc (lowercase stm32), but fetch_sdk.sh creates Drivers/STM32F4xx_hal_Driver. CMake bails with Could NOT find STM32HAL (missing: STM32HAL_INCLUDE_DIR). It only works on Windows because NTFS is case-insensitive. Could you align everything on STM32F4xx_HAL_Driver — both HINTS lines, fetch_sdk.sh, and fetch_sdk.ps1? That's the spelling both STM32F767ZI-Nucleo and NUCLEO_F401RE already use. With just that change the build finishes cleanly here (GCC 13.2, CMake 4.4, Ninja).

2. Wrong FPU for the part.cmake/arm-gcc-cortex-m4.cmake sets -mfpu=fpv5-d16, which is the Cortex-M7 unit — that got carried over from the F767 toolchain file. The F429's Cortex-M4F has FPv4-SP-D16, single precision only. GCC accepts -mcpu=cortex-m4 -mfpu=fpv5-d16 without complaint and will happily emit vdiv.f64, which the hardware doesn't implement. The current demo contains no double-precision instructions so it won't fault today, but readelf -A on the ELF does report Tag_FP_arch: FPv5/FP-D16 for ARMv8, and the first bit of double math anyone adds would hard-fault. Please use -mfpu=fpv4-sp-d16NUCLEO_F401RE already does.

3. The __HAL_UART_CLEAR_PEFLAG call in USART3_IRQHandler drops characters. This one is subtle and entirely the F7's fault. On the F7 that macro writes to ICR. On the F4 it expands to a read of SR followed by a read of DR — a destructive read. Since it runs unconditionally at the end of every interrupt, any byte that arrives between your RXNE read and that line gets consumed and thrown away, and no further interrupt fires for it. Rare at 115200, but real. I'd handle the error flags explicitly instead, e.g. only run the SR/DR clear sequence when ORE/FE/NE/PE is actually set, and push the recovered byte into the ring buffer.

Please retarget to dev

We take PRs against dev rather than main. That matters more than usual here: dev has a refactored F767 sample that moved the app into app/demos/<demo>/ with an ACTIVE_DEMO CMake cache variable and now carries a NetX Duo echo demo and a network station demo. So the layout you copied from main no longer exists upstream. Rebasing onto dev and matching that structure (app/demos/threadx_basic/main.c) would save us a painful reconciliation later — and it's the structure your USBX demo will want to slot into anyway.

Dead hardware init

ethernet_phy_init() and MX_USB_OTG_FS_PCD_Init() are both commented out in board_init(), MPU_Config() is declared but never defined or called, and ethernet_phy.c is compiled but unreachable. Its .RxDecripSection / .TxDecripSection descriptors aren't in the linker script either — that only goes unnoticed because --gc-sections discards them. For this PR I'd drop ethernet_phy.c, the eth component from find_package, and HAL_ETH_MODULE_ENABLED / HAL_PCD_MODULE_ENABLED from stm32f4xx_hal_conf.h, then bring Ethernet in properly when there's a demo that uses it. (Some of this is inherited from the F767 original — not your doing, but I'd rather not propagate it to a third board.)

On the tools/ folder — you asked, so:

  • The .ioc I'd definitely keep. None of the other boards have one, and documenting how the pin configuration was produced is genuinely useful. Good precedent to set.
  • The Ozone .jdebug I'm happy to take too. I checked and it only uses relative paths (./STM32F429.svd, ../build/stm32f429_threadx.elf), so it's portable. Please add a line about it to the README so people know it's there.
  • The 2.1 MB STM32F429.svd is the one I'd rather not commit. It's not reachable from any build, and most people get it from their IDE or ST's CMSIS pack. Could you fetch it in fetch_sdk.sh alongside the HAL and CMSIS clones instead? If that turns out to be awkward, I won't block the PR over it — but then it needs a NOTICE entry.

Which brings me to: NOTICE.md needs updating for the third-party files this PR vendors in. The SVD is ST, Apache-2.0. The .jdebug is SEGGER. And the CubeIDE-generated files committed under app/syscalls.c, sysmem.c, startup_stm32f429xx.s, system_stm32f4xx.c, main.h, and the linker script — all carry ST copyright with no accompanying licence text. Right now NOTICE only covers the components fetch_sdk.sh downloads.

Smaller things

  • board_init(): the comment above SystemClock_Config() still says "Configure the system clock to 216 MHz". It's 168.
  • README: the binary is build/stm32f429_threadx.bin, not stm32F429_threadx.bin — the capital F will send Linux users looking for a file that isn't there.
  • README: 250 ms on plus 250 ms off is a 1 Hz blink (2 Hz toggle rate). Worth rewording.
  • MX_GPIO_Init() configures the user button as GPIO_MODE_IT_RISING, but the EXTI line is never enabled and the button is polled. GPIO_MODE_INPUT is what you want.
  • int __io_getchar(void); is declared in main.c and never used.
  • Three threads call printf concurrently and it funnels into an unguarded HAL_UART_Transmit, so output can interleave. Same in the F767 sample, so not a blocker — but a TX_MUTEX around the console would be a real improvement if you feel like it.
  • Header attribution: you credited yourself in main.c and board_init.c but not in console.c, ethernet_phy.c/h, CMakeLists.txt, the cmake modules, or the scripts. Please add yourself to everything you touched. Also, new-file headers here should read "Eclipse ThreadX contributors" — console.c says "Eclipse Foundation", inherited from the original.
  • Commit style: our short descriptions start with a past-tense verb, so "Added the STM32 NUCLEO-F429ZI sample". And the PR body says F676 where it means F767. 😄

None of this is hard to fix and the foundation is solid. Looking forward to the USBX one as a separate PR.

@fdesbiensfdesbiens left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Marking this as changes-requested to reflect the state accurately — the details are in my review just above. The three blockers are the Linux build break in FindSTM32HAL.cmake, the -mfpu=fpv5-d16 Cortex-M7 flag on an M4, and the destructive __HAL_UART_CLEAR_PEFLAG read in USART3_IRQHandler. Retargeting onto dev is the other must-do. Happy to re-review as soon as you've had a pass at them.

Basically a copy of the STM32F676 implementation for the NUCLEO-F429ZI. It
uses the same tasks and IO but for STM32F4 peripherals.
@Jaxc

Jaxc commented Aug 31, 2026

Copy link
Copy Markdown
Author

I fixed most things, and pushed just for me to check how it looks now. I will do another amend to fix the last things.

This brings me to:

How should I update the NOTICE.md? Some files was copied from F767 and it doesn't have the needed info there either :)

Oh and about the .svd: It feels a bit wrong to add it to the fetch_sdk as it is "optional". But it also feels a bit redundant to add a new script to fetch only that file. But maybe there are more optional debug focused files that could be fetched? For now I removed the file from the commit

@Jaxc
Jaxc changed the base branch from main to devAugust 31, 2026 15:24
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

2 participants

@Jaxc@fdesbiens