Author Topic: starting with STM32 CMSIS  (Read 12968 times)

0 Members and 1 Guest are viewing this topic.

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1663
  • Country: us
Re: starting with STM32 CMSIS
« Reply #25 on: July 22, 2019, 04:12:16 pm »
The syntax is consistent and takes the form of "peripheral_register_bitfield" for example to set GPIOA-10

: GPIOA_BSRR_BS10   %1 10 lshift GPIOA_BSRR bis! ;     \  Port A set bit 10

Yeah, consistently crappy. There's a reason why C is the industry standard language for embedded development and Forth is not.
Complexity is the number-one enemy of high-quality code.
 
The following users thanked this post: Siwastaja

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: starting with STM32 CMSIS
« Reply #26 on: July 22, 2019, 11:34:54 pm »
The syntax is consistent and takes the form of "peripheral_register_bitfield" for example to set GPIOA-10

: GPIOA_BSRR_BS10   %1 10 lshift GPIOA_BSRR bis! ;     \  Port A set bit 10

Yeah, consistently crappy. There's a reason why C is the industry standard language for embedded development and Forth is not.

Websters Dictionary informs the meaning of the word "crappy" as " markedly inferior in quality ". Can you provide a 'C' Language example to counter to my simple Forth example below which demonstrates your claim ?

After you do so, perhaps someone on this forum who *doesn't know C* can comment on which is easiest to read ?

For instance the code snippet above (which used correct CMSIS-SVD naming), could be written as :

: power-led-on %1 10 lshift GPIOA_BSRR bis! ;  \ The power led is connected to GPIOA-10

And thereafter the power led can be turned on with the command "power-led-on"

to turn it off, this code could be used :

:  power-led-off  %1 26 lshift GPIOA_BSRR bis! ;  \ The power led is connected to GPIOA-10

These allow  syntax like the code below which turns on the power led for 10 seconds, then turns it off. I suspect that even someone who has no clue about Forth (like yourself) could read this and understand what it does.

power-led-on    10 blocking-delay-seconds    power led off

Those statements could easily be consolidated into a single Word (Subroutine, Function) to blink the power led once, named "blink-power-led" :

: blink-power-led    power-led-on    10 blocking-delay-seconds    power led off ;

Now all one need do is execute the Word "blink-power-led" ... need I even describe what will happen, isn't it obvious from the actual Forth code ?

Note: GPIOA-10 is set and reset here without affecting any other bits in GPIOA by using the Cortex-M0 GPIOA_BRR register designed for this purpose. Anyone familiar with this hardware would understand.

 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4392
  • Country: dk
Re: starting with STM32 CMSIS
« Reply #27 on: July 23, 2019, 12:37:16 am »
The syntax is consistent and takes the form of "peripheral_register_bitfield" for example to set GPIOA-10

: GPIOA_BSRR_BS10   %1 10 lshift GPIOA_BSRR bis! ;     \  Port A set bit 10

Yeah, consistently crappy. There's a reason why C is the industry standard language for embedded development and Forth is not.

Websters Dictionary informs the meaning of the word "crappy" as " markedly inferior in quality ". Can you provide a 'C' Language example to counter to my simple Forth example below which demonstrates your claim ?

After you do so, perhaps someone on this forum who *doesn't know C* can comment on which is easiest to read ?

For instance the code snippet above (which used correct CMSIS-SVD naming), could be written as :

: power-led-on %1 10 lshift GPIOA_BSRR bis! ;  \ The power led is connected to GPIOA-10

And thereafter the power led can be turned on with the command "power-led-on"

to turn it off, this code could be used :

:  power-led-off  %1 26 lshift GPIOA_BSRR bis! ;  \ The power led is connected to GPIOA-10

These allow  syntax like the code below which turns on the power led for 10 seconds, then turns it off. I suspect that even someone who has no clue about Forth (like yourself) could read this and understand what it does.

power-led-on    10 blocking-delay-seconds    power led off

Those statements could easily be consolidated into a single Word (Subroutine, Function) to blink the power led once, named "blink-power-led" :

: blink-power-led    power-led-on    10 blocking-delay-seconds    power led off ;

Now all one need do is execute the Word "blink-power-led" ... need I even describe what will happen, isn't it obvious from the actual Forth code ?

Note: GPIOA-10 is set and reset here without affecting any other bits in GPIOA by using the Cortex-M0 GPIOA_BRR register designed for this purpose. Anyone familiar with this hardware would understand.


apart from being in an obscure language few uses how is it any better than a C macro?
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8110
  • Country: fi
Re: starting with STM32 CMSIS
« Reply #28 on: July 23, 2019, 05:56:22 am »
: GPIOA_BSRR_BS10   %1 10 lshift GPIOA_BSRR bis! ;     \  Port A set bit 10

Number of elements your brain needs to understand:
1) :
2) GPIOA_BSRR
3) _BS10
4) %
5) 1
6) 10
7) lshift
8) why GPIOA_BSRR comes again?
9) bis
10) !
11) ;

Equivalent C:

GPIOA->BSRR = 1<<10;

1)GPIOA->BSRR
2) =
3) 1
4) <<
5) 10
6) ;

It baffles me how people who (partially rightfully) complain that C is difficult, always tend to come up with a solution which is orders of magnitude more difficult.
 
The following users thanked this post: Jacon

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • !
  • Posts: 2699
  • Country: tr
Re: starting with STM32 CMSIS
« Reply #29 on: July 23, 2019, 06:10:34 am »
Quote
GPIOA->BSRR = 1<<10;

1)GPIOA->BSRR
2) =
3) 1
4) <<
5) 10
6) ;

GPIOA->BSRR = 0x400;

1)GPIOA->BSRR
2) =
3) 0x400
4) ;

IIRC the Open Firmware in the PPC Macs was written in Forth, and had a Forth shell.
« Last Edit: July 23, 2019, 06:50:08 am by GeorgeOfTheJungle »
The further a society drifts from truth, the more it will hate those who speak it.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
Re: starting with STM32 CMSIS
« Reply #30 on: July 23, 2019, 06:12:49 am »
Quote
... could be written as ...
Quote
... could easily be consolidated ...
Quote
Can you provide a 'C' Language example to counter to my simple Forth example:
Code: [Select]
: GPIOA_BSRR_BS10   %1 10 lshift GPIOA_BSRR bis! ;     \  Port A set bit 10
First of all, isn't that ... wrong?  GPIO_BSRR is specifically a word-wide atomic set/reset register, so you should be using just a normal store ("!", IIRC?) instead of "bis!" (a Bit store?)

Second, if you're going to allow for arbitrary "infrastructure programmer improvements", then I'd claim a C example would be Arduino's:
Code: [Select]
  digitalWrite(15, HIGH);A more exact translation would be:
Code: [Select]
void GPIOA_BSRR_BS10() {
   GPIO->BSRR = 1<<10;
}


I suppose we could argue forever about the relative readability of ": " vs "void ", or "%1 10 lshift" vs "1<<10", and never reach an agreement.

Subroutines/functions (sorely under-used in the Arduino user world), vs Forth words...  Not so different.


I used to be pretty enthusiastic about Forth; I have the original Brodie book, and a FigForth 8080 printed version, and I typed in pretty much the entire source code published in Kilobaud and tried to run it under a homebrewed 8085 emulator on a mainframe.  But these days...  It feels like a 1970s programming language based on the assumption that "compilers are too big and expensive to use for a microprocessor (and it's MUCH too difficult to load a compiled program onto an embedded system)", that never "grew up" to recognize that that's no longer true.

I think C and Forth have a lot in common: both are based on very simple core definitions, so Forth is probably the easiest Interpreter to port to new hardware, and C is probably the easiest compiler to port (both because a lot of the "run time" support is "outside" of the core.)




Quote
Mecrisp-Stellaris Forth happily uses CMSIS-SVD and we have a parser for all the various STM32 chips.
How big is the core word set (if that's the right term) for a Forth that auto-generates all the register names from a modern ARM .SVD file?  I would have thought that the usual ARM vendor mentality would make that pretty painful; certainly C's .h files (also usually derived from the SVDs (or both .h and .svd derived from some vendor format)) are huge and intimidating if you actually have to go look at them...

 

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: starting with STM32 CMSIS
« Reply #31 on: July 23, 2019, 09:46:54 am »
: GPIOA_BSRR_BS10   %1 10 lshift GPIOA_BSRR bis! ;     \  Port A set bit 10

Number of elements your brain needs to understand:
1) :
2) GPIOA_BSRR
3) _BS10
4) %
5) 1
6) 10
7) lshift
8) why GPIOA_BSRR comes again?
9) bis
10) !
11) ;

Equivalent C:

GPIOA->BSRR = 1<<10;

1)GPIOA->BSRR
2) =
3) 1
4) <<
5) 10
6) ;

It baffles me how people who (partially rightfully) complain that C is difficult, always tend to come up with a solution which is orders of magnitude more difficult.

Nicely put apart from the cheap shot at anything NOT-C :)

1) ":" means compile the following function

2) GPIOA_BSRR_BS10 is the name of the Word or subroutine being compiled, it's also CMSIS-SVD correct. I could have called it any name I chose, but preferably one that describes what it does such as "power-led-on".

It's the equivalent of  GPIOA_BSRR_BS10{}; in C

I left it as "GPIOA_BSRR_BS10" assuming that C users would recognize CMSIS_SVD syntax when they saw it.

3) % is the BASE identifier for BINARY as $ is for HEX, hence %1 means BINARY 1. Have you never written anything in assembler ?

4) 10 is DECIMAL 10

5) lshift means "left shift".   "10 lshift"  means shift left 10 places

6) GPIOA_BSRR is a constant previously defined with a method similar to the C "header files".
                 $48000000 constant GPIOA ( General-purpose I/Os )
                 GPIOA $18 + constant GPIOA_BSRR ( GPIO port bit set/reset  register )

7) bis! means "Set Bits in word-location"

8) ";" completes the function

Now let us imagine I don't know any C syntax ?

GPIOA->BSRR = 1<<10;

1) GPIOA
2) -
3) >
4) BSRR
5) =
6) 1
7) <
8) <
9) 10
10) ;

