/stm32f42_discovery_demo

A simple demonstration of using D to bare-metal program an STM32F29I Discovery board

Primary LanguageDGNU Lesser General Public License v3.0LGPL-3.0

stm32f42_discovery_demo

A simple demonstration of using D to bare-metal program an STM32F29I Discovery Board

Download Video

The Good

with(GPIOA.MODER)
{
	setValue
	!(
		  MODER3,  0b10  // Alternate function mode
		, MODER4,  0b10
		, MODER6,  0b10
		, MODER11, 0b10
		, MODER12, 0b10
	);
}
  • Seems to be pretty fast, but I still need to verify the generated code to ensure optimizations are being performed properly
  • Small Code Size (6k). The data in the BSS segment is my LCD's frame buffer, so that really doesn't count.
text       data     bss     dec      hex   filename
6200       0        153600  159800   27038 binary/firmware
  • The code resembles the register descriptions in the STM32 reference manual for easy cross-referencing.
  • Good integration with tooling. e.g Register descriptions in DDoc popups, and register layout in outline and code completion windows. In other words, the code is the datasheet.

The Bad

  • The implementation of D runtime is minimal, and therefore very incomplete. Many features of D are not usable.
  • volatileLoad/volatileStore were added in 2.067.0, but that has not yet been merged into GDC. For now, I'm misusing GDC's shared bug as a feature. See code.
  • Due to bug 12496, I can't enforce that a Bitfield belongs to a Register when using the setValue template.
  • Really long build times (Nearly 2 minutes to generate a 6k binary!). I suspect that is due to my liberal use of D's metaprogramming and compile-time features.

The Ugly

  • I didn't put much diligence and care into some of the code, because I was anxious to just get something to appear on the LCD screen. There are a lot of magic numbers that should be enums, and there is no hardware abstraction layer - the program directly manipulates the memory-mapped IO registers.
  • TypeInfo faking. Potential solution
  • The compiler generates a TypeInfo.name string for each and every bitfield in my code, and puts it in the rodata segment. Due to GCC bug 192, -fdata-sections doesn't put this data in its own section, so my binary becomes more than 400k. See this discussion for details. So, I added a sed hack to my build script put these strings in their own sections, and that brings my binary down to around 5-6k. But it's not perfect and sometimes results in removing strings that are needed.
  • Using an unimplemented druntime feature will result in a linker error, at best, instead of a compiler error. Potential solution.
  • I have to put a .value every time I want to access a memory-mapped IO bitfield. This is because there is no static alias x this; in D's static opAssign isn't symetric. I think if I were to do this again, I would use a different pattern altogether.