From 82ccbc40db1d81eb35efd35f915096ddeee3b2b9 Mon Sep 17 00:00:00 2001 From: guozhanxin Date: Wed, 17 May 2023 17:17:38 +0800 Subject: [PATCH] support llvm-arm 16.0 --- .../stm32l475-atk-pandora/board/SConscript | 2 +- bsp/stm32/stm32l475-atk-pandora/rtconfig.py | 33 +++++++++++ components/drivers/spi/SConscript | 2 +- components/libc/compilers/common/cstring.c | 2 + .../compilers/common/extension/SConscript | 2 +- components/libc/compilers/picolibc/README.md | 8 +++ components/libc/compilers/picolibc/SConscript | 29 ++++++++++ components/libc/compilers/picolibc/syscall.c | 16 ++++++ libcpu/arm/cortex-m4/SConscript | 2 +- tools/llvm_arm.py | 57 +++++++++++++++++++ 10 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 components/libc/compilers/picolibc/README.md create mode 100644 components/libc/compilers/picolibc/SConscript create mode 100644 components/libc/compilers/picolibc/syscall.c create mode 100644 tools/llvm_arm.py diff --git a/bsp/stm32/stm32l475-atk-pandora/board/SConscript b/bsp/stm32/stm32l475-atk-pandora/board/SConscript index 97c31ee844..513aa8598a 100644 --- a/bsp/stm32/stm32l475-atk-pandora/board/SConscript +++ b/bsp/stm32/stm32l475-atk-pandora/board/SConscript @@ -47,7 +47,7 @@ if GetDepend(['BSP_USING_AUDIO']): startup_path_prefix = SDK_LIB -if rtconfig.PLATFORM in ['gcc']: +if rtconfig.PLATFORM in ['gcc', 'llvm-arm']: src += [startup_path_prefix + '/STM32L4xx_HAL/CMSIS/Device/ST/STM32L4xx/Source/Templates/gcc/startup_stm32l475xx.s'] elif rtconfig.PLATFORM in ['armcc', 'armclang']: src += [startup_path_prefix + '/STM32L4xx_HAL/CMSIS/Device/ST/STM32L4xx/Source/Templates/arm/startup_stm32l475xx.s'] diff --git a/bsp/stm32/stm32l475-atk-pandora/rtconfig.py b/bsp/stm32/stm32l475-atk-pandora/rtconfig.py index af29494a89..6b54a18e1a 100644 --- a/bsp/stm32/stm32l475-atk-pandora/rtconfig.py +++ b/bsp/stm32/stm32l475-atk-pandora/rtconfig.py @@ -24,6 +24,9 @@ elif CROSS_TOOL == 'keil': elif CROSS_TOOL == 'iar': PLATFORM = 'iccarm' EXEC_PATH = r'C:/Program Files (x86)/IAR Systems/Embedded Workbench 8.3' +elif CROSS_TOOL == 'llvm-arm': + PLATFORM = 'llvm-arm' + EXEC_PATH = r'D:\Progrem\LLVMEmbeddedToolchainForArm-16.0.0-Windows-x86_64\bin' if os.getenv('RTT_EXEC_PATH'): EXEC_PATH = os.getenv('RTT_EXEC_PATH') @@ -176,6 +179,36 @@ elif PLATFORM == 'iccarm': EXEC_PATH = EXEC_PATH + '/arm/bin/' POST_ACTION = 'ielftool --bin $TARGET rtthread.bin' +elif PLATFORM == 'llvm-arm': + # toolchains + PREFIX = 'llvm-' + CC = 'clang' + AS = 'clang' + AR = PREFIX + 'ar' + CXX = 'clang++' + LINK = 'clang' + TARGET_EXT = 'elf' + SIZE = PREFIX + 'size' + OBJDUMP = PREFIX + 'objdump' + OBJCPY = PREFIX + 'objcopy' + DEVICE = ' --config armv7em_hard_fpv4_sp_d16.cfg' + CFLAGS = DEVICE + CFLAGS += ' -mfloat-abi=hard -march=armv7em -mfpu=fpv4-sp-d16' + AFLAGS = ' -c' + DEVICE + ' -Wa,-mimplicit-it=thumb ' ## -x assembler-with-cpp + LFLAGS = DEVICE + ' -Wl,--gc-sections,-Map=rt-thread.map,-u,Reset_Handler -T board/linker_scripts/link.lds' + + CPATH = '' + LPATH = '' + + if BUILD == 'debug': + CFLAGS += ' -O0 -gdwarf-2 -g' + AFLAGS += ' -gdwarf-2' + else: + CFLAGS += ' -O2' + + CXXFLAGS = CFLAGS + + POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n' def dist_handle(BSP_ROOT, dist_dir): import sys diff --git a/components/drivers/spi/SConscript b/components/drivers/spi/SConscript index 27b7a8dd71..e84ed7bb06 100644 --- a/components/drivers/spi/SConscript +++ b/components/drivers/spi/SConscript @@ -29,7 +29,7 @@ if GetDepend('RT_USING_SFUD'): if GetDepend('RT_SFUD_USING_SFDP'): src_device += ['sfud/src/sfud_sfdp.c'] - if rtconfig.PLATFORM in ['gcc', 'armclang']: + if rtconfig.PLATFORM in ['gcc', 'armclang', 'llvm-arm']: LOCAL_CFLAGS += ' -std=c99' elif rtconfig.PLATFORM in ['armcc']: LOCAL_CFLAGS += ' --c99' diff --git a/components/libc/compilers/common/cstring.c b/components/libc/compilers/common/cstring.c index 733433598e..59c516d273 100644 --- a/components/libc/compilers/common/cstring.c +++ b/components/libc/compilers/common/cstring.c @@ -19,10 +19,12 @@ * * @note The bzero() function is deprecated (marked as LEGACY in POSIX. 1-2001). */ +#ifndef RT_USING_PICOLIBC void bzero(void* s, size_t n) { rt_memset(s, 0, n); } +#endif void bcopy(const void* src, void* dest, size_t n) { diff --git a/components/libc/compilers/common/extension/SConscript b/components/libc/compilers/common/extension/SConscript index ddd83c8234..75bb23d18e 100644 --- a/components/libc/compilers/common/extension/SConscript +++ b/components/libc/compilers/common/extension/SConscript @@ -9,7 +9,7 @@ group = [] src += Glob('*.c') -if rtconfig.PLATFORM != 'gcc': +if rtconfig.PLATFORM != 'gcc' and rtconfig.PLATFORM != 'llvm-arm': group = DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH) list = os.listdir(cwd) diff --git a/components/libc/compilers/picolibc/README.md b/components/libc/compilers/picolibc/README.md new file mode 100644 index 0000000000..af766e7ca7 --- /dev/null +++ b/components/libc/compilers/picolibc/README.md @@ -0,0 +1,8 @@ +# PICOLIBC (LLVM-ARM) porting for RT-Thread + +https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm + +https://github.com/picolibc/picolibc + + + diff --git a/components/libc/compilers/picolibc/SConscript b/components/libc/compilers/picolibc/SConscript new file mode 100644 index 0000000000..999f7cca56 --- /dev/null +++ b/components/libc/compilers/picolibc/SConscript @@ -0,0 +1,29 @@ +import os +from building import * +from llvm_arm import * +Import('rtconfig') + +group = [] + +picolibc_version = GetPicoLibcVersion(rtconfig) + +if picolibc_version and not GetDepend('RT_USING_EXTERNAL_LIBC'): + print('PicoLibc version: ' + picolibc_version) + + cwd = GetCurrentDir() + src = Glob('*.c') + + CPPPATH = [cwd] + CPPDEFINES = ['RT_USING_PICOLIBC', 'RT_USING_LIBC', '_POSIX_C_SOURCE=1', '__PICOLIBC_ERRNO_FUNCTION=pico_get_errno'] # identify this is Newlib, and only enable POSIX.1-1990 + # LIBS = ['c', 'm'] # link libc and libm + AddDepend(['RT_USING_PICOLIBC', 'RT_USING_LIBC']) + + group = group + DefineGroup('Compiler', src, depend = [''], CPPPATH = CPPPATH, CPPDEFINES = CPPDEFINES)#, LIBS = LIBS) + + list = os.listdir(cwd) + for d in list: + path = os.path.join(cwd, d) + if os.path.isfile(os.path.join(path, 'SConscript')): + group = group + SConscript(os.path.join(d, 'SConscript')) + +Return('group') diff --git a/components/libc/compilers/picolibc/syscall.c b/components/libc/compilers/picolibc/syscall.c new file mode 100644 index 0000000000..882964a1f3 --- /dev/null +++ b/components/libc/compilers/picolibc/syscall.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-05-17 Flybreak the first version + */ + +#include + +int pico_get_errno(void) +{ + return rt_get_errno(); +} diff --git a/libcpu/arm/cortex-m4/SConscript b/libcpu/arm/cortex-m4/SConscript index b24349c4fc..3ecbea8de3 100644 --- a/libcpu/arm/cortex-m4/SConscript +++ b/libcpu/arm/cortex-m4/SConscript @@ -14,7 +14,7 @@ if rtconfig.PLATFORM in ['armcc', 'armclang']: if rtconfig.PLATFORM == 'armclang': src += Glob('*_rvds.S') -if rtconfig.PLATFORM in ['gcc']: +if rtconfig.PLATFORM in ['gcc', 'llvm-arm']: src += Glob('*_init.S') src += Glob('*_gcc.S') diff --git a/tools/llvm_arm.py b/tools/llvm_arm.py new file mode 100644 index 0000000000..e7910ce141 --- /dev/null +++ b/tools/llvm_arm.py @@ -0,0 +1,57 @@ +# +# File : llvm_arm.py +# This file is part of RT-Thread RTOS +# COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Change Logs: +# Date Author Notes +# 2023-05-17 Flybreak The first version + +import os +import re +import platform + +def GetLLVM_ARMRoot(rtconfig): + exec_path = rtconfig.EXEC_PATH + lib_path = 'lib/clang-runtimes/arm-none-eabi' + root_path = os.path.join(exec_path, '..', lib_path) + + return root_path + +def CheckHeader(rtconfig, filename): + root = GetLLVM_ARMRoot(rtconfig) + config = re.findall(r"--config (.*)\.cfg", rtconfig.CFLAGS) + if config: + fn = os.path.join(root, config[0], 'include', filename) + if os.path.isfile(fn): + return True + + return False + +def GetPicoLibcVersion(rtconfig): + version = None + root = GetLLVM_ARMRoot(rtconfig) + if CheckHeader(rtconfig, 'picolibc.h'): # get version from picolibc.h file + config = re.findall(r"--config (.*)\.cfg", rtconfig.CFLAGS) + fn = os.path.join(root, config[0], 'include', 'picolibc.h') + f = open(fn, 'r') + if f: + for line in f: + if line.find('__PICOLIBC_VERSION__') != -1 and line.find('"') != -1: + version = re.search(r'\"([^"]+)\"', line).groups()[0] + f.close() + return version