biemster / st17h66_FindMy

Firmware for Lenze ST17h66 that advertises to the Apple Find My network
30 stars 10 forks source link

Linker script implementation #1

Closed biemster closed 1 year ago

biemster commented 2 years ago

The Lenze SDK is written for the ARMCC compiler, and uses Keil uVision. Linking is done using a scatter file scatter_load.sct. GCC is using a linker script, which is not compatible with the scatter file. The process of converting the uVision uvproject was done using https://github.com/phodina/ProjectConverter which provides an example GCC linker script, but this has to be modified by hand.

Some useful resources on how to do this are: https://interrupt.memfault.com/blog/how-to-write-linker-scripts-for-firmware https://www.renesas.com/kr/en/document/apn/b-024-porting-keil-uvision-project-gnu-chain-tool https://github.com/adamheinrich/cm-makefile

Also uVision can be configured to use GCC (this maybe generates a linker script): https://developer.arm.com/documentation/101407/0537/Creating-Applications/Tips-and-Tricks/GNU-C-Compiler-Support https://developer.arm.com/downloads/-/gnu-rm

biemster commented 2 years ago

Some object files in lib/rf.lib seem to have an invalid sh_info value, and the GNU linker is stumbling over them:

:~/temp/Lenze/ST17H65_SDK_3.1.1.2_lowPower_beacon/lib/rflib$ readelf -s patch.o > /dev/null
readelf: Warning: local symbol 748 found at index >= .symtab's sh_info value of 418

because readelf is writing this to stderr.

biemster commented 2 years ago

Patching patch.o and rf_phy_driver.o with a hex editor actually fixes this issue. Next problem:

rf.lib(phy_sec_ext.o) conflicting CPU architectures 12/0

and a whole bunch of those. I might have to recompile the rf.lib and ble_host.lib myself somehow. UPD: https://github.com/biemster/Lenze_libs looks promising.

biemster commented 2 years ago

Seems like an issue in GCC not supporting the exact CPU architecture: https://stackoverflow.com/a/16688192/11545161 So I see two possible solutions atm:

  1. Convince the linker that it is fine to link
  2. Get a toolchain with support for thumb/cortex-m0;@mthumb@mcpu=cortex-m0

UPD: Found a toolchain that has support for point 2. here: https://sysprogs.com/getfile/5/arm-eabi-gcc6.2.0-r4.exe but the linker still complains about conflicting CPU arch.

biemster commented 2 years ago

https://github.com/biemster/Lenze_libs should be exactly the source for the libs, as ST17H65_SDK_3.1.1.2_lowPower_beacon/lib/rflib/phy_sec_ext.o contains the string PHY+62XXPLUS0504 which is the same s_company_id found in phy_sec_ext.c in that repository! It might be from an older version of the SDK though, so I might need to dig up some old SDKs. I already have 3.0.9, and I remember seeing 3.0.6 somewhere as well..

biemster commented 2 years ago

More people are trying something similar: https://github.com/AloyseTech/PHY6202_GCC

biemster commented 2 years ago

So I can get it to compile fully to a hex file using GCC in uVision on Windows, good first step! I'm not fully sure though if everything got linked correctly, but I do have all the ingredients now. One minus is that the hex is too big to fit on the chip, LeKit complains that the XIP part is too large. I tried to discard unused objects using -ffunction-sections, -fdata-sections, and then linker flag --gc-sections, but then uVision reports that gcc does not know about --gc-sections. So Keil seems to inject some linker options into the compiler command.. :( UPD: that was my fault, the flag is Wl,--gc-sections. Now Keil discards all the sections, GCC thinks everything is unused.

biemster commented 2 years ago

It's compiling now to a 90kB hex under linux using GCC, but when flashing this to the chip nothing seems to happen.. I doubt this is worth my effort further, as it will require a much deeper understanding of this stuff than I currently have.

biemster commented 2 years ago

The ch6121 looks very similar to the 17h66 and has an GCC SDK: https://github.com/diskman88/PHY6212

biemster commented 1 year ago

I've started https://github.com/biemster/st17h66_blinky to first try to convert an absolute minimum project to GCC

biemster commented 1 year ago

Blinky compiles and runs now with GCC!

biemster commented 1 year ago

https://github.com/biemster/st17h66_RF now also compiles on GCC, including sleep mode! As this is much simpler code, this repo will be rewritten to use the RF only approach build there. Since that compiles on GCC now, this can be closed.

wangwillian0 commented 7 months ago

https://github.com/biemster/st17h66_RF now also compiles on GCC, including sleep mode! As this is much simpler code, this repo will be rewritten to use the RF only approach build there. Since that compiles on GCC now, this can be closed.

Hi, I just tried the current GCC build and it doesn't work (no BLE activity), do you think it would be easy to refactor this repo using that approach? I'm quite busy these days but maybe I can help with one thing or another

biemster commented 7 months ago

It should work, I definitely got BLE activity there also on the binaries built by GCC. Getting this repo with the whole osal and bluetooth stack should be quite straightforward to port to GCC too, although the linker script and specifically the XIP stuff will need some work.

steve-m commented 7 months ago

I recently played around with this and added the FindMy specific code, and I had the tag appear on the FindMy map: https://github.com/steve-m/st17h66_RF

wangwillian0 commented 7 months ago

@steve-m I just tried it and the beacon doesn't seem to be broadcasting any packet, did you confirm it by bluetooth? maybe the problem is with my local setup

steve-m commented 7 months ago

Yes, that seems likely. I am starting an LE scan with the bluetoothctl command "scan le", and filter the packets in Wireshark to match the MAC address of my beacon. I can see the periodic advertisements there.

wangwillian0 commented 7 months ago

I tested again under ubuntu packages using docker (I was originally with Manjaro), compiled with make and got the same result. I also tried https://github.com/biemster/st17h66_blinky and nothing blinked at all, which makes me think I'm with a slightly different version of hardware. Building with the ARM compiler from Keil works fine.

wangwillian0 commented 7 months ago

Ok, my mistake, I was using the wrong flash_st17h66.py 🤦. I can confirm your repository is working, it also periodically makes a sound and prints debug messages to serial. Thank you!

biemster commented 7 months ago

Great work! Keep in mind though that enabling the UART will decrease your battery life from close to a year to a week or two.

steve-m commented 7 months ago

Yes, that should be disabled again. I needed it for debugging, because when there is no BLE output and no UART, you don't know what goes wrong ;)