import os
import subprocess
PREFIX = " arm-none-eabi- "
BUILDER = " DEV "
common_flags = [ ]
build_projects = { }
build_projects [ " body " ] = {
" MAIN " : " main.c " ,
" STARTUP_FILE " : " startup_stm32f413xx.s " ,
" LINKER_SCRIPT " : " stm32fx_flash.ld " ,
" APP_START_ADDRESS " : " 0x08004000 " ,
" PROJECT_FLAGS " : [
" -mcpu=cortex-m4 " ,
" -mhard-float " ,
" -DSTM32F4 " ,
" -DSTM32F413xx " ,
" -mfpu=fpv4-sp-d16 " ,
" -fsingle-precision-constant " ,
" -Os " ,
" -g " ,
] ,
}
if os . getenv ( " RELEASE " ) :
BUILD_TYPE = " RELEASE "
cert_fn = os . getenv ( " CERT " )
assert cert_fn is not None , ' No certificate file specified. Please set CERT env variable '
assert os . path . exists ( cert_fn ) , ' Certificate file not found. Please specify absolute path '
else :
BUILD_TYPE = " DEBUG "
cert_fn = File ( " ../certs/debug " ) . srcnode ( ) . relpath
common_flags + = [ " -DALLOW_DEBUG " ]
if os . getenv ( " DEBUG " ) :
common_flags + = [ " -DDEBUG " ]
includes = [
" inc/STM32F4xx_HAL_Driver/Inc " ,
" inc " ,
" .. " ,
" . " ,
]
c_sources = [
[ " hal_flash " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash.c " ] ,
[ " hal_pwr " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c " ] ,
[ " hal_rcc " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c " ] ,
[ " hal_i2c " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c.c " ] ,
[ " hal_i2c_ex " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2c_ex.c " ] ,
[ " hal_tim " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim.c " ] ,
[ " hal_tim_ex " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_tim_ex.c " ] ,
[ " hal_adc_ex " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc_ex.c " ] ,
[ " hal_cortex " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c " ] ,
[ " hal_flash_ex " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_flash_ex.c " ] ,
[ " hal_gpio " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c " ] ,
[ " hal_rcc_ex " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c " ] ,
[ " hal " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c " ] ,
[ " hal_adc " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_adc.c " ] ,
[ " hal_dma " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_dma.c " ] ,
[ " system " , " inc/system_stm32f4xx.c " ] ,
[ " it " , " inc/stm32f4xx_it.c " ] ,
[ " bldc " , " bldc/bldc.c " ] ,
[ " bldc_data " , " bldc/BLDC_controller_data.c " ] ,
[ " bldc_con " , " bldc/BLDC_controller.c " ] ,
[ " util " , " util.c " ] ,
]
c_bstub_sources = [
[ " hal_pwr " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_pwr.c " ] ,
[ " hal_rcc " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc.c " ] ,
[ " hal_cortex " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_cortex.c " ] ,
[ " hal_gpio " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_gpio.c " ] ,
[ " hal_rcc_ex " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c " ] ,
[ " hal " , " inc/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal.c " ] ,
[ " system " , " inc/system_stm32f4xx.c " ] ,
[ " it " , " inc/stm32f4xx_it.c " ] ,
[ " util " , " util.c " ] ,
]
def get_version ( builder , build_type ) :
try :
git = subprocess . check_output ( [ " git " , " rev-parse " , " --short=8 " , " HEAD " ] , encoding = ' utf8 ' ) . strip ( )
except subprocess . CalledProcessError :
git = " 00000000 "
return f " { git } "
def to_c_uint32 ( x ) :
nums = [ ]
for _ in range ( 0x20 ) :
nums . append ( x % ( 2 * * 32 ) )
x / / = ( 2 * * 32 )
return " { " + ' U, ' . join ( map ( str , nums ) ) + " U} "
def get_key_header ( name ) :
from Crypto . PublicKey import RSA
public_fn = f ' ../certs/ { name } .pub '
rsa = RSA . importKey ( open ( public_fn ) . read ( ) )
assert ( rsa . size_in_bits ( ) == 1024 )
rr = pow ( 2 * * 1024 , 2 , rsa . n )
n0inv = 2 * * 32 - pow ( rsa . n , - 1 , 2 * * 32 )
r = [
f " RSAPublicKey { name } _rsa_key = {{ " ,
f " .len = 0x20, " ,
f " .n0inv = { n0inv } U, " ,
f " .n = { to_c_uint32 ( rsa . n ) } , " ,
f " .rr = { to_c_uint32 ( rr ) } , " ,
f " .exponent = { rsa . e } , " ,
f " }} ; " ,
]
return r
def objcopy ( source , target , env , for_signature ) :
return ' $OBJCOPY -O binary %s %s ' % ( source [ 0 ] , target [ 0 ] )
# Common autogenerated includes
git_ver = get_version ( BUILDER , BUILD_TYPE )
with open ( " obj/gitversion.h " , " w " ) as f :
f . write ( f ' const uint8_t gitversion[8] = " { git_ver } " ; \n ' )
certs = [ get_key_header ( n ) for n in [ " debug " , " release " ] ]
with open ( " obj/cert.h " , " w " ) as f :
for cert in certs :
f . write ( " \n " . join ( cert ) + " \n " )
for project_name in build_projects :
project = build_projects [ project_name ]
linkerscript_fn = File ( project [ " LINKER_SCRIPT " ] ) . srcnode ( ) . relpath
flags = [
" -Wall " ,
" -Wextra " ,
" -Wstrict-prototypes " ,
" -Werror " ,
" -mlittle-endian " ,
" -mthumb " ,
" -nostdlib " ,
" -fno-builtin " ,
f " -T { linkerscript_fn } " ,
" -std=gnu11 " ,
" -fdata-sections " ,
" -ffunction-sections " ,
" -Wl,--gc-sections " ,
] + project [ " PROJECT_FLAGS " ] + common_flags
project_env = Environment (
ENV = os . environ ,
CC = PREFIX + ' gcc ' ,
AS = PREFIX + ' gcc ' ,
OBJCOPY = PREFIX + ' objcopy ' ,
OBJDUMP = PREFIX + ' objdump ' ,
ASCOM = " $AS $ASFLAGS -o $TARGET -c $SOURCES " ,
CFLAGS = flags ,
ASFLAGS = flags ,
LINKFLAGS = flags ,
LIBS = [ ' gcc ' , ] ,
CPPPATH = includes ,
BUILDERS = {
' Objcopy ' : Builder ( generator = objcopy , suffix = ' .bin ' , src_suffix = ' .elf ' )
}
)
startup = project_env . Object ( project [ " STARTUP_FILE " ] )
c_bstub_obj_list = [ ]
for c in c_bstub_sources :
c_bstub_obj_list . append ( project_env . Object ( f " { c [ 0 ] } - { project_name } " , c [ 1 ] ) )
# Bootstub
crypto_obj = [
project_env . Object ( f " rsa- { project_name } " , " ../crypto/rsa.c " ) ,
project_env . Object ( f " sha- { project_name } " , " ../crypto/sha.c " )
]
bootstub_obj = project_env . Object ( f " bootstub- { project_name } " , " bootstub.c " )
bootstub_elf = project_env . Program ( f " obj/bootstub. { project_name } .elf " , [ startup ] + crypto_obj + c_bstub_obj_list + [ bootstub_obj ] )
bootstub_bin = project_env . Objcopy ( f " obj/bootstub. { project_name } .bin " , bootstub_elf )
c_obj_list = [ ]
for c in c_sources :
c_obj_list . append ( project_env . Object ( f " { c [ 0 ] } - { project_name } " , c [ 1 ] ) )
# Build main
main_obj = project_env . Object ( f " main- { project_name } " , project [ " MAIN " ] )
obj_list = [ startup , main_obj ] + c_obj_list
main_elf = project_env . Program ( f " obj/ { project_name } .elf " , obj_list ,
LINKFLAGS = [ f " -Wl,--section-start,.isr_vector= { project [ ' APP_START_ADDRESS ' ] } " ] + flags )
main_bin = project_env . Objcopy ( f " obj/ { project_name } .bin " , main_elf )
# Sign main
sign_py = File ( " ../crypto/sign.py " ) . srcnode ( ) . relpath
panda_bin_signed = project_env . Command ( f " obj/ { project_name } .bin.signed " , main_bin , f " SETLEN=1 { sign_py } $SOURCE $TARGET { cert_fn } " )