Skip to content
This repository has been archived by the owner on Jun 14, 2020. It is now read-only.

STM8 SPL license status #1

Closed
gicking opened this issue Jan 6, 2019 · 7 comments
Closed

STM8 SPL license status #1

gicking opened this issue Jan 6, 2019 · 7 comments

Comments

@gicking
Copy link
Contributor

gicking commented Jan 6, 2019

hi all,

here my current status of knowledge (please correct me if I'm wrong):

  • STM8 SPL is currently under the ST proprietary Mix Ultimate Liberty+OSS+3rd-party V1 . As pointed out by Philipp Krause this license is not fully OSS compliant

  • several people have started independent discussions with STM about this topic, e.g. Philipp Krause, Bruno Schwander, Weihong Guan, and myself (a while ago). In summary

    • the contacted STM people don't see a risk, but are unable to change the SPL license to comply to OSS rules

    • (at least to me) there seems to be no activity at STM to solve this legal question once and for all.

  • As a consequence of the unsolved legal situation:

    • SDCC currently does not provide STM8 device headers (see here), which leads to a lot of custom solutions, e.g. this (by lujji), this (by Philipp), or this (by me). Unfortunately these are mutually incompatible, so code snippets need to be fixed manually... Bundling the SPL headers with SDCC would solve that issue

    • the changes to the SPL required for SDCC (at least my version) are only available as patchfile, not as source. This may be ok for experienced users but is probably a no-go for newbies

  • Independent of the above items there are at least 3 more activities ongoing which IMHO require to solve the legal issue once and for all:

    • Michael Mayer recently released a tool to split the SPL functions into separate files:

      • this facilitates linker optimization and makes the generated code much smaller. This significantly increases SPL attractiveness

      • however, applying this change also to the SPL and releasing it as patchfile makes no sense, as the patchfile essentially contains the full SPL -> back to the above legal issue

    • (again) Michael Mayer is providing sduino, which integrates STM8/SDCC into the Arduino IDE. Aim is to make STM8 programming equally easy as Arduino. Currently sduino uses the patched SPL headers.

    • last but not least Benedikt Freisen is working on C++ support for STM8/SDCC by bundling LLVM+SDCC. If/when he succeeds it will make porting libraries from Arduino to STM8/sduino much easier

In essence:

  • using STM8/SDCC for OS-projects is possible but requires much more manual setup than e.g. for Atmel/Arduino. IMHO this is a serious show blocker for STM8 for the occasional hobbyist

  • the reason for this drawback is purely legal, not technical. And the situation is getting "worse", as more and more OS-projects are supporting STM8/SDCC

  • (I feel) there exists no synchronized discussion with STM to solve this topic once and for all. Please correct me if I'm wrong...!?

Looking forward to a lively discussion! Please forward this page to anybody who might be concerned/interested.

Regards, Georg

Note: a similar issue exists for my serial upload tool stm8gal (see issue #4). If possible, I would like to avoid inventing the wheel again, just to remove a few bytes of "non-free binary blobs"...

@roybaer
Copy link

roybaer commented Jan 6, 2019

The main problem here it that – whether we like it or not – St is right.

The PIC µCs have been cloned extensively and with the LGT8F series by LogicGreen (China) the AVR µCs have now been cloned, as well, albeit only about 99% compatible (patent reasons?).
The same holds true for St's STM32 series that has been cloned Milandr (MDR32, Russia) and GigaDevice (GD32, China).

So basically, a well established proprietary library is the only thing that discourages companies from using the cheaper clones.
And because people at St know that they have a valid point and because they are not dumb, they are not going to move.

So what can we do?

Well, we can write our own interoperable header. (There are projects like wine, after all.)

We can basically rewrite every macro or typedef that is trivially derived from the datasheets in exactly the same way.
Anything else can still use the same interface (i.e. in our case: name) but has to provide a new – and ideally different – implementation.
For example, while St's headers use bit masks, AVR headers use bit numbers. We could therefore define macros for bit numbers within a register and then base the St-compatible mask macros on those. This would have the additional advantage of simplifying porting efforts even further.

The best approach with SDCC in mind would probably be one monolithic header with typedefs and macros, only. It would not contain any functions, but rather function-like macros.
This would already mean approx. 90% interoperability and would be perfectly suited for SDCC or any other use case without function-level linking and link-time optimization.
You'd basically pay for what you use. Nothing else. No overhead.

One could boost the level of interoperability further by including a set of wrapper functions for the function like macros.

The resulting free STM8 library would then consist of:

  • A monolithic header with
    • all object-like macros and typedefs that a user is supposed to use and
    • function-like macros for all relevant SPL functions, e.g. with a leading underscore
  • A header that defines all SPL functions as function-like macros that wrap the version with leading underscore
  • An alternative header that defines them as actual function prototypes
  • A bunch of c files, one for each function, that wrap the macros with leading underscore in an actual function. (Can be auto-generated from the prototypes)

That kind of implementation would be about as different from St's version as it can be while maintaining >95% interoperability from a programmer's point of view.
At the same time it would allow for the generation of very efficient code.

This SDCC-optimized library could then be bundled with SDCC.

What do you think?

@gicking
Copy link
Contributor Author

gicking commented Jan 6, 2019

hi Benedict,

unfortunately I don't fully understand your proposal due to my limited preprocessor knowledge :-( Maybe you can provide some simple examples...? But what I do understand is that we end up with a lot of extra effort for creating and maintaining OSS-compliant headers/functions, darn! Actually I was hoping to avoid this double work and use SPL instead. But your comment on ST's IP protection strategy does have a point...

But I may have missed one important point above: according to a mail by Philipp, device headers may not be "copyrightable" after all. If that is correct(?), we can keep the SPL headers - ideally bundled with SDCC - and concentrate only on the functions. That would save us a lot of double work...

However, if we do require custom device headers, I have another/additional proposal for the peripheral header structure. Assume a peripheral register which contains >1bit values (e.g. CC3S in TIM1_CCMR3). With bit masks or bit numbers you end up with AND/OR-ing multiple bit masks/numbers. This is not a big issue but inconvenient. Therefore "my" header use unions of structs instead. This structure allows direct r/w access the respective value. For example see here for a definition and here for usage. Note that the register is still byte-accessible via .byte, so bit masks/numbers still work. I did some quick & dirty tests and found no impact on speed or codesize of unions compared to bit masks. However, I didn't go down to assembler level, sorry!

But first things first: can/should we use the SPL device headers or do we need custom ones? @ Philipp, is there a plan to bundle STM8 headers with upcoming SDCC releases? And, if yes, which?

As I said, lively discussion... :-)

@roybaer
Copy link

roybaer commented Jan 6, 2019

I'll gladly provide an example:

If the function looks like this:

void InitUART(UART_struct *uart)
{
  uart->CR1 = CR1_INIT_VAL;
}

We could write something like this:

#define _InitUART(uart) \
{ \
  (uart)->CR1 = INITIAL_CR1_VALUE; \
}

With a wrapper macro in one header:

#define InitUART(uart) _InitUART(uart)

And, in case a user needs a genuine function, this wrapper function somewhere else:

void InitUART(UART_struct *uart) { _InitUART(uart); }

This gives the user the choice between something that is always inlined and introduces no overhead if unused and something that is never inlined and can be used arbitrarily often without blowing up the code size. Also, whenever you need a function pointer, you obviously cannot use the macro.

Regarding the SPL headers the situation is a bit tricky because in our situation it barely even matters what actually is legal.
When it's multi-national corporation (STMicroelectronics) vs. tiny project with no money (e.g. SDCC), the only thing that really matters is what St thinks is legal.
If we use portions of SPL code illegally but St thinks it's legal, well, nothing happens.
If we use portions of SPL code legally but St thinks it's illegal, we'll get sued, anyway, which we cannot afford.

However, we can definitely use the same public interface and we can also definitely use information from the datasheets.
German law, for instance, even explicitly allows reverse engineering where its use is necessary to create interoperability.

The basic problem here is that code is subject to copyright, facts are not and a C header is somewhere in between.
It is undeniably C code but might merely be a list of facts.

Please note in that context that Kazimir Malevich's Black Square (oil on canvas) is a copyrighted painting!
You can obviously paint your own black square, but you must not copy his.
Some court might want to apply the same principle to C headers. It's ridiculous but you never know.

Regarding bits in control registers, I totally get the appeal of bit fields!
They are, however, not so well standardized. (Technically they are well standardized: As implementation defined!)
So if you e.g. pack eight individually named bits in one byte you cannot be sure whether the first one is bit 0 or bit 7.

@bschwand
Copy link

bschwand commented Jan 7, 2019

Hi,

In your introductory paragraph, you did not mention/link the patched and corrected STM8 SPL-SDCC that I published here (although not complete for all STM8 variants) and was approved for such by ST after some discussion.

My view is that

  • since ST will not budge on their license because like @roybaer mentions, ST is right to have their own license,
  • since ST sees no problem in having a complete patched STM8 SPL published by a third party as long as their license is published,

The path of least resistance is to "port" the SPL like I did for some of the STM8 variant, document and let know SDCC users that the SPL can be installed in full easily and how. I think that is not much different from any arduino-like library that has to be installed separately from the compiler. One does not expect to have a compiler and toolchain to support everything for a given uC when the compiler is installed. Seems pretty easy to me: install SDCC, clone the STM8 SPL-SDCC repo, start coding.

I agree that would not be practical for an evolving library, but STM8 is quite mature and I don't think any changes are forthcoming to the STM8 SPL.

That does not settle the license issue like you say, and implies an extra step. I think it's worth it, though, mostly because I don't see as a requirement that SDCC and all libs are bundled together, nor do I see as very important that everything falls under a single license.

I do agree that if someone wants to tackle writing SDCC-SPL interoperable headers, that would be best of all from the user and SDCC distribution point of view. But it's certainly a lot more work, and will not be 100% interoperable in the end.

Just my opinion, mostly from a practical-centered point of view.

@gicking
Copy link
Contributor Author

gicking commented Jan 12, 2019

hello bschwand,

I agree with you that it would be more practical to download the patched SPL. Ideally split into functions like you and tenbaht do, but that's a technical detail in this discussion.

However, as roybaer mentioned above, we (i.e. in this case you) rely on that STM will never change their mind and sue you. Do you have an actual contract with them or just a mail or so? I only have the latter, which is why I only provide the SPL patches as patchfiles, not as source. Call me a coward, but I'm not a lawyer and I simply don't want to take chances...

Besides, the SDCC developers are quite fussy about 100% OSS-complience, e.g. see here. What's the point of an OS compiler if you still have license restrictions for the actual output?

Unfortunately you are also right in the comment about effort for 100% SPL compatible headers. But what about OSS-headers which at least do not collide with the SPL. Those headers could be bundled with SDCC, so bare-metal programming of STM8 would be possible out of the box. And if someone chooses to install SPL in parallel (like you propose above), that is then his/her choice... Basically a combination of the 2 above proposals.

What do you think?

PS: sorry for the delayed answer but last weeks have been extremely busy.

@gicking
Copy link
Contributor Author

gicking commented Jan 27, 2019

Hello all,

sorry for my long silence - as it was me who started this discussion... But hopefully I have something worth the delay.

But first, let me briefly summarize my understanding of the above discussion (please correct me if I'm wrong):

  • SDCC doesn't provide STM8 device headers for license concerns(?) -> must be installed manually
  • There are many custom headers out there, which are generally incompatible and mostly incomplete
  • Ideally (legally and for compatibility) SDCC would bundle OS STM8 device headers, like e.g. for hc08 and mcs51. These would
    • be more convenient for users, as no manual install required
    • set a de-facto standard for users, so codes could be shared more easily
    • remove legal risk for users & developers (see next point)
  • STM8-SPL will likely never become full OS, which prevents bundling them with SDCC(?)
  • The ideal solution would be new STM8 device headers for bundling with SDCC, which are
    • fully OS compliant, i.e. not some patch to SDCC, but a re-write
    • can be mixed with SPL

I have just uploaded my proposal for such STM8 OS-headers under Headers/stm8. Simple blink example projects can be found under Headers/examples. Basically these are 3 variants of the blink-example with:

  • byte- and bitwise access to peripherals
  • with and without interrupts
  • with and without additional SPL calls

Practically I combined my existing headers from STM8_templates with a new Python script to extract device data from the STM8 product list from STM Homepage. Of the 138 STM8 devices in the list, 34 are supported and 104 are pending. But before I continue I would like to know if it makes sense to continue.

Specifically:

  1. what do you think, is this the way to go?
  2. if yes, would the SDCC developer team consider bundling these headers with SDCC in the future?

Eagerly waiting for your feedback! Have a great day :-)

Regards, Georg

@gicking
Copy link
Contributor Author

gicking commented Jun 14, 2020

hello all,

thanks to the Covid-19 lockdown I finally had time to resume this activity. Specifically I created FOSS device headers for all STM8 families and uploaded them to https://github.com/gicking/STM8_headers. Hope they find their way into the SDCC repo. Thanks again to Benedikt and Phillip for their input!

Regards, Georg

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

No branches or pull requests

3 participants