GPIOA puts something into BSRR ?
This is also equal to 10 being put into 1 ?
Are we changing pin 1 or pin 10, it's not clear, and hardly self evident.

Your code really involves 10 steps, 2 more than mine ;-)

As always if one doesn't know the programming language, nothing is obvious.

Why is this a surprise to anyone ?

Incidentally, I didn't write " : GPIOA_BSRR_BS10   %1 10 lshift GPIOA_BSRR bis! ; " rather it was auto-generated by a CMSIS-SVD parser I wrote a few years ago which generates Forth Words for every single register bitfield in a STM32 MCU. They are just templates and I always change the function name placeholder (for something more descriptive) you were complaining about earlier.

In some cases there are over fourteen thousand register bitfields generated (STM32F7xx). This is the same way you get your 'C' Language Cortex-M header files, they're all generated from CMSIS-SVD files.
 

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: starting with STM32 CMSIS
« Reply #32 on: July 23, 2019, 10:04:16 am »

apart from ( Forth) being in an obscure language few uses how is it any better than a C macro?

Apple will be saddened to hear that you think there are only a few OSX computers in the world as every one of them uses a Forth based Boot Loader. Same with *BSD.

I wonder if you can work out why Forth is used as a PC Boot Loader, and not something compiled with C ?

Is C inferior to Forth in this instance, and why ?

I'm also curious to know why you assume that C macros have anything in common with Forth ?
 

Offline GeorgeOfTheJungle

  • Super Contributor
  • ***
  • !
  • Posts: 2699
  • Country: tr
Re: starting with STM32 CMSIS
« Reply #33 on: July 23, 2019, 10:27:41 am »
EFI uses Forth as well? Are you sure?
The further a society drifts from truth, the more it will hate those who speak it.
 

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: starting with STM32 CMSIS
« Reply #34 on: July 23, 2019, 11:44:41 am »
EFI uses Forth as well? Are you sure?

Um ... no :)

FreeBSD:
I'm not a bootloader expert by any means but Freebsd uses LOADER(8) which is Forth based and supports the following architectures:
x86 (PC, UEFI, coreboot, OLPC, Mac), ARM (U-Boot, UEFI), MIPS, PowerPC, SPARC v9
 
The following filesystems:
FAT12/FAT16/FAT32/VFAT, ext2, NANDFS, ISO-9660, UFS, ZFS

and gzip, bzip2 compression.

Source: https://en.wikipedia.org/wiki/Comparison_of_boot_loaders

man 8 loader has this to say:

 The program called loader is the final stage of FreeBSD's kernel
     bootstrapping process.  On IA32 (i386) architectures, it is a BTX client.
     It is linked statically to libstand(3) and usually located in the
     directory /boot.

     It provides a scripting language that can be used to automate tasks, do
     pre-configuration or assist in recovery procedures.  This scripting
     language is roughly divided in two main components.  The smaller one is a
     set of commands designed for direct use by the casual user, called
     "builtin commands" for historical reasons.  The main drive behind these
     commands is user-friendliness.  The bigger component is an ANS Forth
     compatible Forth interpreter based on FICL, by John Sadler.

Openboot is also Forth based:
Said Oracle @ https://docs.oracle.com/cd/E63648_01/html/E63649/gpsgy.html
"The OpenBoot CLI is based on the industry-standard interactive programming language called FORTH.Combining sequences of commands to form complete programs provides the capability for debugging hardware and software."

Note that Oracle doesn't seem to think that Forth is 'obscure' as Langwadt claims below, rather they say that Forth is a  "industry-standard interactive programming language"
 

Offline Sal Ammoniac

  • Super Contributor
  • ***
  • Posts: 1663
  • Country: us
Re: starting with STM32 CMSIS
« Reply #35 on: July 23, 2019, 04:58:24 pm »
As always if one doesn't know the programming language, nothing is obvious.

Why is this a surprise to anyone ?

I'm curious to hear your take on why C became the industry standard programming language for embedded systems and Forth did not.
Complexity is the number-one enemy of high-quality code.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
Re: starting with STM32 CMSIS
« Reply #36 on: July 23, 2019, 08:31:30 pm »
Quote
% is the BASE identifier for BINARY as $ is for HEX, hence %1 means BINARY 1. Have you never written anything in assembler ?
Meh.  First of all "1" doesn't need a base, and specifying one only leads to confusion.  I was uncertain whether % was a radix specifier, a variable size specifier, or something else "Forthish"  (one of the things Forth does that annoys me is word names that start with a digit ("2dup")   Grr.)
Secondly, assemblers are woefully inconsistent about base identifiers.  I'm not sure I've ever seen "%digits" for binary " :-(Assemblers that I have used 'recently" would want:

0b1  (gnu assembler, AVR assembler)

B'1'  (MPASM PIC assembler)

2_1 (ARM Official assembly syntax.  (Had to look that one up: I usually use the gnu assembler for ARM.))

01b (MASM, 8051 assembler (most Intel assemblers?))

01y (MASM if the default radix is hex.)

^B1 (Macro-10, Macro-11)

 
The following users thanked this post: Siwastaja

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: starting with STM32 CMSIS
« Reply #37 on: July 23, 2019, 08:52:21 pm »
Quote
% is the BASE identifier for BINARY as $ is for HEX, hence %1 means BINARY 1. Have you never written anything in assembler ?
Meh.  First of all "1" doesn't need a base, and specifying one only leads to confusion.

