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

Compiling cdc_msc example for SAMD21G18 works fine using -O0 but hangs using -O1 #303

Closed
jeremyherbert opened this issue Mar 21, 2020 · 10 comments · Fixed by #312
Closed
Labels

Comments

@jeremyherbert
Copy link
Contributor

I'm trying to port tinyusb to the seeeduino xiao which uses the SAMD21G18A. Since this is the same chip as the feather_m0_express I used it as a template to begin. I've made the following changes:

  • Rename feather_m0_express.c to seeeduino_xiao.c
  • Edit seeeduino_xiao.c, changing the button and LED pin, as well as deleting the code which configures the clock output
  • Edit samd21g18a_flash.ld to set the ROM base address to 0x00000000, length 0x00040000 (this is because I am debugging with a J-Link and don't care about the bootloader for the time being).

If I build the cdc_msc example with any optimisation level other than -O0, the code just hangs. According to my JLink, it's just spinning in the Dummy_Handler function. With -O0 everything works fine.

Will try to work out which interrupt is firing.

@jeremyherbert
Copy link
Contributor Author

Ok, it's a hardfault. But it seems like it is to do with the JLink programming itself; if I power cycle the microcontroller after programming it works fine...

@hathach
Copy link
Owner

hathach commented Mar 21, 2020

you should check your vector ISR table, probably put atttribute((used)) in the proper place of isr vector to prevent it is optimized out.

@cr1901
Copy link
Collaborator

cr1901 commented Mar 21, 2020

I can't tell whether this applies, but last time I had a problem like this, it was because I forgot to manually mark some I/O addresses as volatile: #97 (comment)

@jeremyherbert
Copy link
Contributor Author

This is a bug in the J-Link tools, not in tinyusb.

@jeremyherbert
Copy link
Contributor Author

Turns out this is not a bug in the segger tools, but rather a dud linker script provided by Atmel/Microchip. The script does not set the entry point of the code correctly, so it defaults to zero in the elf header. It is should be set to the address of Reset_Handler. I added the missing line in my pull request (#306) for this board:

This problem appears to be present in at least the feather_m0_express linker file.

The hardfault was because the PC was being set to 0 after reset, which meant that the CPU was trying to decode the vector table as instructions.

@jeremyherbert jeremyherbert reopened this Mar 23, 2020
@hathach
Copy link
Owner

hathach commented Mar 23, 2020

Thanks for the findout, I will check and fix the feather m0 and/or other m0 boards as well.

@hathach
Copy link
Owner

hathach commented Mar 28, 2020

I checked, but with and without

 ENTRY(Reset_Handler) 

The address of Reset_Handler doesn't change at all. Adding this is right thing to do, though I am curious which version gcc/toolchain you are using, and your OS as well.

@jeremyherbert
Copy link
Contributor Author

arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 9-2019-q4-major) 9.2.1 20191025 (release) [ARM/arm-9-branch revision 277599]
Linux ubuntu 5.3.0-42-generic #34~18.04.1-Ubuntu SMP Fri Feb 28 13:42:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

using arm-none-eabi-readelf -e seeeduino_xiao-firmware.elf, if I have the line commented out it sets the entry point to the start of the vector table (0x2000 as it is leaving the first 8kB for the bootloader), not the address of Reset_Handler:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x2000 <<<<<<<<<<<<<<<<<<<<<<<<<< BAD
  Start of program headers:          52 (bytes into file)
  Start of section headers:          310276 (bytes into file)
  Flags:                             0x5000200, Version5 EABI, soft-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         18
  Section header string table index: 17

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00002000 002000 0025f0 00  AX  0   0  4
  [ 2] .relocate         REL             20000000 010000 002018 08  WA  0   0  4
  [ 3] .bss              NOBITS          20002018 012018 000614 00  WA  0   0  4
  [ 4] .stack            NOBITS          2000262c 012018 002004 00  WA  0   0  1
  [ 5] .debug_info       PROGBITS        00000000 012018 01e7f0 00      0   0  1
  [ 6] .debug_abbrev     PROGBITS        00000000 030808 002be4 00      0   0  1
  [ 7] .debug_loc        PROGBITS        00000000 0333ec 006e01 00      0   0  1
  [ 8] .debug_aranges    PROGBITS        00000000 03a1ed 0001c0 00      0   0  1
  [ 9] .debug_ranges     PROGBITS        00000000 03a3ad 001478 00      0   0  1
  [10] .debug_line       PROGBITS        00000000 03b825 006849 00      0   0  1
  [11] .debug_str        PROGBITS        00000000 04206e 006188 01  MS  0   0  1
  [12] .comment          PROGBITS        00000000 0481f6 000079 01  MS  0   0  1
  [13] .ARM.attributes   ARM_ATTRIBUTES  00000000 04826f 00002a 00      0   0  1
  [14] .debug_frame      PROGBITS        00000000 04829c 0005e4 00      0   0  4
  [15] .symtab           SYMTAB          00000000 048880 0029f0 10     16 622  4
  [16] .strtab           STRTAB          00000000 04b270 0008de 00      0   0  1
  [17] .shstrtab         STRTAB          00000000 04bb4e 0000b6 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x045f0 0x045f0 R E 0x10000
  LOAD           0x010000 0x20000000 0x000045f0 0x02018 0x04630 RW  0x10000

 Section to Segment mapping:
  Segment Sections...
   00     .text 
   01     .relocate .bss .stack

And with the entry point line it correctly points to the Reset_Handler function:

ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x3525  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< CORRECT
  Start of program headers:          52 (bytes into file)
  Start of section headers:          310276 (bytes into file)
  Flags:                             0x5000200, Version5 EABI, soft-float ABI
  Size of this header:               52 (bytes)
  Size of program headers:           32 (bytes)
  Number of program headers:         2
  Size of section headers:           40 (bytes)
  Number of section headers:         18
  Section header string table index: 17

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00002000 002000 0025f0 00  AX  0   0  4
  [ 2] .relocate         REL             20000000 010000 002018 08  WA  0   0  4
  [ 3] .bss              NOBITS          20002018 012018 000614 00  WA  0   0  4
  [ 4] .stack            NOBITS          2000262c 012018 002004 00  WA  0   0  1
  [ 5] .debug_info       PROGBITS        00000000 012018 01e7f0 00      0   0  1
  [ 6] .debug_abbrev     PROGBITS        00000000 030808 002be4 00      0   0  1
  [ 7] .debug_loc        PROGBITS        00000000 0333ec 006e01 00      0   0  1
  [ 8] .debug_aranges    PROGBITS        00000000 03a1ed 0001c0 00      0   0  1
  [ 9] .debug_ranges     PROGBITS        00000000 03a3ad 001478 00      0   0  1
  [10] .debug_line       PROGBITS        00000000 03b825 006849 00      0   0  1
  [11] .debug_str        PROGBITS        00000000 04206e 006188 01  MS  0   0  1
  [12] .comment          PROGBITS        00000000 0481f6 000079 01  MS  0   0  1
  [13] .ARM.attributes   ARM_ATTRIBUTES  00000000 04826f 00002a 00      0   0  1
  [14] .debug_frame      PROGBITS        00000000 04829c 0005e4 00      0   0  4
  [15] .symtab           SYMTAB          00000000 048880 0029f0 10     16 621  4
  [16] .strtab           STRTAB          00000000 04b270 0008de 00      0   0  1
  [17] .shstrtab         STRTAB          00000000 04bb4e 0000b6 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  y (purecode), p (processor specific)

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  LOAD           0x000000 0x00000000 0x00000000 0x045f0 0x045f0 R E 0x10000
  LOAD           0x010000 0x20000000 0x000045f0 0x02018 0x04630 RW  0x10000

 Section to Segment mapping:
  Segment Sections...
   00     .text 
   01     .relocate .bss .stack 

@hathach
Copy link
Owner

hathach commented Mar 28, 2020

@jeremyherbert ah yeash, you are right, I wasn't doing the correct checking readelf is more precise.

Reset_Handler is at 00002fb9

$ nm _build/build-metro_m0_express/metro_m0_express-firmware.elf | grep Reset
00002fb9 T Reset_Handler

readelf without ENTRY(Reset_Handler), entry point is 0x2000 which is not Correct

$ arm-none-eabi-readelf -e _build/build-metro_m0_express/metro_m0_express-firmware.elf
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x2000 

readelf WITH addition of ENTRY(Reset_Handler), entry point is spot on with ResetHandler from nm

$ arm-none-eabi-readelf -e _build/build-metro_m0_express/metro_m0_express-firmware.elf
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           ARM
  Version:                           0x1
  Entry point address:               0x2fb9

@hathach
Copy link
Owner

hathach commented Mar 29, 2020

thank you for reporting the issue, I have updated the linker for all samd board to include ENTRY . It seems no harm to use on Adafruit board since bootloader takes care of entry point. Without bootloader, it could run into hardfault since gcc doesn't emit the correct code to the entry.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants