Getting started with ST NUCLEO F767ZI Board - hpaluch/hpaluch.github.io GitHub Wiki

Getting started with ST NUCLEO-F767ZI board

The NUCLEO-F767ZI is development board with STM32F767ZI belonging to ARM Cortex-M7 family. The board has integrated USB ST-LINK-v2 programmer/debugger (so you don't need to buy any) with additional virtual COM port and even Mass Storage.

I ordered my piece on Amazon.de to omit awful toll/tax paperwork if ordered overseas.

Please see STM32 Nucleo boards - Unified scalable offering for "bird-view" information.

NOTE: ARM Cortex has 3 major families:

  • Cortex-M - smallest one also called "microcontroller" or "deeply embedded". No OS support (because there is no MMU), however some may run RT OS.
  • Cortex-R - for Real-Time OS
  • Cortex-A - "application" level - includes OS support. This one is most likely to be in your mobile phone.

Setup

You need at least:

  • NUCLEO-F767ZI development board
  • PC Running Windows OS (tested Windows 10 Home N). I did not test Development environment under Linux.
  • micro-USB cable to connect board to PC (NOT included with board)
  • good Internet connection to download around 2GB of required software

Please start with Getting started with STM32 Nucleo board software development tools document for basic setup overview

Following steps are required to start development with Nucleo board:

  • download ST-Link driver for Windows
  • install ST Link drivers for Windows
  • verify boards Jumpers
  • connect board
  • download development environment
  • download sample project
  • build and run sample project

NOTE: If you become lost go to official NUCLEO-F767ZI as starting point.

Downloading ST-Link driver

NOTE: The driver should be installed prior connecting board to USB port to ensure that ST's driver was not overshadowed by some generic Windows driver.

  • Go to page STSW-LINK009
  • click on Get Software button at the bottom of page
  • you will be asked for your name and e-mail
  • once submitted you need to check your e-mail and click on Download link in your e-mail

2023 update: Now you need to register account on st.com to be able to download driver. Only logged-in users can download driver today.

You should get file en.stsw-link009.zip

Installing ST-Link drivers

  • Extract zip file en.stsw-link009.zip downloaded in previous section. Ensure that extraction path does NOT contains spaces.
  • Run batch launcher stlink_winusb_install.bat in CMD.exe with Elevated Privileges.
  • confirm everything.

It is also recommended to rather download and install en.st-link-server.zip

  • extracted file st-stlink-server.1.0.6-1.msi

WARNING! If you use AtlasOS mod, you may get "Error 2503". Please see https://forum.atlasos.net/d/555-fix-for-errors-2502-and-2503-with-installers for fix.

Verify board Jumpers

The jumpers should be already in right position but it is OK to double-check.

According to STM32 Nucleo-144 boards to section 5.1 Getting Started:

  • JP1 PWR-EXT - OFF (open)
  • JP3 ON - closed middle pin called U5V, other pins open
  • JP5 IDD ON
  • CN4 ON (there should be 2 jumpers closed)

Connect board to PC

Now there is the 1st moment of truth - connect your board to PC using micro-USB cable to connector CN1 on board (on small ST-Link board). Beware there is also "user" USB-connector CN3 that can be accessed from ARM CPU...

If everything is OK, you should see:

  • LED LD4 COM on (red light)
  • LED LD6 POWER on (green light)
  • user LED LD3 quickly blinking (red light)

If you press button B1 USER you can toggle one of LEDs:

  1. LED LD2 slowly blinking - blue light
  2. LED LD1 very slowly blinking - green light
  3. again LED LD3 quickly blinking - red light

Now it is right time to prepare development environment.

Development environment

There are many options (some of them has code size limitations etc.). You can generally follow Getting started with STM32 Nucleo board software development tools document with few exceptions.

I decided to try System Workbench for STM32 (also known as SW4STM32):

Installation:

  • run downloaded installer - install_sw4stm32_win_64bits-v2.7.exe in my example
  • accept everything with one exception:
    • uncheck ST-Link/V2 driver (we already installed it)

The installation should finish without error.

Unfortunately we are not done yet. We need to get sample project for our board - in next section...

Download sample projects

Please note that official guide in Getting started with STM32 Nucleo board software development tools is currently outdated - we need to download different files to get projects exactly for our NUCLEO-F767ZI.

Actually we need to:

2023 update:

  • I extracted en.stm32cubef7_v1-17-0.zip right into c:\Ac6 directory.
  • Then I extracted to same destination en.stm32cubef7-v1-17-1.zip. If you do it correctly it will ask to overwrite (updated) files - answer yes. Please note that folder name will be still c:\Ac6\STM32Cube_FW_F7_V1.17.0 (not 1.17.0) - which is good to remember

Importing sample project

Now we can basically follow Getting started with STM32 Nucleo board software development tools section 4.1.4 SW4STM32 toolchain

Briefly:

  • run System Workbench for STM32 from Windows menu or using shortcut on Desktop
  • confirm workspace creation (default path should be OK)
  • confirm Allow access on Windows Firewall question
  • wait until Installing ARM toolchain (Windows)... finishes.
  • close Welcome window (if you want to farewell to that Window then uncheck Always show Welcome at startup - in right-bottom)
  • right-click anywhere in Project Explorer window
  • click on Import...
  • select General -> Existing Projects into Workspace...
  • click on Next
  • in Select root directory browse to:
    c:\Ac6\STM32Cube_FW_F7_V1.17.0\Projects\STM32F767ZI-Nucleo\Examples\GPIO\GPIO_IOToggle\SW4STM32\STM32F767ZI-Nucleo
    
  • Do NOT check "copy project to workspace" it will break all relative paths in project and make it impossible to build it!
  • there should be automatically detected and checked project in Projects listbox
  • click on Finish

Fixing Eclipse errors

WARNING!

I encountered this problem only in 1 out of 2 installations. Currently I don't know what trigger these errors...

If you try to open in your project /STM32F767ZI-Nucleo/Example/User/main.c there will be soon shown errors. List of these errors is visible in Problem Window (note Eclipse call specific tab View instead of Window). In my example there are

Symbol 'uint32_t' could not be resolved	main.c
Type '__HAL_RCC_GPIOB_CLK_ENABLE()' could not be resolved	main.c
	                                                              

The problem is that Eclipse uses internal analyzer (called Indexer) which does not see some external (out of project) include files.

To find real cause of problem try:

  • right-click on project /STM32F767ZI-Nucleo
  • select Index -> Search for Unresolved includes
  • you should now see the cause in Window Search:
    Unresolved inclusion: stdint.h
    

We need to find where this header is located:

  • Use any suitable tool to search stdint.h
  • in my case (TotalCMD) I had found these candidates:
    X:\PREFIX\plugins\fr.ac6.mcu.externaltools.arm-none.win32_1.16.0.201807130628\tools\compiler\arm-none-eabi\include\stdint.h
    X:\PREFIX\plugins\fr.ac6.mcu.externaltools.arm-none.win32_1.16.0.201807130628\tools\compiler\arm-none-eabi\include\c++\7.2.1\tr1\stdint.h
    X:\PREFIX\plugins\fr.ac6.mcu.externaltools.arm-none.win32_1.16.0.201807130628\tools\compiler\lib\gcc\arm-none-eabi\7.2.1\include\stdint.h  
    

Where X:PREFIX is your intallation directory for your System Workbench for STM32.

The 1st one path looks most promising.

So we will need to add system directory with stdint.h to indexer path. Do this:

  • right-click on project /STM32F767ZI-Nucleo

  • select Properties

  • expand C/C++ General -> Paths and Symbols

  • select Languages -> GNU C

  • click on Add...

  • fill-in Directory: ${openstm32_compiler_path}/arm-none-eabi/include

    • Disclaimer: this path work for my version of environment, that is, for install_sw4stm32_win_64bits-v2.7.exe installer.

      If there appear warning about invalid path than you need to look in your filesystem and fix it.

  • check Add to all configurations

  • click on OK

  • click on main dialog OK

  • answer yes if asked for Rebuild

  • the errors should now be gone. And if you hover cursor - for example over GPIO_MODE_OUTPUT_PP macro - there should appear tooltip with definition.

Build and run sample project

Now we will try to build project according to manual:

  • in Project Explorer right-click our project and select Build project
  • or just click on "Hammer" icon on toolbar - it will do same
  • click on Console window
  • after a while there should be OK message Build Finished for example:
arm-none-eabi-objcopy -O binary "STM32F767ZI-Nucleo.elf" "STM32F767ZI-Nucleo.bin"
arm-none-eabi-size "STM32F767ZI-Nucleo.elf"
   text	   data	    bss	    dec	    hex	filename
   4424	     20	   1588	   6032	   1790	STM32F767ZI-Nucleo.elf

18:05:38 Build Finished (took 17s.541ms)

To run this project on target board you need to (manual does not work - yet!):

  • right-click our project in Project Explorer
  • select Target -> Program chip...
  • there should be correctly preselected just one binary and one qualifier
  • check the checkbox Reset after program

After successful programming you should see that now:

  • only LED LD1 is green blinking
  • there is no LED flipping on button B1 USER press (there is no code in this example)

Change our first project

To verify that we really re-programmed our board we can try to

  • modify Example\User\main.c code in Project Explorer that way:
      while (1)
    {
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
      /* Insert delay 100 ms */
      /* NOTE: change delay from 100 to 1000 below: */
      // HAL_Delay(100);
      HAL_Delay(1000);
    }
  • press Ctrl-S to save our changes
  • rebuild and reprogram your board as described in previous section

Outcome: you should now see that LED D1 is blinking 10-times slower.

Yes, that's it! Our first program!

Debugging our project

To successfully Run or Debug project in Eclipse one need to create so called Configuration. It is briefly described on Getting started with System Workbench for STM32 page (free registration/login required).

Disabling code optimisations: To succesfully debug compiled code it is necessary to turn off all optimisation otherwise Eclipse Debugger will be very likely confused on stepping code or displaying variables. Therefore:

  • right-click on your project
  • click on Properties
  • expand C/C++ Build -> Settings
  • click on MCU Gcc Compiler -> Optimization
  • select Optimization Level: None (-O0)
  • click on OK
  • on project's menu click on Clean project to ensure that all binaries are not optimized "out"

To create debug configuration do this:

  • in Eclipse menu click on Run -> Debug Configurations...
  • select AC6 STM32 Debugging
  • click on New icon (paper with + sign - tooltip New launch config.)
  • fill-in some suitable Name: - I used My-Nucleo
  • on Main tab (should be current) click on Search Project... button to search for future Debugged binary.
  • confirm the only item in Binaries: and Qualifier: listboxes and click on OK to close Search Project... dialog
  • also ensure that Enable auto build is selected - it is convenient
  • the error sign should now disappear

Now hold breath and click on Debug

  • the Eclipse will be now launching Debug configuration

WARNING!

I encountered the problem described below - only in 1 out of 2 installations. Currently I don't know what triggered these errors...

Ooops!!!! There are many errors like (detailed in Console view):

.../plugins/fr.ac6.mcu.externaltools.arm-none.win32_1.16.0.201807130628/tools/compiler/bin/../lib/gcc/arm-none-eabi/7.2.1/../../../../arm-none-eabi/bin/ld.exe: error: Drivers/BSP/STM32F767ZI-Nucleo/stm32f7xx_nucleo_144.o uses VFP register arguments, STM32F767ZI-Nucleo.elf does not
.../ld.exe: failed to merge target specific data of file Drivers/BSP/STM32F767ZI-Nucleo/stm32f7xx_nucleo_144.o
.../ld.exe: error: Drivers/CMSIS/system_stm32f7xx.o uses VFP register arguments, STM32F767ZI-Nucleo.elf does not
.../ld.exe: failed to merge target specific data of file Drivers/CMSIS/system_stm32f7xx.o
...
collect2.exe: error: ld returned 1 exit status

There is some vague hint at: http://www.openstm32.org/forumthread135 but we have very different situation - the system objects were not build with hard-float support...

The solution was surprisingly easy - bot NOT obvious:

  • right-click on your project
  • select Properties
  • select C/C++ Build -> Settings
  • select MCU Settings
  • AND NOW IT IS:
    • change Floating point hardware from none to only option fpv5-d16
  • click-on OK

Now ensure that you cleaned up project using:

  • right-click on your project
  • Clean project

Then start again Debug session and:

  • Confirm perspective switch and check Remember my decision
  • after a while you should see - Suspended an at main.c

Now you can for example:

  • place breakpoint at line:
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
  • and press F8 to resume execution
  • soon breakpoint will be reached at above line (and ST-Link diode will be flashing RED/GREEN quickly)
  • now watch LED LD1 and press F8 again
  • it should light now
  • press F8 to resume and it should light-off

Done :-)