Please try and read the complete post  before jumping in ?

You didn't read that the Forth Word you refer to was 'automatically generated'. Do you *really* think that *anyone* here is unaware that "1 doesn't need a base" ?

Really ?

Here are examples of  Words using more than 1 configuration bit. These were AUTOMATICALLY GENERATED from CMSIS-SVD (along with thousands of others)  when the Word you refer to was also created.

These are Bitfields, the databook shows them as binary bits because each one serves a different purpose, they are not Decimal numbers.

: I2C2_PECR_PEC   ( %XXXXXXXX -- ) 0 lshift I2C2_PECR bis! ;  \ I2C2_PECR_PEC    Packet error checking  register
: TIM1_SMCR_ETF   ( %XXXX -- ) 8 lshift TIM1_SMCR bis! ;  \ TIM1_SMCR_ETF    External trigger filter
: TIM1_CCMR1_Input_CC1S   ( %XX -- ) 0 lshift TIM1_CCMR1_Input bis! ;  \ TIM1_CCMR1_Input_CC1S    Capture/Compare 1  selection

I have to ask, do you have any recent experience configuring modern MCU's with thousands of Bitfields ?
 

Online langwadt

  • Super Contributor
  • ***
  • Posts: 4392
  • Country: dk
Re: starting with STM32 CMSIS
« Reply #38 on: July 23, 2019, 09:26:20 pm »
I have to ask, do you have any recent experience configuring modern MCU's with thousands of Bitfields ?

you argue that forth isn't an obscure language that few use because it is used in bootloaders

using the same logic the billions of people who use a computer or cellphone have recent experience configuring
modern MCU's with thousands of Bitfields
 

Offline Bassman59

  • Super Contributor
  • ***
  • Posts: 2501
  • Country: us
  • Yes, I do this for a living
Re: starting with STM32 CMSIS
« Reply #39 on: July 23, 2019, 10:03:25 pm »
If you're interested in the hardware itself why use the 'C' programming language, it's not made for hardware interaction.

The Forth programming language is made for hardware interaction yet allows the programmer to start at the bare metal and proceed to the actual Problem Definition Language as they go.

Mecrisp-Stellaris Forth happily uses CMSIS-SVD and we have a parser for all the various STM32 chips.

The syntax is consistent and takes the form of "peripheral_register_bitfield" for example to set GPIOA-10

: GPIOA_BSRR_BS10   %1 10 lshift GPIOA_BSRR bis! ;     \  Port A set bit 10

Then executing "GPIOA_BSRR_BS10" sets Port A set bit 10, providing it is set as a OUTPUT elsewhere.

This is just one way and there are many alternative choices, but no HAL, no C compiler and no assembler are required with Forth, you talk to the chip directly via a serial terminal in real time INTERACTIVELY.

All due respect, but the vast majority of embedded systems don't sit there and wait for a user to type in an obscure command so they can toggle the state of an LED.

Sure, we've all done designs which have a serial port that connects to a terminal emulator and we use that to send commands and such, but that's just it, we send commands that are parsed by the micro to do something useful. For example, a thing on my bench right now has a TEC. I can send it a command to turn the cooling off and on. I can send it another command to set the temperature set-point. The micro itself runs the cooling loop, reading the temperature on a periodic basis and then updating the current through the TEC. No user interaction required, or even wanted!

I certainly do not send it individual commands to read the temperature and then use that to update a PID controller I have elsewhere!

Another thing I am working on uses a USB-MIDI interface to take messages from the computer to set up some hardware and then if the user pushes a button or turns a knob, messages are sent back to the computer. Please, show me a USB stack written in Forth.

We extensively use Ethernet interfaces in many designs. Show me a tcp/ip stack written in Forth, and tell us why that's better than C.

The notion that we can put a Forth interpreter in the micro (how much code and data memory does this require, anyway) is interesting if we want a debug monitor, but we have JTAG and SWD and they're both superior to an interactive monitor in so many ways.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
Re: starting with STM32 CMSIS
« Reply #40 on: July 24, 2019, 03:20:00 am »
Quote
You didn't read that the Forth Word you refer to was 'automatically generated'. Do you *really* think that *anyone* here is unaware that "1 doesn't need a base" ?
Actually, I thought "GPIOA_BSRR" was auto-generated, but "GPIOA_BSRR_BS10" was user-defined.

You auto-generate a "*_BSxx" word for every possible bitfield and value??!!
And I thought the dictionary size would be getting out-of-control with just all the register-names in it!

Quote
do you have any recent experience configuring modern MCU's with thousands of Bitfields ?
Yeah.  Extensively, using C structures with bitfields overlaid on the peripheral address space, and/or network packets and/or etc. (Not endian-safe.  But neither is the Forth.)  Before that, I used a cpu and assembler with hardware bitfield support, and assembler macos for defining structures with bitfields...


Actually, this points out one of my complaints about Forth.  Where are the high level structures?Why is a "GPIOA_BSRR_BS10" word instead of someting like "GPIOA BSRR strref bit10 !"
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8110
  • Country: fi
