Skip to content
This repository has been archived by the owner on Sep 15, 2022. It is now read-only.

Why do we use objects for storing global state (like STM32F746GDiscovery)? #559

Open
kasperl opened this issue Jun 30, 2016 · 4 comments
Open

Comments

@kasperl
Copy link
Contributor

kasperl commented Jun 30, 2016

Right now, we insist on all users of important system wide properties to first create an instance of a specific class through something like new STM32F746GDiscovery(). Why?

Does it make sense for two such objects to co-exist within the same process? How much state does the objects you can grab hold from from the STM32F746GDiscovery instance have?

I think most users would prefer this kind of board-support library:

library stm32.stm32f746g_discovery;
final Gpio gpio = new STM32Gpio();
final FrameBuffer frameBuffer = new FrameBuffer();
...

or maybe even insist on making all the objects involved compile-time constants that hold any necessary state in static fields.

@jakobr-google
Copy link
Contributor

The main 'board' should really be a singleton.

There's not much state in these objects (since most of it's held in the hardware), but it doesn't really make sense to have more than one instance (per hardware unit - one board might have 3 ADC units, for example).

I'm not sure I'd make them complete compile-time constants, though, since that'll tie the code that uses them to a specific implementation.

What I'd really like, is to be able to inject the concrete board-specific class at compile time, maybe through a project/hardware manifest, so the rest of the code can be as generic as possible, making it easier to support multiple boards with the same application code.

@sigurdm
Copy link
Contributor

sigurdm commented Jul 1, 2016

I think having a main library per board that passes a board-object to the rest of the program is the right way to 'inject' the dependency.

@sgjesse
Copy link
Contributor

sgjesse commented Jul 6, 2016

I agree that having board objects as instantiatable objects is not the right solution. Having more than one instance (of any board) in a given application does not make sense.

We might use Interface Libraries (configuration specific imports) to abstract over board differences to create a program that can run on several boards.

File board_interface.dart

import 'package:gpio/gpio.dart';
// Main LED.
GpioOutputPin get led {}

File board.dart

export 'board_interface.dart'
    if (board.stm32f746g_discovery) 'board_stm32f746g_discovery.dart'
    if (board.stm32f411re_nucleo) 'board_stm32f411re_nucleo.dart'
    show led;

File board_stm32f746g_discovery.dart

import 'package:stm32/stm32f746g_disco.dart';
// Use LED1 as main LED.
final led = gpio.initOutput(LED1);

File board_stm32f411re_nucleo.dart

import 'package:stm32/stm32f411re_nucleo.dart';
// Use LED2 as main LED.
final led = gpio.initOutput(LED2);

And the main program

import 'dart:dartino'
import 'board.dart'
main() {
  led.toggle();
  sleep(500);
}

The passing either -Dboard.stm32f746g_discovery or -Dboard.stm32f411re_nucleo at compile-time should make the main file compile for both boards.

If we get the board selection integrated into the compilation/project setup the the -D options should be set automatically when compiling from project configuration.

@karlklose
Copy link
Contributor

Another solution to allow for generic programs is to make the board classes form a class hierarchy and have a factory constructor instatiate the concrete object using an environment constant. For example, new Stm32Board() would return either a Stm32F7DiscoveryBoard or Stm32F411RENucleoBoard (depending on the target platform specified), but a new Stm32F411RENucleoBoard would throw an error if the STM32F746G board is specified as target.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Development

No branches or pull requests

5 participants