When you want finish click on:

  • Terminate icon

Disconnecting board

Rather ensure that you terminated your Debug/Run session on board (ST-Link LED is not dual-light blinking).

Because ST-LINK-v2 provides Mass storage (drive letter) capability you should always use Windows's Safely remove Hardware ... in notification area prior disconnecting NUCLEO-F767ZI board.

Tips

Create diassembled code listing

It is possible to create complete disassembled code listing using standard GNU commands. In case of this Example project do this in CMD.exe:

cd /d "c:\Ac6\STM32Cube_FW_F7_V1.17.0\Projects\STM32F767ZI-Nucleo\Examples\GPIO\GPIO_IOToggle\SW4STM32\STM32F767ZI-Nucleo\Debug"
c:\Ac6\SystemWorkbench\plugins\fr.ac6.mcu.externaltools.arm-none.win32_1.17.0.201812190825\tools\compiler\bin\arm-none-eabi-objdump.exe ^
  -dS STM32F767ZI-Nucleo.elf > STM32F767ZI-Nucleo.lst

Listing is stored in file STM32F767ZI-Nucleo.lst. To see most important function main() search for <main>: in listing file.

Here is brief reduced example of main():

08000f68 <main>:
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
 8000f68:	b580      	push	{r7, lr}
 8000f6a:	b092      	sub	sp, #72	; 0x48
