Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Clang support #2606

Merged
merged 53 commits into from
Apr 24, 2024
Merged

Add Clang support #2606

merged 53 commits into from
Apr 24, 2024

Conversation

hathach
Copy link
Owner

@hathach hathach commented Apr 23, 2024

Describe the PR

  • Clang arm support for cmake and make https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm
  • tested with most of stm32, nrf, imxrt, lpc
  • samd21/51 built but usb does not enumerated yet Fixed linker issue with clang: cannot self-check defined symbol with lld e.g STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x1000 --> STACK_SIZE = 0
  • rp2040 not ported yet, since pico-sdk does not fully support clang without some modificaiton. Will port rp2040 in a separated PR
  • also added clang build to ci

note:

  • also update nrfx to v3.4.0
  • mcxn947 somehow does not enumerate when building with gcc, probably messed up something in previous commit. will check later

- switch unit test back to gcc, since path to clang conflict on local setup (x86 and arm)
- compile nrf with __STARTUP_CLEAR_BSS and link flag -nostartfiles
fix clang build with nrf
… e.g `STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : 0x1000` --> STACK_SIZE = 0
@@ -89,7 +89,7 @@ void tuh_cdc_mount_cb(uint8_t idx) {
// while eneumerating new cdc device
cdc_line_coding_t line_coding = {0};
if (tuh_cdc_get_local_line_coding(idx, &line_coding)) {
printf(" Baudrate: %lu, Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
printf(" Baudrate: %" PRIu32 ", Stop Bits : %u\r\n", line_coding.bit_rate, line_coding.stop_bits);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gcc print format for uint32_t is %lu while clang is %u, should use PRIu32 to prevent format warning

# nanolib
--specs=nosys.specs
--specs=nano.specs
-nostartfiles
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't depend on gcc/clang start file (crt0). Need to define __STARTUP_CLEAR_BSS for start up to clear .bss . This also applies to other nxp mcu as well as nrf


/* hathach add heap section for clang */
.heap (NOLOAD): {
__heap_start = .;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

old lpc didn't define __heap_start/__heap_end for use with clang libc

PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RamLoc32 - 0);

/* ## Create checksum value (used in startup) ## */
/* This cause issue with clang linker, so it is disabled */
/* MemManage_Handler, BusFault_Handler, UsageFault_Handler may not be defined */
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed since this cause lld issue (either operant must be absolute address or somethin)

@@ -1,7 +1,7 @@
/* Linker script to configure memory regions. */

SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these group libgcc must be removed since not available in clang

/* Linker script to configure memory regions. */

SEARCH_DIR(.)
/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libgcc is not available in clang, since ld in nrfx/mdk contains this, we must keep an copy of lds just to remove this line


INCLUDE "nrf_common.ld"

/* nrfx v2 linker does not define __tbss_start/end__ __sbss_start/end__*/
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug in nrfx v2 linker that does not define these symbole for defining __STARTUP_CLEAR_BSS. This is fixed and not required with nrfx v3

@@ -40,7 +40,7 @@ MEMORY
}

/* The stack size used by the application. NOTE: you need to adjust according to your application. */
STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000;
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x2000;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang linkder does not seem to support self-check defined for symbol, if not change, result is STACK_SIZE = 0

/* Memories definition */
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 128K
}

/* Highest address of the user mode stack */
_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang: symbol (_estack) must be defined memory section properties after defining MEMORY section first. For this reason, we must keep local copy stm32 ld files, since many of them from stm cmsis repo use this style

@@ -743,7 +743,7 @@ EmbeddedCli *embeddedCliNew(EmbeddedCliConfig *config) {

bool allocated = false;
if (config->cliBuffer == NULL) {
config->cliBuffer = (CLI_UINT *) malloc(totalSize); // malloc guarantees alignment.
// config->cliBuffer = (CLI_UINT *) malloc(totalSize); // malloc guarantees alignment.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove malloc/free usage since we use static allocation anyway. This prevent linker to try to find libc, heap start/end symbols.

@@ -118,7 +119,7 @@ static struct {
xfer_td_t xfer[EP_CBI_COUNT + 1][2];

// nRF can only carry one DMA at a time, this is used to guard the access to EasyDMA
atomic_bool dma_running;
atomic_flag dma_running;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

clang is picky, only alow using atomic_flag_ function with atomic_flag and not atomic_bool

@@ -81,20 +81,20 @@

:tools:
:test_compiler:
:executable: clang
:name: 'clang compiler'
:executable: gcc
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change unit test compiler to gcc, since clang (x86 target) conflict with my clang arm target

@hathach hathach merged commit 313d966 into master Apr 24, 2024
134 checks passed
@hathach hathach deleted the build-clang branch April 24, 2024 16:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant