Thread overview | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
November 24, 2013 Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
I am very new to D, but I finally got my toolchain compiled and working. I'm using LDC. I failed with GDC and eventually gave up. I am trying to get an _extremely_ minimal bare metal ARM Cortex-M HelloWorld-type program (no phobos, no runtime, nothing but what I type myself) compiled and executed on my STM32F4-based hardware. I know the toolchain is buggy for arm right now, but I'm hoping I can do something about that if I can just get started. Here's the basic C code and linker script for my hardware. It doesn't actually print "hello world". I intend to add that after I get the following code compiled and downloaded to my hardware. /*************************** * start.c ****************************/ // defined in linker script extern unsigned long _stack_end; void handler_reset(void) { //Print hello world using SWI } __attribute__ ((section(".interrupt_vector"))) void (* const table_interrupt_vector[])(void) = { (void *) &_stack_end, handler_reset }; /*************************** * linkerscript.ld ****************************/ MEMORY { CCRAM (rxw) : ORIGIN = 0x10000000, LENGTH = 64k SRAM (rxw) : ORIGIN = 0x20000000, LENGTH = 128k FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024k } _stack_end = ORIGIN(CCRAM) + LENGTH(CCRAM); SECTIONS { .isr_vector : { . = ALIGN(4); KEEP(*(.isr_vector)) . = ALIGN(4); } >FLASH .text : { . = ALIGN(4); KEEP(*(.interrupt_vector)) *(.text) *(.text*) *(.rodata) *(.rodata*) . = ALIGN(4); } > flash } Can anyone out them tell me if/how this can be accomplished in D? Is there some syntax equivalent to __attribute__ ((section(".interrupt_vector")))? Would the following give me a minimal reset_handler? // compile with: ldc2 -c -nodefaultlib -noruntime module reset_handler; extern(C) __gshared void * _Dmodule_ref; extern(C) void reset_handler() { } I've seen some examples out on the web, but they all either use C, or are written specifically for an x86/x86_64 platform. So any help you could provide would be great to help me get started. |
November 24, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike | On Sunday, 24 November 2013 at 13:00:39 UTC, Mike wrote:
> Is there some syntax equivalent to __attribute__ ((section(".interrupt_vector")))?
There isn't right now, but it would be entirely feasible to implement this in an LDC-specific extension. Could you open an issue on our GitHub tracker?
David
|
November 24, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | On Sunday, 24 November 2013 at 13:30:10 UTC, David Nadlinger wrote: > On Sunday, 24 November 2013 at 13:00:39 UTC, Mike wrote: >> Is there some syntax equivalent to __attribute__ ((section(".interrupt_vector")))? > > There isn't right now, but it would be entirely feasible to implement this in an LDC-specific extension. Could you open an issue on our GitHub tracker? > > David https://github.com/ldc-developers/ldc/issues/547 |
November 24, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike | On Sunday, 24 November 2013 at 14:10:54 UTC, Mike wrote: > On Sunday, 24 November 2013 at 13:30:10 UTC, David Nadlinger wrote: >> On Sunday, 24 November 2013 at 13:00:39 UTC, Mike wrote: >>> Is there some syntax equivalent to __attribute__ ((section(".interrupt_vector")))? >> >> There isn't right now, but it would be entirely feasible to implement this in an LDC-specific extension. Could you open an issue on our GitHub tracker? >> >> David > > https://github.com/ldc-developers/ldc/issues/547 A full working example for gdc and cortex-m4 (stm32f4) is in my repo at https://bitbucket.org/timosi/minlibd I have used startup file from st and have no need to put interrupt vectors in d code. |
November 25, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timo Sintonen | On Sunday, 24 November 2013 at 20:00:56 UTC, Timo Sintonen wrote: > A full working example for gdc and cortex-m4 (stm32f4) is in my repo at > https://bitbucket.org/timosi/minlibd > > I have used startup file from st and have no need to put interrupt vectors in d code. Thanks Timo, your minlibd is awesome, and will be my next object of study. I already know how do do what you did with assembly and C, but my goal is not just to get something working, but to learn what can and can't be done with D. minlibd uses an assembly startup file and calls into C functions to set up the clock, flash, etc... That works, and may be the only (best?) way to go. But I'd like to explore and learn what limitations exist in the D language and the D tools. If the LDC folks add a section-attribute-like feature, then I believe it should be possible to do away with the assembly startup file, and put the vectors, data section relocation, and bss initialization all in D, and that appeals to me. I'm wondering, though, if the vector table's simple name could be added to the text section. Then the attribute syntax would be unnecessary. Something like this: void (* const table_interrupt_vector[])(void) = { (void *) &_stack_end, handler_reset }; .text : { . = ALIGN(4); *(.text.table_interrupt_vector) *(.text) *(.text*) *(.rodata) *(.rodata*) . = ALIGN(4); } > flash ...but maybe the symbol will be added twice. Unfortunately I won't be home for a few more days to try it out. According to LDs docs, execution should default to the start of text, and if I could just figure out how to make sure table_interrrupt_vector is there, that would basically be it. |
November 30, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike | I finally succeeded in doing what I set out to do: Write a simple hello world program for an ARM Cortex-M processor using ONLY D. /************************* * The D Program (start.d) *************************/ module start; import ldc.llvmasm; extern(C) __gshared void * _Dmodule_ref; //Must be stored as second 32-bit word in .text section immutable void function() ResetHandler = &OnReset; void SendCommand(int command, void* message) { __asm ( "mov r0, $0; mov r1, $1; bkpt #0xAB", "r,r,~{r0},~{r1}", command, message ); } void OnReset() { while(true) { // Create semihosting message message uint[3] message = [ 2, //stderr cast(uint)"hello\r\n".ptr, //ptr to string 7 //size of string ]; //Send semihosting command SendCommand(0x05, &message); } } /***************************** * The Linker Script (link.ld) *****************************/ MEMORY { CCRAM (rxw) : ORIGIN = 0x10000000, LENGTH = 64k SRAM (rxw) : ORIGIN = 0x20000000, LENGTH = 128k FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024k } _stackStart = ORIGIN(CCRAM) + LENGTH(CCRAM); SECTIONS { .text : { LONG(_stackStart); /* Initial stack pointer */ KEEP(start.o(.data.rel.ro)) /* Internet vector table */ /* the code */ *(.text) *(.text*) /* for "hello\r\n" string constant */ . = ALIGN(4); *(.rodata) *(.rodata*) }>FLASH /* Need .data, .bss, .ctors and probably more as program becomes More complex */ } Tools used: Operating System: Arch Linux 64-bit Compiler: LDC (2063b4) Linker & Binary Utilities & Debugger: GNU Tools for ARM Embedded Processors (https://launchpad.net/gcc-arm-embedded) JTAG Emulator: JTAG-lock-pick Tiny 2 w/ OpenOCD 0.7.0 To compile: ldc2 -march=thumb -mcpu=cortex-m4 -noruntime -nodefaultlib -c start.d To link: arm-none-eabi-ld -T link.ld --gc-sections start.o -o start.elf To execute: openocd -f interface/jtag-lock-pick_tiny_2.cfg -f target/stm32f4x.cfg arm-none-eabi-gdb start.elf .. in GDB: target remote localhost:3333 monitor arm semihosting enable monitor reset halt load monitor reset init continue Output: hello hello ... Code Size: 148 bytes (not bad) Why I think this is significant: 1. It shows D can write the most low level of programs and does not require an operating system 2. It shows that the D runtime and D standard library are not mandatory and do not need to be fully ported to one's platform to begin programming ARM Cortex-M bare metal hardware in D (although this is not the first to do so: https://bitbucket.org/timosi/minlibd) 3. It shows linking to C code and assembly files are optional 4. It shows the tools are capable (although they have not been well exercised in this example) and more specifically MY toolchain is working. 5. It's a great start to writing very embedded systems in D, or more importantly, not C/C++ (good riddance!) What's next for me: 1. Get a GDC toolchain working, although I'll probably switch to LDC when LDC matures. 2. Learn more about D. 3. Study minlibd and the d runtime and program the bare essentials to make D a productive language for the ARM Cortex-M. 4. Help the D community help me, by testing the toolchains for the ARM Cortex-M platform and file bug reports. Thanks to those who commented on my previous posts. I'm quite excited about this language. |
November 30, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Attachments:
| On Nov 30, 2013 11:40 AM, "Mike" <none@none.com> wrote: > > I finally succeeded in doing what I set out to do: Write a simple hello world program for an ARM Cortex-M processor using ONLY D. > > /************************* > * The D Program (start.d) > *************************/ > module start; > > import ldc.llvmasm; > > > extern(C) __gshared void * _Dmodule_ref; > > //Must be stored as second 32-bit word in .text section immutable void function() ResetHandler = &OnReset; > > void SendCommand(int command, void* message) > { > __asm > ( > "mov r0, $0; > mov r1, $1; > bkpt #0xAB", > "r,r,~{r0},~{r1}", > command, message > ); > } > > void OnReset() > { > while(true) > { > // Create semihosting message message > uint[3] message = > [ > 2, //stderr > cast(uint)"hello\r\n".ptr, //ptr to string > 7 //size of string > ]; > > //Send semihosting command > SendCommand(0x05, &message); > } > } > > /***************************** > * The Linker Script (link.ld) > *****************************/ > > MEMORY > { > CCRAM (rxw) : ORIGIN = 0x10000000, LENGTH = 64k > SRAM (rxw) : ORIGIN = 0x20000000, LENGTH = 128k > FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024k > } > > _stackStart = ORIGIN(CCRAM) + LENGTH(CCRAM); > > SECTIONS > { > .text : > { > LONG(_stackStart); /* Initial stack pointer */ > KEEP(start.o(.data.rel.ro)) /* Internet vector table */ > > /* the code */ > *(.text) > *(.text*) > > /* for "hello\r\n" string constant */ > . = ALIGN(4); > *(.rodata) > *(.rodata*) > }>FLASH > > /* Need .data, .bss, .ctors and probably more as program becomes > More complex */ > } > > Tools used: > Operating System: Arch Linux 64-bit > Compiler: LDC (2063b4) > Linker & Binary Utilities & Debugger: GNU Tools for ARM Embedded Processors (https://launchpad.net/gcc-arm-embedded) > JTAG Emulator: JTAG-lock-pick Tiny 2 w/ OpenOCD 0.7.0 > > To compile: > ldc2 -march=thumb -mcpu=cortex-m4 -noruntime -nodefaultlib -c start.d > > To link: > arm-none-eabi-ld -T link.ld --gc-sections start.o -o start.elf > > To execute: > openocd -f interface/jtag-lock-pick_tiny_2.cfg -f target/stm32f4x.cfg > arm-none-eabi-gdb start.elf > > .. in GDB: > target remote localhost:3333 > monitor arm semihosting enable > monitor reset halt > load > monitor reset init > continue > > Output: > hello > hello > ... > > Code Size: 148 bytes (not bad) > > Why I think this is significant: > 1. It shows D can write the most low level of programs and does not require an operating system > 2. It shows that the D runtime and D standard library are not mandatory and do not need to be fully ported to one's platform to begin programming ARM Cortex-M bare metal hardware in D (although this is not the first to do so: https://bitbucket.org/timosi/minlibd) > 3. It shows linking to C code and assembly files are optional > 4. It shows the tools are capable (although they have not been well exercised in this example) and more specifically MY toolchain is working. > 5. It's a great start to writing very embedded systems in D, or more importantly, not C/C++ (good riddance!) > > What's next for me: > 1. Get a GDC toolchain working, although I'll probably switch to LDC when LDC matures. > 2. Learn more about D. > 3. Study minlibd and the d runtime and program the bare essentials to make D a productive language for the ARM Cortex-M. > 4. Help the D community help me, by testing the toolchains for the ARM Cortex-M platform and file bug reports. > > Thanks to those who commented on my previous posts. I'm quite excited about this language. In before the "that's not D! That's some D, a bit of some extended inline assembly, and a custom linker script." Congrats though. :) Regards -- Iain Buclaw *(p < e ? p++ : p) = (c & 0x0f) + '0'; |
November 30, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike | On Saturday, 30 November 2013 at 11:37:25 UTC, Mike wrote: > What's next for me: > 1. Get a GDC toolchain working, although I'll probably switch to LDC when LDC matures. > 2. Learn more about D. > 3. Study minlibd and the d runtime and program the bare essentials to make D a productive language for the ARM Cortex-M. > 4. Help the D community help me, by testing the toolchains for the ARM Cortex-M platform and file bug reports. > > Thanks to those who commented on my previous posts. I'm quite excited about this language. Congratulations from me too. I just put my old gdc cross compiler instructions in the wiki: https://bitbucket.org/timosi/minlibd/wiki/gdc_cross_compiler If you are not going to have your own repository, feel free to send pull requests to me. |
December 01, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike | On Saturday, 30 November 2013 at 11:37:25 UTC, Mike wrote: > I finally succeeded in doing what I set out to do: Write a simple hello world program for an ARM Cortex-M processor using ONLY D. That's some nice progress indeed! Would you mind transferring your excellent description of the process to the D wiki and link it from http://wiki.dlang.org/LDC? This way, it would be easier to find in a few months than an old forum post. David |
December 02, 2013 Re: Need help making minimal bare metal ARM Cortex-M D program | ||||
---|---|---|---|---|
| ||||
Posted in reply to David Nadlinger | > Would you mind transferring your excellent description of the process to the D wiki and link it from http://wiki.dlang.org/LDC? This way, it would be easier to find in a few months than an old forum post. > > David http://wiki.dlang.org/Extremely_minimal_semihosted_%22Hello_World%22 |
Copyright © 1999-2021 by the D Language Foundation