Local DFU compile

Hello all,

I have recently set up everything to compile code locally and flash it over USB while the photon is in DFU mode. I have two questions for anyone perhaps experienced in this:

  1. I have successfully compiled code that uses the standard functions (ie pinMode and digitalWrite). I am interested in writing directly to the registers however when I try GPIOB->ODR I get an error that GPIOB and ODR are not define. When I looked into the firmware files, I found that the definitions are in stm32f2xx.h so I downloaded that file and included it as a header. The issue is that now when I try to compile the code, it tells me that it cannot find another file which is referenced in stm32f2xx.h. I did the same thing and it seems to be a never ending loop of copying and downloading more files. There must be an easier way of doing this. I could download the whole firmware folder but from what I know the header files should all be in the same directory. Can anyone point me in the right direction

  2. Is there any way that instead of writing the code in the two segments (setup and loop), that I can write it like a standard c code (having int main() ) ?

Thanks in advance!

You should not need to include anything really.
Direct register access is possible even with the cloud build farms, so I’d not see reason why it shouldn’t work with a local toolchain.
Could you post the offending code lines and the exact error messages you get?

If you want 2), you’d need to do the jobs that are done in the already existing main() function in your own too - unless you want to ditch all the system stuff that’s baked into that already.
You can even ditch the whole framwork and treat the Particles as “dumb” STM32Fs :wink:

This is the code that I’m compiling (The compile/flash over serial gives no errors for regular functions as stated above):
Filename: application.cpp
#include “application.h”

void setup() {
// Initialize pins D3 and D4 as outputs
GPIOB->MODER=0x00000140;
}

void loop() {
// Set pin D3 to logical HIGH
GPIOB->ODR = 0x00000010;  
}

I get the following error:

applications/reg_test/application.cpp: In function 'void setup()':
applications/reg_test/application.cpp:5:8: error: 'struct GPIO_TypeDef' has no m
ember named 'MODER'
 GPIOB->MODER=0x00000140;
        ^
make[2]: *** [../build/target/user/platform-0-lto/applications/reg_test/applicat
ions/reg_test/application.o] Error 1
make[2]: Leaving directory `C:/Particle/firmware/user'
make[1]: *** [user] Error 2
make[1]: Leaving directory `C:/Particle/firmware/main'
make: *** [main] Error 2

As for the second part, where can I find all that is done in the main() function? also, I try compiling code with int main() {} with nothing in the brackets just to test it out and I’m getting the following error:

Invoking: ARM GCC C++ Linker
mkdir -p ../build/target/main/platform-0-lto/
arm-none-eabi-g++ -DSTM32_DEVICE -DSTM32F10X_MD -DPLATFORM_THREADING=0 -DPLATFOR
M_ID=0 -DPLATFORM_NAME=core -DUSBD_VID_SPARK=0x1D50 -DUSBD_PID_DFU=0x607F -DUSBD
_PID_CDC=0x607D -g3 -gdwarf-2 -Os -mcpu=cortex-m3 -mthumb -flto -DINCLUDE_PLATFO
RM=1 -DPRODUCT_ID=0 -DPRODUCT_FIRMWARE_VERSION=65535 -DUSE_STDPERIPH_DRIVER -DDF
U_BUILD_ENABLE -DSYSTEM_VERSION_STRING=0.5.1 -DRELEASE_BUILD -Werror -I../user/i
nc -I../wiring/inc -I../hal/inc -I../hal/shared -I../hal/src/core -I../hal/src/s
tm32 -I../system/inc -I../services/inc -I../communication/src -I../platform/shar
ed/inc -I../platform/MCU/STM32F1xx/CMSIS/Include -I../platform/MCU/STM32F1xx/CMS
IS/Device/ST/Include -I../platform/MCU/STM32F1xx/SPARK_Firmware_Driver/inc -I../
platform/MCU/shared/STM32/inc -I../platform/MCU/STM32F1xx/STM32_StdPeriph_Driver
/inc -I../platform/MCU/STM32F1xx/STM32_USB_Device_Driver/inc -I../platform/NET/C
C3000/CC3000_Host_Driver -I../dynalib/inc -I. -MD -MP -MF ../build/target/main/p
latform-0-lto/xtest20.elf.d -ffunction-sections -fdata-sections -Wall -Wno-switc
h -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DS
PARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHE
R_SERIAL_SPEED=28800 -DMODULE_VERSION=0 -DMODULE_FUNCTION=3 -DMODULE_DEPENDENCY=
0,0,0 -D_GNU_SOURCE -D_WINSOCK_H ../build/target/main/platform-0-lto/./src/modul
e_info.o  ../build/target/main/platform-0-lto/startup/startup_stm32f10x_md.o --o
utput ../build/target/main/platform-0-lto/xtest20.elf -nostartfiles -Xlinker --g
c-sections -flto -Os -fuse-linker-plugin -Tlinker_stm32f10x_md_dfu.ld -L../build
/arm/linker --specs=nano.specs -lc -lnosys -u _printf_float -Wl,-Map,../build/ta
rget/main/platform-0-lto/xtest20.map  -L../build/target/user/platform-0-lto/appl
ications/xtest20/ -L../build/target/wiring/platform-0-lto/ -L../build/target/sys
tem/platform-0-lto/ -L../build/target/services/platform-0-lto/ -L../build/target
/communication/platform-0-lto-prod-0/ -L../build/target/hal/platform-0-lto/ -L..
/build/target/platform/platform-0-lto/ -L../build/target/wiring_globals/platform
-0-lto/ -L../build/target/newlib_nano/platform-0-lto -L../build/arm/linker -Wl,-
-whole-archive -lnewlib_nano -luser -lwiring -lhal -lsystem -lservices -lcommuni
cation -lplatform -lwiring_globals -Wl,--no-whole-archive
core_hal.o (symbol from plugin): In function `HAL_Ssystem_Backup_Restore':
(.text+0x0): multiple definition of `main'
application.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
make[1]: *** [../build/target/main/platform-0-lto/xtest20.elf] Error 1
make[1]: Leaving directory `C:/Particle/firmware/main'
make: *** [main] Error 2

Is this because I’m not doing something properly? From what you said, the program should compile. It wouldn’t work on the photon as it is but it should compile and create a .bin file am I right?

You seem to be building for PLATFORM=core is this correct?
But if you are talking about stm32f2xx.h you should be building for PLATFORM=photon or PLATFORM=electron

I am using PLATFORM=photon. I use the following command to build the file:

C:\Particle\firmware>make PLATFORMR=photon APP=appname

Is the typo PLATFORMR just in the post? In any case, you should probably do the make from firmware/modules, not the top level.

Is this a typo there


doh’ @rickkas7 was faster


But if you did by accident build for the Core, you could try one of the registers available there, to check :wink:

typedef struct
{
  __IO uint32_t CRL;
  __IO uint32_t CRH;
  __IO uint32_t IDR;
  __IO uint32_t ODR;
  __IO uint32_t BSRR;
  __IO uint32_t BRR;
  __IO uint32_t LCKR;
} GPIO_TypeDef;

Also, you should be able to use those definitions, even with Particle Build, the Web IDE, without copying any includes. I was able to build this code in the web IDE:

#include "Particle.h"
#include "stm32f2xx.h"

void setup() {
    // Initialize pins D3 and D4 as outputs
    GPIOB->MODER=0x00000140;
}

void loop() {
    // Set pin D3 to logical HIGH
    GPIOB->ODR = 0x00000010;  
}

You don’t even need the #include "stm32f2xx.h"

1 Like

Oops, I just noticed you said that above. So you were first on that one :slight_smile:

1 Like

@ScruffR @rickkas7

Well it seems to be working now. I think the issue was that I had the typo going today and the system was simply ignoring the PLATFORM®=photon so it was assuming the default core. In the past I have been including the stm32 header file and i seemed to be running into issues there. Anyways works now so thank you!

As for the modules, I used to get errors in the past. I just tried switching now and its working just fine. I guess I’ll stay there.

So back to the issue of using main() is there a place I can look at to get the ball rolling? I’m assuming we’re talking about things in the firmware folder that define all the functions and such

1 Like

Just out of interest, why would you need to replace the “framework” main() and not just go with the setup()/loop() scheme?

@ScruffR I’m doing some research into the Particle Photon with the hopes of implementing it in an educational program for electrical engineers. One of the aspects that we would like to implement is bare coding (ie coding the microprocessor straight and not from the setup/loop)