ld: refactor stm32 linker scripts#7799
Conversation
d20609a to
4bfaf4e
Compare
jnohlgard
left a comment
There was a problem hiding this comment.
Only one comment for now, I do not have time to look at it more closely right now.
| { | ||
| rom (rx) : ORIGIN = rom_start_addr + boot_offset, LENGTH = rom_length - boot_offset | ||
| ram (rwx) : ORIGIN = ram_start_addr, LENGTH = ram_length | ||
| ccmram (rwx): ORIGIN = ccmram_start_addr, LENGTH = ccmram_length |
There was a problem hiding this comment.
This does not belong in the central cortex m ldscript.
There was a problem hiding this comment.
Removed from here and moved to a stm32_common.ld linker script.
vincent-d
left a comment
There was a problem hiding this comment.
I didn't reviewed it thoroughly, but some CPUs seem to have been dropped out.
4bfaf4e to
1cc2d4d
Compare
|
Oops! I forgot to add the offsets for the boards which have a bootloader. |
fc869f9 to
0602a48
Compare
|
#7739 is merged, and this is ready for review @gebart @vincent-d |
| ifeq ($(PROGRAMMER),dfu-util) | ||
| export LINKER_SCRIPT = stm32f103c8_bluepill.ld | ||
| export BINFILE = $(patsubst %.elf,%.bin,$(ELFFILE)) | ||
| export BINFILE = $(patsubst %.elf,%.bin,$(ELFFILE)) |
There was a problem hiding this comment.
This line defines BINFILE, but L24 below uses HEXFILE. Is there a use for this variable?
There was a problem hiding this comment.
Well, actually I just moved the indentation since there were tabs instead of 2 spaces, which is the convention. I think whatever modification of the code itself should be in another PR.
makefiles/arch/cortexm.inc.mk
Outdated
|
|
||
| export ASFLAGS += $(CFLAGS_CPU) $(CFLAGS_DBG) | ||
| export LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ldscripts -L$(RIOTCPU)/cortexm_common/ldscripts | ||
| export LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ldscripts -L$(RIOTCPU)/cortexm_common/ldscripts -L$(RIOTCPU)/stm32_common/ldscripts |
There was a problem hiding this comment.
no, this has to go somewhere else (stm32_common for example)
|
I've tried a few days ago to automatically generate info from STM32_INFO := $(shell printf '%s' $(CPU_MODEL) | tr 'a-z' 'A-Z' | sed -E -e 's/^STM32(F|L)(0|1|2|3|4)([0-9])([0-9])(.)(.)/\1 \2 \2\3\4 \3 \4 \5 \6/')
export STM32_TYPE = $(word 1, $(STM32_INFO))
export STM32_FAMILY = $(word 2, $(STM32_INFO))
export STM32_MODEL = $(word 3, $(STM32_INFO))
export STM32_MODEL2 = $(word 4, $(STM32_INFO))
export STM32_MODEL3 = $(word 5, $(STM32_INFO))
export STM32_PINCOUNT = $(word 6, $(STM32_INFO))
export STM32_ROMSIZE = $(word 7, $(STM32_INFO))
ifeq ($(STM32_TYPE), F)
ifeq ($(STM32_FAMILY),0)
ifneq ($(STM32_MODEL3),0)
ifeq ($(STM32_MODEL2),3)
export STM32_RAMSIZE = 4
else ifeq ($(STM32_MODEL2),4)
export STM32_RAMSIZE = 6
else ifeq ($(STM32_MODEL2),5)
export STM32_RAMSIZE = 8
else ifeq ($(STM32_MODEL2),7)
export STM32_RAMSIZE = 16
else ifeq ($(STM32_MODEL2),9)
export STM32_RAMSIZE = 32
endif
endif
else ifeq ($(STM32_FAMILY),1)
ifeq ($(STM32_MODEL3), 0)
ifneq (,$(filter $(STM32_ROMSIZE), 4 6))
export STM32_RAMSIZE = 4
else ifneq (,$(filter $(STM32_ROMSIZE), 8 B))
export STM32_RAMSIZE = 8
else ifneq (,$(filter $(STM32_ROMSIZE), C))
export STM32_RAMSIZE = 24
else ifneq (,$(filter $(STM32_ROMSIZE), E D))
export STM32_RAMSIZE = 32
endif
else ifneq (,$(filter $(STM32_MODEL3), 1 2))
ifneq (,$(filter $(STM32_ROMSIZE), 4))
export STM32_RAMSIZE = 4
else ifneq (,$(filter $(STM32_ROMSIZE), 6))
export STM32_RAMSIZE = 6
else ifneq (,$(filter $(STM32_ROMSIZE), 8))
export STM32_RAMSIZE = 10
else ifneq (,$(filter $(STM32_ROMSIZE), B))
export STM32_RAMSIZE = 16
else ifneq (,$(filter $(STM32_ROMSIZE), C))
export STM32_RAMSIZE = 32
else ifneq (,$(filter $(STM32_ROMSIZE), D E))
export STM32_RAMSIZE = 48
else ifneq (,$(filter $(STM32_ROMSIZE), F G))
export STM32_RAMSIZE = 80
endif
else ifeq ($(STM32_MODEL3), 3)
ifneq (,$(filter $(STM32_ROMSIZE), 4))
export STM32_RAMSIZE = 6
else ifneq (,$(filter $(STM32_ROMSIZE), 6))
export STM32_RAMSIZE = 10
else ifneq (,$(filter $(STM32_ROMSIZE), B 8))
export STM32_RAMSIZE = 20
else ifneq (,$(filter $(STM32_ROMSIZE), C D E))
export STM32_RAMSIZE = 20
else ifneq (,$(filter $(STM32_ROMSIZE), F G))
export STM32_RAMSIZE = 20
endif
else ifneq (,$(filter $(STM32_MODEL3), 1 2))
export STM32_RAMSIZE = 64
endif
else ifeq ($(STM32_FAMILY),2)
ifeq ($(STM32_ROMSIZE),B)
export STM32_RAMSIZE = 64
else ifeq ($(STM32_ROMSIZE),C)
export STM32_RAMSIZE = 96
else ifeq (,$(filter $(STM32_ROMSIZE), E F))
export STM32_RAMSIZE = 128
endif
else ifeq ($(STM32_FAMILY),3)
ifeq ($(STM32_MODEL),301)
export STM32_RAMSIZE = 16
else ifeq ($(STM32_MODEL),302)
ifneq (,$(filter $(STM32_ROMSIZE), 6))
export STM32_RAMSIZE = 32
else ifneq (,$(filter $(STM32_ROMSIZE), 8))
export STM32_RAMSIZE = 64
else ifneq (,$(filter $(STM32_ROMSIZE), B))
export STM32_RAMSIZE = 128
else ifneq (,$(filter $(STM32_ROMSIZE), C))
export STM32_RAMSIZE = 256
else ifneq (,$(filter $(STM32_ROMSIZE), D))
export STM32_RAMSIZE = 384
else ifneq (,$(filter $(STM32_ROMSIZE), E))
export STM32_RAMSIZE = 512
endif
else ifeq ($(STM32_MODEL),303)
ifneq (,$(filter $(STM32_ROMSIZE), 6 8))
export STM32_RAMSIZE = 16
else ifneq (,$(filter $(STM32_ROMSIZE), B))
export STM32_RAMSIZE = 40
else ifneq (,$(filter $(STM32_ROMSIZE), C))
export STM32_RAMSIZE = 48
else ifneq (,$(filter $(STM32_ROMSIZE), D E))
export STM32_RAMSIZE = 80
endif
else ifeq ($(STM32_MODEL3),4)
export STM32_RAMSIZE = 16
else ifeq ($(STM32_MODEL),373)
export STM32_RAMSIZE = 32
else ifeq ($(STM32_MODEL3),8)
ifneq (,$(filter $(STM32_MODEL2), 1 2))
export STM32_RAMSIZE = 16
else ifneq (,$(filter $(STM32_MODEL2), 5))
export STM32_RAMSIZE = 48
else ifneq (,$(filter $(STM32_MODEL2), 7))
export STM32_RAMSIZE = 32
else ifneq (,$(filter $(STM32_MODEL2), 9))
export STM32_RAMSIZE = 80
endif
endif
else ifeq ($(STM32_FAMILY),4)
ifeq ($(STM32_MODEL),401)
ifneq (, $(filter $(STM32_ROMSIZE), B C))
export STM32_RAMSIZE = 64
else ifneq (, $(filter $(STM32_ROMSIZE), D E))
export STM32_RAMSIZE = 96
endif
else ifeq ($(STM32_MODEL),410)
export STM32_RAMSIZE = 32
else ifneq (, $(filter $(STM32_MODEL), 411 446))
export STM32_RAMSIZE = 128
else ifneq (, $(filter $(STM32_MODEL), 412 427 429))
export STM32_RAMSIZE = 256
else ifeq ($(STM32_MODEL),413)
export STM32_RAMSIZE = 320
else ifneq (, $(filter $(STM32_MODEL), 405 407))
export STM32_RAMSIZE = 192
else ifeq ($(STM32_MODEL),469)
export STM32_RAMSIZE = 384
endif
endif
else ifeq ($(STM32_TYPE), L)
ifeq ($(STM32_FAMILY),0)
ifneq (, $(filter $(STM32_MODEL2), 1 2)
export STM32_RAMSIZE = 2
else ifneq (, $(filter $(STM32_MODEL2), 3 4 5 6)
export STM32_RAMSIZE = 8
else ifneq (, $(filter $(STM32_MODEL2), 7 8)
export STM32_RAMSIZE = 20
endif
else ifeq ($(STM32_FAMILY),1)
else ifeq ($(STM32_FAMILY),4)
ifneq (, $(filter $(STM32_MODEL2), 3))
export STM32_RAMSIZE = 64
else ifneq (, $(filter $(STM32_MODEL2), 7))
export STM32_RAMSIZE = 128
else ifneq (, $(filter $(STM32_MODEL2), 5))
export STM32_RAMSIZE = 160
else ifneq (, $(filter $(STM32_MODEL2), 9))
export STM32_RAMSIZE = 320
endif
endif
endif
ifeq ($(STM32_RAMSIZE), )
$(error Unsupported cpu model $(CPU_MODEL))
endif
ifeq ($(STM32_ROMSIZE),4)
export STM32_ROMSIZE = 16
else ifeq ($(STM32_ROMSIZE),6)
export STM32_ROMSIZE = 32
else ifeq ($(STM32_ROMSIZE),8)
export STM32_ROMSIZE = 64
else ifeq ($(STM32_ROMSIZE),B)
export STM32_ROMSIZE = 128
else ifeq ($(STM32_ROMSIZE),Z)
export STM32_ROMSIZE = 192
else ifeq ($(STM32_ROMSIZE),C)
export STM32_ROMSIZE = 256
else ifeq ($(STM32_ROMSIZE),D)
export STM32_ROMSIZE = 384
else ifeq ($(STM32_ROMSIZE),E)
export STM32_ROMSIZE = 512
else ifeq ($(STM32_ROMSIZE),F)
export STM32_ROMSIZE = 768
else ifeq ($(STM32_ROMSIZE),G)
export STM32_ROMSIZE = 1024
else ifeq ($(STM32_ROMSIZE),H)
export STM32_ROMSIZE = 1536
else ifeq ($(STM32_ROMSIZE),I)
export STM32_ROMSIZE = 2048
endif
ifeq ($(STM32_PINCOUNT),A)
export STM32_PINCOUNT = 169
else ifeq ($(STM32_PINCOUNT),B)
export STM32_PINCOUNT = 208
else ifeq ($(STM32_PINCOUNT),C)
export STM32_PINCOUNT = 48
else ifeq ($(STM32_PINCOUNT),F)
export STM32_PINCOUNT = 20
else ifeq ($(STM32_PINCOUNT),G)
export STM32_PINCOUNT = 28
else ifeq ($(STM32_PINCOUNT),H)
export STM32_PINCOUNT = 40
else ifeq ($(STM32_PINCOUNT),I)
export STM32_PINCOUNT = 176
else ifeq ($(STM32_PINCOUNT),J)
export STM32_PINCOUNT = 72
else ifeq ($(STM32_PINCOUNT),K)
export STM32_PINCOUNT = 32
else ifeq ($(STM32_PINCOUNT),M)
export STM32_PINCOUNT = 81
else ifeq ($(STM32_PINCOUNT),N)
export STM32_PINCOUNT = 216
else ifeq ($(STM32_PINCOUNT),Q)
export STM32_PINCOUNT = 132
else ifeq ($(STM32_PINCOUNT),R)
export STM32_PINCOUNT = 64
else ifeq ($(STM32_PINCOUNT),T)
export STM32_PINCOUNT = 36
else ifeq ($(STM32_PINCOUNT),U)
export STM32_PINCOUNT = 63
else ifeq ($(STM32_PINCOUNT),V)
export STM32_PINCOUNT = 100
else ifeq ($(STM32_PINCOUNT),Z)
export STM32_PINCOUNT = 144
endif
$(info STM32 type: $(STM32_TYPE))
$(info STM32 Family: $(STM32_FAMILY))
$(info STM32 Model: $(STM32_MODEL))
$(info STM32 Pin count: $(STM32_PINCOUNT))
$(info STM32 ROM size: $(STM32_ROMSIZE))
$(info STM32 RAM size: $(STM32_RAMSIZE)) |
|
@vincent-d so what you propose is to trigger that script instead of define the variables in stm32xx/Makefile.include? If so, do you agree we need to put your |
|
@kYc0o that's actually a Makefile script ;) and yes, I propose to use this to compute ROM and RAM sizes. I took the idea from @gebart and his work for kinetis. The main advantage would be that every new part number can be supported easily (and almost automatically). |
|
Excellent! Sorry for the confusion, it looked at a first sight as a shell script. I'll adapt it then. Thanks a lot! |
Why didn't you factorise this altogether? |
0602a48 to
4295baa
Compare
0e25cb6 to
3661e3d
Compare
| * @} | ||
| */ | ||
|
|
||
| ccmram_length = DEFINED( ccmram_len ) ? ccmram_len : 0x0 ; |
There was a problem hiding this comment.
I can't find any definition of ccmram_len, why is the purpose of that file?
There was a problem hiding this comment.
I wanted to remove it but some people convinced me to leave it as a reference. Only certain models have this kind of memory but currently is not used by our main cortex linker script. I don't think it harms and it reminds that a special memory i's available for those models, maybe in the future we'll find an usage.
There was a problem hiding this comment.
Oh, I forgot to answer the main question... I'll add the memory definition to such models.
|
Hej guys, looking at the I was just recently pointed to to the approach that @basilfx took (or is going to propose) for the SiLabs CPUs. He put all the relevant CPU information in a very easy to parse file (look here) parses this from a straight-forward Makefile (look here). I must say I like it as it is so simple and easy to read, so could that also be an option to use here? |
It looks nice at first glance, but I think the number of stm32 is higher and I'm not sure listing them all in a file would make things easier to read and maintain. The problem with stm32 is that they didn't properly encode the RAM size in the part number...otherwise the ROM size is easy to parse. |
|
I agree with @vincent-d, I looked at @basilfx code and my first thought was how ugly (maybe more than the current approach) this would be to read, taking into account the hundreds of stm32 devices. This without taking into account the pain to write it... |
|
Silicon Labs has divided their CPUs into families: EFM32GG, EFM32LG, etc. Therefore I have @vincent-d more than 34 families with in total 736 CPUs? :-P |
|
I see. I personally simply like explicit statements (as in one easy to read row per CPU). But I don't have strong opinion about this. Just wanted to point out the alternative approach here. So I'd say leave this PR as is then. |
|
Added CCM ram variable. |
yeah, I don't think so :D But as you pointed out, silabs provide vendor libraries which you use. This is not the case with st... |
| RAM_LEN = 192K | ||
| else ifneq (, $(filter $(STM32_MODEL), 469 479)) | ||
| RAM_LEN = 384K | ||
| ifneq (, $(filter $(STM32_MODEL3), 5 7 9)) |
|
I think all the comments were addressed here, anyone cares to give an (or two) ACK(s) ? |
vincent-d
left a comment
There was a problem hiding this comment.
Two minor comments remaining, but it's an ACK from my side, you can squash
| else ifeq ($(STM32_MODEL3), 3) | ||
| ifeq ($(STM32_ROMSIZE), 4)) | ||
| RAM_LEN = 6K | ||
| else ifeq ( $(STM32_ROMSIZE), 6)) |
| endif | ||
|
|
||
| ifeq ($(RAM_LEN), ) | ||
| $(warning Unsupported cpu model $(CPU_MODEL) automatically) |
d530f5f to
5216acf
Compare
|
Last comments fixed and squashed. |
|
@gebart, do you see remaining things here ? I just went through the change and it seems all comments are addressed now. |
jnohlgard
left a comment
There was a problem hiding this comment.
Looks fine now. Fix my minor comments if you like, you may squash immediately and merge.
| # The next block takes care of setting the rigth lengths of RAM and ROM | ||
| # for the stm32 family. Most of the CPUs should have been taken into | ||
| # account here, so no need to assign the lengths per model. | ||
| STM32_INFO := $(shell printf '%s' $(CPU_MODEL) | tr 'a-z' 'A-Z' | sed -E -e 's/^STM32(F|L)(0|1|2|3|4|7)([0-9])([0-9])(.)(.)/\1 \2 \2\3\4 \3 \4 \5 \6/') |
There was a problem hiding this comment.
Tiny mistake: put single quotes around the $(CPU_MODEL)
| STM32_MODEL2 = $(word 4, $(STM32_INFO)) | ||
| STM32_MODEL3 = $(word 5, $(STM32_INFO)) | ||
| STM32_PINCOUNT = $(word 6, $(STM32_INFO)) | ||
| STM32_ROMSIZE = $(word 7, $(STM32_INFO)) |
There was a problem hiding this comment.
Change to immediate assignments here and above (= -> :=)
|
My comments are only pedantic, feel free to merge with or without addressing them |
|
@gebart I'll take them into account. |
5216acf to
d6751dd
Compare
|
Last comments addressed, found some extra parenthesis left. Should be ok now. |
|
Let's go! |
A subset of #7729 and follow-up of #7739.
This PR aims to add a generic linker script for all stm32 mcu family. The goal is to remove all stm32 related linker scripts and rather provide the addresses and sizes of the memory map, to be integrated by the common cortexm.ld linker script.
This can be then extended to other families (e.g. kinetis, NXP, Nordic...).