If you are familiar with the idea of Dependency Injection, the
embedded-hal serves as a collection of common interfaces the ecosystem can build on.
It's a really powerful abstraction and helps to make your code 1) platform-agnostic, and 2) testable (i.e. you can write software tests to test your business logic without bringing in the complexity of interacting with real hardware).
Yes. For something small like an arduino project you could create an
OutputPin for you device, for example the 0'th pin in GPIO A,
stm32f30x_hal::gpio::gpioa::PA0, and then set it high/low as you wish. You just need to pull in the
embedded_hal::digital::v2::OutputPin trait to get access to those methods.
embedded-hal's full power starts to show as you build larger applications with more components.
The idea is that some library author will be able to make their code generic over an interface (e.g. an output pin representing an LED) and have it work regardless of whether the underlying
OutputPin is a GPIO on your chip, a device over I2C, or the Linux GPIO subsystem.
Then as an application author, you can create an
OutputPin which is connected to your LED and create a
CountDown timer, then pass them to some generic
blinky function/crate which will implement the blinking logic.
What normally happens is the low-level code gets pushed into the implementation for your particular
OutputPin implementation, so you may write a
Stm32GpioPin that does the usual register bashing to toggle GPIO states.
Often these "drivers" will get pulled out into their own crate (e.g. see the linux implementation).