Re: starting with STM32 CMSIS
« Reply #41 on: July 24, 2019, 06:56:05 am »
Extensively, using C structures with bitfields overlaid on the peripheral address space, and/or network packets and/or etc. (Not endian-safe.  But neither is the Forth.)

This. Exactly this. C is high enough level to provide such massive improvements on code writability and readability over autogenerated bloat.

One of the worst things in C is the standardization, and their original laziness (and laziness to correct things afterwards) to specify sane, practical intent on the standardization level.

You want to access same memory location as two different data types? Happens all the time, called type punning. Guess what? C has a feature specifically for this purpose: union. So everybody uses this obvious tool, everything works fine, and the code is readable. Then, someone reads the standard only to find out that this obvious thing is... forbidden. It just it, for no reason.

Low-level code, be it linux kernel or a microcontroller project, tends to massively benefit (both in readability and performance) by utilizing the C features in obvious ways, but specified "undefined behavior" or "implementation-defined" in the standard (paper). Now, getting over this and just starting writing readable, elegant and high-performance code, ignoring language purists who talk about demons flying out of your nose, is the key to success. linux kernel does this extensively, and they have a good track record of calling bullshit whenever gcc tries to break code just because a standard (paper) allows doing so.

C offers good combination of low and high level; it's a round peg with a bit of surface roughness needed to be filed off, to a round hole. But as a result, C isn't strictly standardized, but has "compiler dialects".

Embedded C would greatly benefit from a standardized low-level memory access addendum, just formalizing the usual "undefined behavior"/"implementation defined" patterns people want to use. Think about bitfield layouts, for example! But we don't have it, and the alternatives haven't succeeded, so we use what we have.


The real issue of this discussion is that with C, extremely complex systems are written day in day out, by really experienced folks. It's very easy to point out obvious pitfalls (like overindexing a table, or dangers of zero-terminated strings), and suggest new languages and paradigms, but this is often done by amateurs lacking understanding (demonstrated clearly in this thread by showing a fundamental misunderstanding  about what the BSRR register is, thus producing wrong Forth code to access it). C is already proven to work as a tool for really complex systems; for anything much less mainstream, it needs to be proven separately, and the communication style of the fanboys of any more or less trendy "alternative" does not give much confidence about these languages, even if they were technically, and theoretically, suitable for the task.
« Last Edit: July 24, 2019, 07:02:38 am by Siwastaja »
 

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: starting with STM32 CMSIS
« Reply #42 on: July 24, 2019, 09:11:00 am »
As always if one doesn't know the programming language, nothing is obvious.

Why is this a surprise to anyone ?

I'm curious to hear your take on why C became the industry standard programming language for embedded systems and Forth did not.

Not that I have any special access to the embedded systems industry or the hearts and minds of embedded systems writers any more than anyone else but I do have my pet theories.

Firstly there is no such thing as a "industry standard programming language for embedded systems".

I'm happy to concede that The 'C' programming language is probably the most common programming language in use today. However let's not overlook other languages designed specifically for embedded development and use such as Assembly Language and Forth etc

Some reasons why Forth will never be popular, and why C is very common in my opinion. Not in order of significance:

Standardization:
C has a standard syntax that doesn't change much which many (but not all) users and all software sales organizations prefer. C was always perfect for pretty colored shrink wrapped boxes in retail stores and a plethora of books such as SAM's learn C in 24 hours. Forth is the darling of the software sales industry, but other recent languages such as Python are also becoming very popular, especially in embedded where tons of memory resources are available.
C easily wins the standardization category.

Sidenote: I'm waiting for someone to create a 'Tethered Python', I think that may give C and Arduino a run for it's money at least in the hobby market.

Marketing:
C is easy to market as mentioned above but Forth is not, and never will be.
C easily wins the marketing category.

Arduino:
Arduino brought thousands of hobbyists to C.
Until the advent of Arduino, embedded was not trivial, a designer had to do the hard yards before they could even get a MCU to boot. Arduino brought artists and hobbyists flocking to their easy to use system, complete with 'libraries'. Want to run a stepper motor, no problem, grab a ULN2003, a 'sketch' and step away!
Arduino hid all the hard stuff, and unfortunately is still recommended by users on this forum as a way to learn Microprocessors, but I disagree. Arduino was designed for artists with little technical knowledge.
If you really want to learn the basics of Embedded design, grab a Intel  8085 chip, a Parallel Flash EPROM and make something that works using Assembly Language. Report back  when you have actually built something (pics required) and figured it all out.
I put together a 'Learning Microprocessors' page at https://sourceforge.net/projects/learning-microprocessors/ based on the 8085 and a handy Java simulator which represents the state of the technology about 10 years after I started in the embedded area in 1975.

