2018-06-09 06:42 AM
I understand that programming enterprise software on a 8 core CPU with 4GHz and a simple STM32 MCU is different, nevertheless I would have added a few things to the HAL layer from the beginning:
Wouldn't such things help greatly to get started? And to debug? And make the user experience better? And lower frustrations? And cause proper error messages rather than simply not working?
Or am I missing something.
Note: this post was migrated and contained many threaded conversations, some content may be missing.2018-06-15 02:10 AM
Old guys on a trip down the memory lane ...
I know PL/M and ALGOL merely from books, never had access to machine running such heavy stuff at that times. But I barely escaped FORTRAN at my unversity, and got 'teached' the hot new C. Not really learned anything I didn't already know, though.
Basically I agree with Vlad - code generators, even for hardware-level MCU code - will be the future. But ST's CubeMX will not. The quality of every release shows there are too many unilluminated hands involved. Which makes me believe the code generator is not based on a formal/abstract description of the MCU and peripherals (kind of RTL or GIMPLE), but rather manned by a hand-crafted repository.
Never heard of BLISS before either.
2018-06-15 03:10 AM
Actually, I'm not interested in hiding the hardware details at all - I want to understand them better. I just don't want to wade through them all the time. The existing tools and libraries are much less helpful than they could be for many mundane tasks which are essentially boiler plate for most of my projects, and which frequently baffle newcomers to the platform, leading to many questions in this forum. The generated code should be sufficiently readable that it will educate the interested.
I really like the idea of something like CubeMX, but its implementation is simply dreadful. Why can it only generate C code in terms of HAL (also dreadful)? Why not C++ using CMSIS, or <YourFavouritLibrary>, or even Rust? Configuring the hardware is completely orthogonal to the generated implementation, so why not exploit this? One approach to this might be to have several alternative suites/libraries of driver plugins, with each library resting on some common base code or an application framework. One library might generate everything in terms of CMSIS, another SPL, and so on. No one is forced down any particular path, and the platform is open to new developments. I wanted this tool to appeal to experienced no-libraries types as well as to newbies and Arduino coders. The point is to create a productivity tool which genuinely enhances productivity, and without generating horrible code should not be used in production.
I'm not too worried about a proliferation of driver APIs. I've used enough large widget libraries over the years of which I needed only a tiny fraction. Who cares that there are ten thousand driver classes, so long as there is one which implements that buffered DMA UART you need for your project? This seems preferable to every developer having to independently re-invent every wheel. And if the library doesn't contain just the widget you need, write your own based on what there is, and optionally add it to the library. I don't know about this being my calling. I'm just an old fart with some ideas that may or may not be worth pursuing.Al
2018-06-15 03:24 AM
I'm not familiar with Cypress PSOC Creator, but that does look very interesting. Does the diagram approach expose *all* the capabilities of the hardware?
2018-06-15 04:09 AM
The basic idea is: Machines are better than humans in repetitive works.
You may refer to the references every day and read the paragraphs several times. If you convert them in tabular forms, database engines can read this tables in short time.
I had successful experiences with using Access instead of Excel in petrochemical-plant design. Saving time was amazing. An hour instead of a month!
ST Company can employ special engineers to carry out this process. The results may be astounding, but I'm sure ST will win the MCU market.
2018-06-15 04:43 AM
Basically I agree with Vlad - code generators, even for hardware-level MCU code - will be the future.
Then the Future is Here.
http://www.st.com/content/st_com/en/about/media-center/press-item.html/n4052.html
Honestly, guys, please, take your great ideas and go coding, 'cos I don't want to pay for them.
JW
2018-06-15 06:17 AM
Not sure I understand how that works, but I like the idea of static checking.
I've been working on using C++ templates to represent the hardware more directly in a type safe manner, and to capture maps of the metadata such as GPIO alternate functions, and DMA stream/channels. Every peripheral is represented by a distinct type so, for example, I can use a type function to map the each peripheral to the correct clock bit in RCC. Similarly for mapping IRQ numbers, alternate functions, and whatnot. The goal is a replacement for CMSIS which is easily understandable in terms of the reference manual, and which gives compilation errors when mistakes are made. At least, it would be nice to have static assertions which check that PinX is correct for TimerY ChannelZ, and that sort of thing.
Probably sounds hideous. But everything is resolved at compile time, and the optimiser outputs very efficient code. Simple example. This is working code:
// Very simple driver template
template <typename GPIO, typename GPIO::Pin PIN>
class DigitalOutput
{
public:
DigitalOutput()
{
// Peripheral base address used to determine RCC AHB index.
RCC::AHBENR.EN[RCCClock<GPIO::ADDR>::index] = true;
GPIO::MODER.MODE[PIN] = GPIO::Mode::Output;
GPIO::OSPEEDR.OSPEED[PIN] = GPIO::OSpeed::High;
GPIO::OTYPER.OTYPE[PIN] = GPIO::OType::PushPull;
GPIO::PUPDR.PUPD[PIN] = GPIO::PuPd::PullUp;
reset();
}
void set() { GPIO::ODR.OD[PIN] = true; }
void reset() { GPIO::ODR.OD[PIN] = false; }
void toggle() { bool val = GPIO::ODR.OD[PIN]; GPIO::ODR.OD[PIN] = !val; }
};
// Driver instances
DigitalOutput<GPIOD, GPIOD::Pin::Pin14> led1;
DigitalOutput<GPIOC, GPIOC::Pin::Pin12> led2;
int main()
{
led1.set();
...
}
It's a work in progress: promising but very early stages. One of the issues is how to extend support to multiple processors without compromising the specificity of the supported features. My preference is for the library to be generated: choose your processor; generate the library with some tool; use the library... To port the program to another processor: regenerate the library; recompile your code; maybe there are errors from using features which don't exist on the new target.
I realise not everyone loves C++, of course.
Al2018-06-15 06:58 AM
Who cares that there are ten thousand driver classes, so long as there is one which implements that buffered DMA UART you need for your project? This seems preferable to every developer having to independently re-invent every wheel.
This your quote is your reply to your first sentence:
Actually, I'm not interested in hiding the hardware details at all - I want to understand them better. I just don't want to wade through them all the time.
To allow the developer to focus on what he needs at the moment means necessarily to hide all the zillions of the MCU internal details from distracting the developer's attention and allow his mind focus on his GOAL. It is amazing that all those (like myself in the past and yourself at present) who have years of experience dealing with MCU chip' underwear think that this should be goal/means/necessity of the application developer.........
2018-06-15 07:07 AM
The basic idea is: Machines are better than humans in repetitive works.
Very true Ahmad - and this is another strong reason why HAL-like libraries (if/when well made) should intelligently deal with all the dependencies of the MCU internal registers while providing application-related function, the developer instead should focus on his application.
2018-06-15 07:21 AM
'...
the developer instead should focus on his application...'
agreed. that's why layering is the single most important invention in software engineering, and why I very much liked the GUI-based programming approach implemented by cypress.
unfortunately ST isn't there yet. Think about how ST's hardware portfolio could be elevated by an equally competent software offering. an opportunity missed so far and for so long.
2018-06-15 07:48 AM
I want both. I want high level abstractions which are easy to use for boiler plate and to get beginners off the ground. I write such code with application-facing APIs which completely encapsulates the hardware details, the SPL calls, and the CMSIS code.
But I also want useful low level abstractions which directly reflect the nitty gritty details of the hardware, so that I can implement or modify new high level objects more easily. CMSIS sort of does this, but I think it could be better. SPL is a sort of halfway house; HAL is I don't know what; and I haven't a clue about LL.
I already have solutions for making my own drivers self-contained, reusable and agnostic about the particular hardware they are using. It just seems to me that ST should be providing solutions so that everyone benefits from them. CubeMX falls very wide of the mark. I don't know the history of it at all, but it looks like a model that works for tiddly 8-bit devices, but hasn't scaled at all well.
I suspect I have exhausted my 2p on this thread.