diff --git a/bsp/stm32/stm32l475-atk-pandora/board/SConscript b/bsp/stm32/stm32l475-atk-pandora/board/SConscript index 97c31ee844847ea92fadda573ae1ad81b9feef65..513aa8598a358f61c8f4e60ae505b0244fc8c926 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 af29494a89cf70f0dd3bb2afd5c0f6bfdd7aa172..6b54a18e1a3f10f06131cb8700e20d26c279ec21 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 27b7a8dd71fed60a2d8cfa554b48ef8db340d0bb..e84ed7bb066fe57065e7308925e84dd1c5943120 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 733433598e26c077aa5d81d848357f76539de30a..59c516d273e80d24b8aee4713ba841ce4261498a 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 ddd83c82345099dab6b633e5b0c4a5457cb00c04..75bb23d18e229b51d2bdd9c8d02109edec844870 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 0000000000000000000000000000000000000000..af766e7ca73690573f33d4caf69ab899742a464f --- /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 0000000000000000000000000000000000000000..999f7cca561f6589f19f00597e4623a680771e36 --- /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 0000000000000000000000000000000000000000..882964a1f3c07bb4885d86b0342a941e847b5593 --- /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 b24349c4fc7f3d55d9cb215b5a8a1495e384294f..3ecbea8de35577ec036d530e8d622601b16ed62e 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 0000000000000000000000000000000000000000..e7910ce141a26a4f663dd4e49f5423faec31f0e1 --- /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