LIbraries:
Like Cargo Cultists, C users eagerly await the latest libraries to drop from the sky, "please God bring me a library that allows me to use Timer3 and Timer6 synchronized together and using interrupts on Timer 1 and DMA on Timer 3 in a easy to use, non technical way so I don't have to read that terrible 2000 page technical manual with all those registers, ... anything but that!".
 C users sing praises of the availability of embedded libraries' while decrying the complexity of library systems which struggle to somehow to bring a unified library into being across dozens of MCU peripherals, hundreds of registers and thousands of register bitfields.
 What C users call a library, Forth users call 'configuration' and we write them as required for each project. It's no biggie, it requires a intimate understanding of the hardware as *it always has* since the first 4004 micro rolled of the production line.
 Nevertheless the promise of 'C Libraries' lives on, it's the holy grail that attracts people by the thousands who think that C will make them into a hardware engineer.
All they need is a C, some libraries and a MCU in some cheap Chinese 'development board' along with 'shields'.
C easily wins the library category.

Interactivity:
Only Forth is interactive, C is not. So Forth is the clear winner in the interactivity category.

Why Forth will never be  be mainstream or popular, but will forever be a niche programming language in my opinion:
1) Forth is like the TAO, it is a way and is only understood when practiced.
2) Forth is easy to learn, but hard to master, it requires a different mindset.
3) Forth is a Chameleon, it is like a stealth aircraft which looks different from every angle. Even the creator of Forth said, when asked "what is Forth" ... " I can't really say, but I know it when I see it"

These are all valid forth Words (subroutines, functions etc):

: + - ;

: foo ." bar" cr ;

CC4OE %1 12 lshift TIM1_CCER bis!

: 2arshift ( d u -- d* )
[
  $CF03 h,
  $2E20 h,
  $D304 h,
  $F1B6 h,
  $0320 h,
  $FA50 h,
  $F203 h,
  $E006 h,
  $FA31 h,
  $F206 h,
  $F1D6 h,
  $0320 h,
  $FA10 h,
  $F303 h,
  $431A h,
  $F847 h,
  $2D04 h,
  $FA50 h,
  $F606 h,
]
3-foldable ;

  10 constant sieve-size       \ Reject variations of less than 10
  0 variable oldinput
 : sieve ( newinput -- output only if newinput = oldinput +- sieve-size  )
   dup oldinput @ sieve-size - <= if 0 >r else 1 >r then
   dup oldinput @ sieve-size + >= if 0 >r else 1 >r then
   r> r> and if drop oldinput @ else dup oldinput ! then
 ;

power-on fill wash drain empty fill wash drain spin power-off


Summary:
I'm not pushing Forth here, I don't care who uses Forth and who doesn't. My motto regarding embedded is "if it works for you then its probably what you need"

I'm here because I'm a Forth user, I recommend it to new users who ask, "what embedded language would be good for me?".

I debate 'C' Language pushers who have no real clue about Forth and attack it in order to justify their mistaken belief that 'common' also means 'best'.
 

Offline cv007

  • Frequent Contributor
  • **
  • Posts: 822
Re: starting with STM32 CMSIS
« Reply #43 on: July 24, 2019, 09:43:28 am »
I think C++ is still largely an untapped resource in the micro world. It would be nice if manufacturers would start thinking about heading in that direction. The downside is they have a lot room to make things worse than what they have now (be careful what you wish for).

Here is a quick and dirty C++ class for gpio pins on a stm32f4 discovery-
https://godbolt.org/z/kgM46M
its not complete, I know very little about stm32 (just looked at user manual), and could be done better, but I think you end up with code that is more readable and in many cases there is no penalty in size/speed compared to C. You don't have to get too deep into C++ to start seeing the benefits.

Quote
Arduino brought thousands of hobbyists to C.
They are using C++ and they don't even know it.

 

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: starting with STM32 CMSIS
« Reply #44 on: July 24, 2019, 09:44:00 am »
Quote
You didn't read that the Forth Word you refer to was 'automatically generated'. Do you *really* think that *anyone* here is unaware that "1 doesn't need a base" ?
Actually, I thought "GPIOA_BSRR" was auto-generated, but "GPIOA_BSRR_BS10" was user-defined.

You auto-generate a "*_BSxx" word for every possible bitfield and value??!!
And I thought the dictionary size would be getting out-of-control with just all the register-names in it!

Quote
do you have any recent experience configuring modern MCU's with thousands of Bitfields ?
Yeah.  Extensively, using C structures with bitfields overlaid on the peripheral address space, and/or network packets and/or etc. (Not endian-safe.  But neither is the Forth.)  Before that, I used a cpu and assembler with hardware bitfield support, and assembler macos for defining structures with bitfields...


Actually, this points out one of my complaints about Forth.  Where are the high level structures?Why is a "GPIOA_BSRR_BS10" word instead of someting like "GPIOA BSRR strref bit10 !"

The whole line is autogenerated, it's a Bitfield Word *template* and takes the names from CMSIS-SVD. The actual Word 'name' is changed when pasted into a Forth program. No way is any of this autoloaded into the Dictionary ... the micro would need megabytes of Flash for it all, and *nobody* uses every peripheral, every Register and every bitfield in a MCU because they usually have far more peripherals than available pins to use them all.

Sure I autogenerate *everything* , here is a link to a example of what it looks like for just the RCC register in a STM32L07:
https://mecrisp-stellaris-folkdoc.sourceforge.io/register-generator.html#example-rcc-bitfields
Why shouldn't I autogenerate everything ? your C compiler maker uses CMSIS-SVD to autogenerate every header file entry etc don't they ?
Don't tell me you have to have a technical reference manual open to set,clear or test every bitfield in a MCU when you program in C?