// ...
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 8001090:	f7ff fb7a 	bl	8000788 <HAL_GPIO_Init>
    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_0);
// here starts while(1){ ....
 8001094:	4620      	mov	r0, r4
 8001096:	2101      	movs	r1, #1
 8001098:	f7ff fc6a 	bl	8000970 <HAL_GPIO_TogglePin>
    HAL_Delay(100);
 800109c:	2064      	movs	r0, #100	; 0x64
 800109e:	f7ff fabd 	bl	800061c <HAL_Delay>
 80010a2:	e7f7      	b.n	8001094 <main+0x12c>
// ...

WARNING! Cortex-M assembler is pain (when compared to PIC), you will have to carefully study https://www.st.com/resource/en/programming_manual/pm0253-stm32f7-series-and-stm32h7-series-cortexm7-processor-programming-manual-stmicroelectronics.pdf to understand so many nuances and shortcuts.

Example:

  • there is no call instruction but rather bl (branch Link Register) which means TWO actions:
    • store return address (address of next instruction) to Link Register (also known as lr or r14)
    • jump to specified location
  • subprogram will push all clobbered registers including Link Register lr using push {...,lr}. It will serve 2 purposes:
    • allow calling another subprograms (using bl which will otherwise overwrite current lr value)
    • allow returning from this subprogram to correct address
  • instead of return instruction, program executes pop where last argument is stored bl value, but this time loaded to pc (program counter), for example: pop {...,pc}, pc is also known as r15
  • another thing is that set of pushed or pop-ed registers is always sorted - because it is encoded as bitmap. If you are really curious - read A7-242 of document https://documentation-service.arm.com/static/606dc36485368c4c2b1bf62f?token= called Armv7-M Architecture Reference Manual

Forcing instruction length:

  • even Thumb instructions sometimes comes in 2 variants: 16-bit and 32-bit
  • 16-bit version is forced using suffix .n, for example "short" branch:
    ; 2-bytes vvvv
    800034a:	e7dd      	b.n	8000308 <__udivmoddi4+0xa0>
    
  • WARNING! There also exists instruction bn LABEL which means "branch when N flag is set". So, it is very important to distinguish .n and plain n suffix!
  • 32-bit instruction is forced using suffix .w (WORD - on ARM WORD is 32-bit, and half-word H is 16-bit!), for example forcing "long" branch:
    ; 4 bytes vvvv vvvv
    800024c:	f000 b972 	b.w	8000534 <__aeabi_idiv0>
    

Operand size is (unfortunately) directly appended to instruction name, for example:

  • 16-bit operand (H - half-word)
    800038e:	b2a3      	uxth	r3, r4
    
    • which means "extracts bits[15:0] from r4 and zero extends to 32 bits into r3 target"
  • 8-bit operand (B - byte):
    80006a4:	b2db      	uxtb	r3, r3
    
    • which means "extracts bits[7:0] from "2nd" r3 and zero extends to 32 bits into "1st" r3"

It is my main objection why I did not use this Nucleo board for some time. I really like STM products, policies and prices, however Cortex-M is probably most difficult microcontroller to learn...

Here are few more Cortex-M assembler resources:

--hp

⚠️ **GitHub.com Fallback** ⚠️