High level structures ? I was illustrating a low level structure (auto generated template remember ).
As previously stated that syntax can ( and would) be easily changed, i.e.

I can't use another LED example as one poster here thinks that all Forth users do is illuminate LEDS's so the TEMPLATE

: GPIOA_BSRR_BS0   %1 0 lshift GPIOA_BSRR bis! ;  \ GPIOA_BSRR_BS0    Port A set bit 0

becomes

: fire-thermonuclear-warhead-missile %1 0 lshift GPIOA_BSRR bis! ;     ... which is uploaded into the Forth Terminal and becomes a Dictionary Word

Simplistic high level stuff might read:

enemy-nuke-launch-detected? IF obtain-targeting upload-targeting-to-missile fire-thermonuclear-warhead-missile ." retaliation commenced" ELSE ." all is quiet" THEN

What are your other complaints about Forth, I'm merely curious and not seeking to change your mind about anything, I'm a Forth user, you're a C user, we both use what we like and understand, end of story :)

 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8110
  • Country: fi
Re: starting with STM32 CMSIS
« Reply #45 on: July 24, 2019, 10:09:01 am »
I agree on the cargo cult "overlibrarization" problem existing, but I don't think it's connected to any particular language. I don't genuinely think that the super crappy STM32 code depending on bloated, hard-to-use libraries have anything to do with C. Quite the opposite - they are not using C features which would help reducing such code, instead depend on autogeneration. C actually makes writing such bloated mess awkward - yet they still managed to fuck it up.

Quite the opposite - the "higher" we go, the more absurd the library cargo cult becomes. From a C viewpoint, many modern C++ developer can't wipe their own butt without linking with a massive bloated library which is harder to use, understand and maintain than just to wipe your butt yourself to begin with.


The interactivity thing is a total mystery to me. If I want to interactively toggle IO pins, I buy a computer equipped with IO (for a modern, cheap example: Raspberry Pi), so it's not only interactive through UART, it's usable as a standalone unit, can get to the Internet, and then I can toggle the pins interactively from shell, Python script or whatever floats my boat.

With a microcontroller, I'm developing an actual production unit, and if my production unit needs to have a UART command parser, I definitely need it to be my custom one, not a stock Forth interpreter capable of running any arbitrary code.

I do see a very limited use case of verifying PCB schematic by toggling pins on the very first unit the first time to see what happens. This would be a bit faster with the Forth interactive interpreter (minutes) than writing my usual initial C testbench (maybe 30-60 minutes).
« Last Edit: July 24, 2019, 10:16:32 am by Siwastaja »
 

Offline techman-001

  • Frequent Contributor
  • **
  • !
  • Posts: 748
  • Country: au
  • Electronics technician for the last 50 years
    • Mecrisp Stellaris Unofficial UserDoc
Re: starting with STM32 CMSIS
« Reply #46 on: July 24, 2019, 10:14:49 am »
I think C++ is still largely an untapped resource in the micro world. It would be nice if manufacturers would start thinking about heading in that direction. The downside is they have a lot room to make things worse than what they have now (be careful what you wish for).

Here is a quick and dirty C++ class for gpio pins on a stm32f4 discovery-
https://godbolt.org/z/kgM46M
its not complete, I know very little about stm32 (just looked at user manual), and could be done better, but I think you end up with code that is more readable and in many cases there is no penalty in size/speed compared to C. You don't have to get too deep into C++ to start seeing the benefits.

Quote
Arduino brought thousands of hobbyists to C.
They are using C++ and they don't even know it.

Compile Explorer looks quite nifty and I can read most of your neatly laid out code.

I understand that C/C++ writers always want to configure a entire GPIO pin in one command and I'm curious why ?

In my experience, GPIO pins are usually configured for a particular project and stay that way forever in most cases, they are the simplest peripheral to configure and their RESET configuration is very sensible in the case of STM32 MCU's.

Usually I don't need to configure more than the MODER register with Forth for simple I/O, so my AUTOGENERATED TEMPLATE for GPIOA-0 is as below:

: GPIOA_MODER_MODER0   ( %XX -- ) 0 lshift GPIOA_MODER bis! ;  \ GPIOA_MODER_MODER0    Port A configuration bits

As I have the MODER OPTIONS defined as constants:
\ Moder
  %00 constant INPUT
  %01 constant OUTPUT
  %10 constant AF
  %11 constant ANALOG
  %0000 constant  AF0 
  %0001 constant  AF1
  %0010 constant  AF2 
  %0011 constant  AF3 
  %0100 constant  AF4
  %0101 constant  AF5 
  %0110 constant  AF6 
  %0111 constant  AF7

I just enter this command to set GPIOA-0 as a OUTPUT :

OUTPUT   GPIOA_MODER_MODER0

or if I want Alternate Function 7 for that pin:

AF7    GPIOA_MODER_MODER0

I find this higher level code very readable and 100% CMSIS-SVD compliant so I know exactly what is happening. I can read this code a year later and it the intention is still perfectly clear. The first Word  "GPIOA_MODER_MODER0" is hidden in the project config.fs file and doesn't clutter up my main Forth project code.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4196
  • Country: us
Re: starting with STM32 CMSIS
« Reply #47 on: July 24, 2019, 10:20:57 am »
Quote
The whole line is autogenerated, it's a Bitfield Word *template* and takes the names from CMSIS-SVD. The actual Word 'name' is changed when pasted into a Forth program.
Could you explain more about how that works?  I would have thought that in order to retain the "interpreter" nature of Forth, you'd have to have all the words in the dictionary.  There are Forth "compilers" (that I'm not at all familiar with) that could do the same sort of templating or symbol translation that C++/C can do, but... that wouldn't be a Forth interpreter any more, would it?

Quote
I'm not pushing Forth here
Sure you are.  But that's fine; it makes us think...
I wish more of the "new" languages were as clearly DIFFERENT as Forth is willing to be, rather than just "well, this is like Java/C++/C/Pascal/Algol except we added a few concepts we really like, and this time the VM we're proposing will really be secure!"

Quote
I'm waiting for someone to create a 'Tethered Python', I think that may give C and Arduino a run for it's money
"Tethered"?   Adafruit is really pushing their "CircuitPython" (a derivative of MicroPython), and building boards that are capable of running it effectively (?) (at prices comparable with Arduino boards.)  Generally this means adding several megabytes of serial flash to hold the source-level libraries that a Python sketch is likely to need.  (and using at least a 48MHz ARM CM0 chip.  None of  this 8-bit nonsense.)

Python might qualify as "significantly different" from C/etc, but it's hard to tell how much is the language, and how much is the libraries.   Though perhaps the ability to write really effective libraries OUGHT to be a major reason to like a language.  I've felt that C falls apart for its inability to put data in libraries (ie "objects") effectively, and C++ seems to add feature after feature designed to allow the small subset of programmers who write really complex libraries to do so without stepping outside the bounds of the language (oh, the horror, if you should have to write part of a library in assembly language!")

I wrote a Python program that scrapes my favorite web-comic to my local disk.  So it has a constant "start page", downloads the the appropriate image and associated text, finds the "next" link, and iterates till done, plus waiting a "friendly" time (2-50 seconds) between each page, so as not to cause excessive traffic. It's 54 lines of code, including the "imports" of "well known libraries", comments, and a dozen lines of "test code that is no longer used" (but is useful for reminding me how I got the final product.)
I am ... impressed, and also horrified!
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8110
  • Country: fi
Re: starting with STM32 CMSIS
« Reply #48 on: July 24, 2019, 10:26:41 am »
I just enter this command to set GPIOA-0 as a OUTPUT :

OUTPUT   GPIOA_MODER_MODER0

or if I want Alternate Function 7 for that pin:

AF7    GPIOA_MODER_MODER0

I think you could still improve on the encapsulation (by the way, which is equally possible in almost any language...)
No need to remember that the register was named MODER, and repeat MODER twice, and no need to remember which numerical value meant "output", which was "input" and which was "analog". Abstract it away once!

I do, in C:

IO_TO_GPO(GPIOA, 0);

HI(GPIOA, 0);
LO(GPIOA, 0);

IO_TO_GPI(GPIOA, 0);
if(IN(GPIOA, 0))

IO_TO_ANALOG(GPIOA, 0);


I also do, in C:
IO_ALTFUNC(GPIOA, 0, 7);

Which sets the whole jazz, the MODER and the AF selection register.

All of this happens without any autogenerated code from my part -  my macros convert to the names used by the ST in their official header files. The defines for the above take 11 lines of code. Example definitions:

Code: [Select]
#define HI(port, idx) do{(port)->BSRR = 1UL<<(idx);}while(0)
#define LO(port, idx) do{(port)->BSRR = 1UL<<(16+idx);}while(0)
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8110
  • Country: fi
Re: starting with STM32 CMSIS
« Reply #49 on: July 24, 2019, 10:34:30 am »
Python might qualify as "significantly different" from C/etc, but it's hard to tell how much is the language, and how much is the libraries.

It's the libraries, definitely. Python libraries, written in C, are fairly well designed, for both usability and performance. They do a better job for usability than C or C++ standard libraries, for example. The typical use case for a python program is to control the flow between libraries that perform fairly large independent tasks. An example? I can hear a lot that "neural networks are written in Python". In reality, it means you write the input data tables and coefficients in Python, and using one function call, invoke the actual backend, which does everything. In this case it's only a configurator script language. It's handy compared to a non-programmable static configuration file, as you can calculate things, for example, and invoke other library modules to produce the values.

It's quite similar to the Arduino approach. With Arduino, you buy a "motor control shield", with both HW&SW already designed, set up a few parameters, and call runMotor();

This is a great approach whenever the solution already exists. The important distinction is, you are not "writing a neural network", nor you are "building a motor controller". This becomes apparent the very second the finished product you are using doesn't do exactly what you need it to.

When the exact solution doesn't exist as a large building block, this design principle falls apart completely, and you are again writing in C - or in the latter example, designing your own PCB and writing your own drivers from scratch. That's usually when I'm being asked for help.
« Last Edit: July 24, 2019, 10:40:52 am by Siwastaja »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf