starting with STM32 CMSIS - Page 1
Forum section: electronics / general

author: vixo
author_rank: Regular Contributor
timestamp: July 15, 2019, 01:31:51 pm
content: I want to start programming the STM32 chips and have bought a STM32F4 discovery board. I'm using the cubeMX and Atollic truestudio. I have succesfully programmed a blink sketch (hooray) using the HAL, but as I understand a) the HAL is often inefficient b) I want to learn about the chip itself and c) I have a bit of experience programming 8-bit AVRs so direct register access or something lower level feels comfortable to me.So if I understand correctly you can use HAL and CMSIS in the same file no problem, so I'm trying to use cubeMX to set up my project and set all the output pins etc. then i want to use the CMSIS only in the main program loop only to toggle the bits of the output register, but I can't find anywhere which has a list of all the registers for my chip. I just need to find which register is should talk to (im assuming its something like GPIOA) but i can't find that information anywhere in the stm32f407xx.h file linked in the CMSIS and I can't find an authoritative resource anywhere online that tells me either.Secondly, i'm not sure what syntax my compiler will support - normally if i was using AVR-GCC i would use something likeCode:PORTA ^= 0xFF;but does this work for the CMSIS? Can i just replace PORTA with the appropriate register names?any help much appreciated

author: MasterT
author_rank: Frequent Contributor
timestamp: July 15, 2019, 02:03:22 pm
content: Not sure about discovery, if it's stm32f407 based than you need to download :"RM0090Reference manualSTM32F405/415, STM32F407/417, STM32F427/437 andSTM32F429/439 advanced Arm®-based 32-bit MCUs"To drive GPIO pin with HAL:HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_RESET);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_6, GPIO_PIN_SET);Or you can locate HAL_GPIO_WritePin() subfunction and dissect it down to direct port manipulation.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 15, 2019, 02:30:43 pm
content: Under the hood, those functions use the GPIOx_BRR and GPIOx_BSRR registers for I/O bitwise handling (you need to check out the reference manual to understand how that works). On ARM Cortex MCUs, you don't directly write to output latches for bitwise writes, unlike other MCUs. There are bit set and reset registers. You can also write a whole port through the ODR register, but that's not recommended for setting and resetting individual bits as it would be clunky and not necessarily atomic.Using the CMSIS header file for your specific MCU, writing to individual I/O bits would look something like, for instance:(defining the proper target in your project and including the "stm32f4xx.h" header should do.)GPIOA->BSRR = xxx;That's basically what the HAL functions do.

author: vixo
author_rank: Regular Contributor
timestamp: July 15, 2019, 02:43:46 pm
content: Quote from: MasterT on July 15, 2019, 02:03:22 pmthanks! as i understand it though, CMSIS is all designed by ARM itself - this seems like proprietary ST stuff? Is there a difference between what is listed here?Quote from: SiliconWizard on July 15, 2019, 02:30:43 pmstupid question - what does this syntax mean? I'm not sure what the -> is for. is there a resource to tell me any syntax meanings I dont yet understand?

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 15, 2019, 02:49:07 pm
content: Quote from: vixo on July 15, 2019, 02:43:46 pmThis is accessing a struct field through a pointer. This is basic C. So I'd suggest you begin with a decent C book.

author: AndyC_772
author_rank: Super Contributor
timestamp: July 15, 2019, 02:50:21 pm
content: The -> operator is pure C, there's nothing proprietary or unique to CMSIS about it.In this case, "GPIOA" is a pointer to a structure, so GPIOA->BSRR refers to the element called BSRR of the structure pointed to by GPIOA.

author: vixo
author_rank: Regular Contributor
timestamp: July 15, 2019, 03:00:06 pm
content: ok great I'll look it up.Out of curiosity, what is the reason you don't just write direct to registers?

author: MasterT
author_rank: Frequent Contributor
timestamp: July 15, 2019, 03:52:00 pm
content: No reason, except of using alphabetical acronyms (GPIOA) instead of 32-bits binary address. You can write directly:(*(uint32_t*)adres_reg) = temp2;For example, if I want to change PWM settings of timer-2 :(*(uint32_t*) 40000034) = 1;I always do reading-writing directly down to specific bit for debugging purposes, though it's require some precaution :1. there are registers read-only/ write-only;2. there are registers that must be set/ unset in specific order - sequence,3. PLL, analog circuits may require specific timing or delay in between set-reset.This is why programming reference manual from manufacturer is important .

author: janoc
author_rank: Super Contributor
timestamp: July 15, 2019, 04:17:31 pm
content: There is a very nice C++ library that handles the which bit in which register is read/write-only and that the literals you are writing to specific places have correct width (if you screw up you get a compile error instead of a runtime bug/crash):http://kvasir.io/It is all templated C++, so runtime/memory cost is zero - multiple register bit manipulations all get optimized down into a single large register write like: foo = 0x12345678;The advantage is readability of the code, which, unless you copiously document your register manipulations, tends to be worse when doing direct register programming than when using some sort of abstraction (like HAL), especially on complex chips like ARMs where some peripherals are controlled by tens of different registers and bits.The only disadvantage is the documentation but the basics are not difficult to learn. The library is generic, it works with any MCU that has a published SVD file describing the registers (most MCUs have these files published).

author: AndyC_772
author_rank: Super Contributor
timestamp: July 15, 2019, 04:27:07 pm
content: Quote from: vixo on July 15, 2019, 03:00:06 pmDoes your IDE allow you to view the C code after it's been through the pre-processor? You might find that your code *is* just writing direct to registers, but thanks to the header files, those registers have relatively easy to remember, portable names.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 15, 2019, 04:36:10 pm
content: It also makes the declarations themselves much more compact, and thus, less error-prone for the manufacturer writing the headers.Registers are memory-mapped. GPIO ports each have a set of associated registers that all have the same function and same offset relative to the base address of the port's register, so it's a lot easier to just declare the base address through a base pointer (such as GPIOA) and nothing else needs to be declared except a single typedef for the struct defining the registers for each port.On those MCUs, there are again many registers for each port, and not just a single register for accessing it like on some older/simpler MCUs.Declaring each register individually is of course possible, but it would look kind of clunky: eg: GPIOA_BSRR (well to each their own), would make a very long list of declarations in the headers and again, would be more error-prone.

author: langwadt
author_rank: Super Contributor
timestamp: July 15, 2019, 05:01:01 pm
content: Quote from: AndyC_772 on July 15, 2019, 02:50:21 pmiow shorthand for (*GPIOA).BSRR

author: mark03
author_rank: Frequent Contributor
timestamp: July 15, 2019, 06:02:51 pm
content: Quote from: vixo on July 15, 2019, 03:00:06 pmAs others have pointed out, this *is* writing directly to the registers. It may help to skim through stm32f4xx.h and see how the identifiers like "GPIOA" are defined. (Actually, you may need to go one level deeper as I think that file just #includes the model-specific file. You'll know you've found the right one when it's many thousands of lines long.) You will see that each peripheral in the chip has its own base address, which is what identifiers like GPIOA or SPI3 are pointers to. Then the registers inside the peripheral all have some offset from this base address, so it is natural to define those as a structure, so you access a specific register by using a [plain old C] construction like GPIOA->BSRR. Otherwise, this is pretty much the same as what you're used to from AVR. Just remember that most registers are now 32 bits wide.To answer your question about ST proprietary vs ARM, understand that CMSIS is a standard for [among other things] how the features and peripherals of any Cortex M processor should be exposed in software. It doesn't mean that different processors from different vendors will have the same peripherals and registers! It defines naming standards, and some helper functions, e.g. calls to enable or disable an interrupt. So that huge header file with all of the register stuff in it complies with CMSIS, but the register details are all ST.Someone already pointed you to the reference manual. For ST processors, that's where you find the register details. The big advantage of programming the way you are trying to do, is that 99.9% of the time the names of registers and bit fields are the same between the reference manual and the C header file. So you can program with just the reference manual PDF open on one screen and your IDE on the other. You rarely if ever need to look anything up in the header file because you already know the exact names to type in. Compare that to the HAL where it's anybody's guess what the function to toggle a GPIO is called... thus you're always having to search in the HAL files for the right names.

author: vixo
author_rank: Regular Contributor
timestamp: July 15, 2019, 07:39:40 pm
content: brilliant. thankyou

author: westfw
author_rank: Super Contributor
timestamp: July 15, 2019, 08:47:15 pm
content: Heh. I just posted a long response on the same subject on another forum (although, with an Atmel SAMD flavor.)Here it is. It sounds like you particularly need to study that first reference:Representing and Manipulating Hardware in Standard C and C++A nice part about this is that since ARM "standardized" the general style in CMSIS, what you learn will be applicable to other ARM chips as well. (And elsewhere. The new AVR Mega-0, Tiny-0, and Tiny-1 series are moving to this sort of structure-based peripheral definition.)-QuoteCMSIS is an ARM standard, the most important parts of which are:Peripheral registers are accessed as memory (ARM doesn't have any separate "peripheral" instructions, so everything is located somewhere inside the 32bit address space.)The memory space for each particular peripheral is described by a C "structure" whose start address is at the beginning peripheral. This is a very common technique for accesses memory-mapped peripherals, but may seem strange if you haven't seen it before. Seehttp://www.open-std.org/jtc1/sc22/wg21/docs/ESC_SF_02_465_paper.pdffor example. The newer AVR chips are also setting things up like this.ARM "standard" peripherals get names and content defined by ARM. This is things like the Systick timer and the Interrupt Controller.Individual vendors have a lot of latitude on the details of their vendor-specific peripherals. Atmel has the convention that each peripheral register has a .reg and .bits union for each register - use the .reg to access the "full" register at once, use .bits to access individual bitfields within the register. (accessing bitfields can be somewhat prone to unexpected behavior, since the chip itself will need to access full registers.) Sometimes vendors do a poor (IMO) job.All this usually involves some pretty ugly C code that is somewhat compiler dependent and causes Language experts to groan, but in general end users don't need to worry about that - the necessary include files for a particular compiler are provided, and they'll work.-So forPORT->Group.DIR.reg:PORT is where all of the SAMD gpio ports start, defined in...tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd51/include/samd51j19a.h:Code:#define PORT ((Port *)0x41008000UL) /**< \brief (PORT) APB Base Address */-They're evenly spaced, and implemented as an array of PortGroup members (one for each of PORTA, etc), in.../tools/CMSIS-Atmel/1.2.0/CMSIS/Device/ATMEL/samd51/include/component/port.h:Code:typedef struct {PortGroup Group; /**< \brief Offset: 0x00 PortGroup groups  */} Port;-(Yeah:PORTis actually 4 ports, a single port is called aPortGroup, and what's in the datasheet as PORTA should be referred to asPORT.Group. That's the sort of thing I meant by "Poor descisions.")PortGroup is defined (also inport.h) with the individual registers:Code:typedef struct {__IO PORT_DIR_Type DIR; /**< \brief Offset: 0x00 (R/W 32) Data Direction */__IO PORT_DIRCLR_Type DIRCLR; /**< \brief Offset: 0x04 (R/W 32) Data Direction Clear */__IO PORT_DIRSET_Type DIRSET; /**< \brief Offset: 0x08 (R/W 32) Data Direction Set */__IO PORT_DIRTGL_Type DIRTGL; /**< \brief Offset: 0x0C (R/W 32) Data Direction Toggle */__IO PORT_OUT_Type OUT; /**< \brief Offset: 0x10 (R/W 32) Data Output Value */__IO PORT_OUTCLR_Type OUTCLR; /**< \brief Offset: 0x14 (R/W 32) Data Output Value Clear */__IO PORT_OUTSET_Type OUTSET; /**< \brief Offset: 0x18 (R/W 32) Data Output Value Set */__IO PORT_OUTTGL_Type OUTTGL; /**< \brief Offset: 0x1C (R/W 32) Data Output Value Toggle */__I PORT_IN_Type IN; /**< \brief Offset: 0x20 (R/ 32) Data Input Value */__IO PORT_CTRL_Type CTRL; /**< \brief Offset: 0x24 (R/W 32) Control */__O PORT_WRCONFIG_Type WRCONFIG; /**< \brief Offset: 0x28 ( /W 32) Write Configuration */__IO PORT_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x2C (R/W 32) Event Input Control */__IO PORT_PMUX_Type PMUX; /**< \brief Offset: 0x30 (R/W 8) Peripheral Multiplexing */__IO PORT_PINCFG_Type PINCFG; /**< \brief Offset: 0x40 (R/W 8) Pin Configuration */RoReg8 Reserved1;} PortGroup;-And then each register is also defined in port.h (the __IO vs __I is elsewhere, though.)-Also note the comparatively huge number of individual registers assigned to each peripheral. And the unallocated space ("Reserved") that makes the arrays come out even. You can get pretty creative when you have a couple of gigabytes of address space to throw at things...-This all works pretty well, in the end. Note that the compiler will normally optimize away what looks like it might be inefficient ("array accesses just to find the port??"), so the resulting binary code is about as good as it could be if you did it any other way...

author: techman-001
author_rank: Frequent Contributor
timestamp: July 16, 2019, 12:47:39 pm
content: Quote from: vixo on July 15, 2019, 01:31:51 pmIf 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 10Then 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.For more information please see the main Mecrisp-Stellaris Homepage athttp://mecrisp.sourceforge.net/and my blog site athttps://mecrisp-stellaris-folkdoc.sourceforge.ioCheers,Terry

author: mark03
author_rank: Frequent Contributor
timestamp: July 16, 2019, 05:27:27 pm
content: Quote from: techman-001 on July 16, 2019, 12:47:39 pmPretty sure Messrs Kernighan and Ritchie would disagree with you on thatNot to mention all the language purists who bash on C for being too closely tied to hardware considerations.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 16, 2019, 05:32:52 pm
content: Yes that was a good one. A bit of shameless advertising.

author: GeorgeOfTheJungle
author_rank: Super Contributor
timestamp: July 16, 2019, 08:08:52 pm
content: Quote from: techman-001 on July 16, 2019, 12:47:39 pmClear as mud...

author: techman-001
author_rank: Frequent Contributor
timestamp: July 17, 2019, 04:47:00 am
content: Quote from: mark03 on July 16, 2019, 05:27:27 pmPerhaps my use of the term "hardware interaction" is a bit ambiguous.For example a forth user can turn a led ( or anything) on or off on the actual hardware without a 'C' compile and download cycle, read a register, modify a register etc, no compile and download cycle, it's all in real time on the hardware via a interactive Terminal connection.If one is unsure what will happen when a Bitfield is changed, they can see it immediately with Forth, in real time.This is 'interactivity with the hardware' as enjoyed by a Forth user.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 17, 2019, 04:59:36 am
content: Quote from: GeorgeOfTheJungle on July 16, 2019, 08:08:52 pmGeorge wishes us all to know that he can't program in Forth, or read Forth code.Grazie per averlo condiviso, George.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 17, 2019, 05:08:04 am
content: Quote from: SiliconWizard on July 16, 2019, 05:32:52 pmWas that directed at me ?Mecrisp-Stellaris is Free and Open Source Software, licensed under the GPL. It's totally Free to download and use.I'm not 'advertizing' it, I'm announcing it's existence and benefits to those that may find it useful, specifically the OP of this topic.

author: MasterT
author_rank: Frequent Contributor
timestamp: July 17, 2019, 12:51:24 pm
content: Quote from: techman-001 on July 17, 2019, 04:47:00 amNo need for a Forth, reading-mod-writing all could be done in arduino IDE environment on the fly. A while ago I posted a sketch:http://www.stm32duino.com/viewtopic.php?f=18&t=4405Interesting things happened when I change timers period w/o autoload-preload active, than it takes long time to roll-over and get new settings.Changing common GPIO drive strength (frequency) and watch on a scope till satisfy with rising /falling timing.

author: noweare
author_rank: Newbie
timestamp: July 19, 2019, 01:23:14 am
content: When I got started using stm32 boards I programmed in direct register access because thats the way the manual is written so it was easy to follow. After a while doing that I could look at the HAL code and understand whats going on. Initially HAL is intimidating, at least to me. The Low Level functions are really awesome though. A bit higher level than direct register programming and kind of self documenting. TrueStudio is really nice to work in also.

author: Doctorandus_P
author_rank: Super Contributor
timestamp: July 22, 2019, 11:02:01 am
content: If you are interested in the very low level stuf of compiling anything for STM32, then I highly recommendhttp://www.pandafruits.com/stm32_primer/stm32_primer_hardware.phpIt is a very short and concise tutorial, yet It handles everything from linkerscripts, makefiles and compiling to working with STM32 registers and clock distribution, and even a bit of programming and debugging.It is a very good overview of all the low level stuff that IDE's usually do under the hood.Knowing how this stuff all fits together helps wen working (and trouble shooting) more "advanced" tools.

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: July 22, 2019, 04:12:16 pm
content: Quote from: techman-001 on July 16, 2019, 12:47:39 pmYeah, consistently crappy. There's a reason why C is the industry standard language for embedded development and Forth is not.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 22, 2019, 11:34:54 pm
content: Quote from: Sal Ammoniac on July 22, 2019, 04:12:16 pmWebsters 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-10And 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-10These 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 offThose 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.

author: langwadt
author_rank: Super Contributor
timestamp: July 23, 2019, 12:37:16 am
content: Quote from: techman-001 on July 22, 2019, 11:34:54 pmapart from being in an obscure language few uses how is it any better than a C macro?

author: Siwastaja
author_rank: Super Contributor
timestamp: July 23, 2019, 05:56:22 am
content: Quote from: techman-001 on July 22, 2019, 11:34:54 pmNumber of elements your brain needs to understand:1) :2) GPIOA_BSRR3) _BS104) %5) 16) 107) lshift8) why GPIOA_BSRR comes again?9) bis10) !11) ;Equivalent C:GPIOA->BSRR = 1<<10;1)GPIOA->BSRR2) =3) 14) <<5) 106) ;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.

author: GeorgeOfTheJungle
author_rank: Super Contributor
timestamp: July 23, 2019, 06:10:34 am
content: QuoteGPIOA->BSRR = 0x400;1)GPIOA->BSRR2) =3) 0x4004) ;IIRC the Open Firmware in the PPC Macs was written in Forth, and had a Forth shell.

author: westfw
author_rank: Super Contributor
timestamp: July 23, 2019, 06:12:49 am
content: QuoteQuoteQuoteFirst 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:digitalWrite(15, HIGH);A more exact translation would be:Code: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.)QuoteHow 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...

author: techman-001
author_rank: Frequent Contributor
timestamp: July 23, 2019, 09:46:54 am
content: Quote from: Siwastaja on July 23, 2019, 05:56:22 amNicely put apart from the cheap shot at anything NOT-C1) ":" means compile the following function2) 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 CI 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 105) lshift means "left shift". "10 lshift" means shift left 10 places6) 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"";" completes the functionNow let us imagine I don't know any C syntax ?GPIOA->BSRR = 1<<10;1) GPIOA2) -3) >4) BSRR5) =6) 17) <<9) 1010) ;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.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 23, 2019, 10:04:16 am
content: Quote from: langwadt on July 23, 2019, 12:37:16 amApple 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 ?

author: GeorgeOfTheJungle
author_rank: Super Contributor
timestamp: July 23, 2019, 10:27:41 am
content: EFI uses Forth as well? Are you sure?

author: techman-001
author_rank: Frequent Contributor
timestamp: July 23, 2019, 11:44:41 am
content: Quote from: GeorgeOfTheJungle on July 23, 2019, 10:27:41 amUm ... noFreeBSD:I'm not a bootloader expert by any means but Freebsd uses LOADER(which is Forth based and supports the following architectures:x86 (PC, UEFI, coreboot, OLPC, Mac), ARM (U-Boot, UEFI), MIPS, PowerPC, SPARC v9The following filesystems:FAT12/FAT16/FAT32/VFAT, ext2, NANDFS, ISO-9660, UFS, ZFSand gzip, bzip2 compression.Source:https://en.wikipedia.org/wiki/Comparison_of_boot_loadersman 8 loader has this to say:The program called loader is the final stage of FreeBSD's kernelbootstrapping process. On IA32 (i386) architectures, it is a BTX client.It is linked statically to libstand(3) and usually located in thedirectory /boot.It provides a scripting language that can be used to automate tasks, dopre-configuration or assist in recovery procedures. This scriptinglanguage is roughly divided in two main components. The smaller one is aset of commands designed for direct use by the casual user, called"builtin commands" for historical reasons. The main drive behind thesecommands is user-friendliness. The bigger component is an ANS Forthcompatible 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"

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: July 23, 2019, 04:58:24 pm
content: Quote from: techman-001 on July 23, 2019, 09:46:54 amI'm curious to hear your take on why C became the industry standard programming language for embedded systems and Forth did not.

author: westfw
author_rank: Super Contributor
timestamp: July 23, 2019, 08:31:30 pm
content: QuoteMeh. 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)

author: techman-001
author_rank: Frequent Contributor
timestamp: July 23, 2019, 08:52:21 pm
content: Quote from: westfw on July 23, 2019, 08:31:30 pmPlease 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 selectionI have to ask, do you have any recent experience configuring modern MCU's with thousands of Bitfields ?

author: langwadt
author_rank: Super Contributor
timestamp: July 23, 2019, 09:26:20 pm
content: Quote from: techman-001 on July 23, 2019, 08:52:21 pmyou argue that forth isn't an obscure language that few use because it is used in bootloadersusing the same logic the billions of people who use a computer or cellphone have recent experience configuringmodern MCU's with thousands of Bitfields

author: Bassman59
author_rank: Super Contributor
timestamp: July 23, 2019, 10:03:25 pm
content: Quote from: techman-001 on July 16, 2019, 12:47:39 pmAll 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.

author: westfw
author_rank: Super Contributor
timestamp: July 24, 2019, 03:20:00 am
content: QuoteActually, 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!QuoteYeah. 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 !"

author: Siwastaja
author_rank: Super Contributor
timestamp: July 24, 2019, 06:56:05 am
content: Quote from: westfw on July 24, 2019, 03:20:00 amThis. 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 featurespecifically 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 registeris, 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.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 09:11:00 am
content: Quote from: Sal Ammoniac on July 23, 2019, 04:58:24 pmNot 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 etcSome 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 athttps://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 100 variable oldinput: sieve ( newinput -- output only if newinput = oldinput +- sieve-size )dup oldinput @ sieve-size - <= if 0 >r else 1 >r thendup oldinput @ sieve-size + >= if 0 >r else 1 >r thenr> r> and if drop oldinput @ else dup oldinput ! then;power-on fill wash drain empty fill wash drain spin power-offSummary: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'.

author: cv007
author_rank: Frequent Contributor
timestamp: July 24, 2019, 09:43:28 am
content: 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/kgM46Mits 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.QuoteThey are using C++ and they don't even know it.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 09:44:00 am
content: Quote from: westfw on July 24, 2019, 03:20:00 amThe 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-bitfieldsWhy 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 0becomes: fire-thermonuclear-warhead-missile %1 0 lshift GPIOA_BSRR bis! ; ... which is uploaded into the Forth Terminal and becomes a Dictionary WordSimplistic 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" THENWhat 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

author: Siwastaja
author_rank: Super Contributor
timestamp: July 24, 2019, 10:09:01 am
content: 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 haveanythingto do with C. Quite the opposite - they are not using C features which would help reducing such code, instead depend onautogeneration. 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, andthenI 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).

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 10:14:49 am
content: Quote from: cv007 on July 24, 2019, 09:43:28 amCompile 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 bitsAs 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 AF7I just enter this command to set GPIOA-0 as a OUTPUT :OUTPUT GPIOA_MODER_MODER0or if I want Alternate Function 7 for that pin:AF7 GPIOA_MODER_MODER0I 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.

author: westfw
author_rank: Super Contributor
timestamp: July 24, 2019, 10:20:57 am
content: QuoteCould 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?QuoteSure 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"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!

author: Siwastaja
author_rank: Super Contributor
timestamp: July 24, 2019, 10:26:41 am
content: Quote from: techman-001 on July 24, 2019, 10:14:49 amI 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 happenswithout any autogenerated codefrom 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:#define HI(port, idx) do{(port)->BSRR = 1UL<<(idx);}while(0)#define LO(port, idx) do{(port)->BSRR = 1UL<<(16+idx);}while(0)

author: Siwastaja
author_rank: Super Contributor
timestamp: July 24, 2019, 10:34:30 am
content: Quote from: westfw on July 24, 2019, 10:20:57 amIt'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 tocontrolthe 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 cancalculatethings, 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.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 10:57:31 am
content: Quote from: Siwastaja on July 24, 2019, 10:09:01 amWe can probably agree that 'poor C programmers' can produce horrible code, but 'poor Forth programmers' produce the absolute worst code ever written by man.I used to be very happy with C, I found it easy to read and easy to write. Now I use Forth instead not because Forth is 'better' but because *I* prefer it.I have always agreed with your advice here on this forum that new C programmers start at the beginning, no libraries, read the tech manuals, understand how it all works.Forth Interactivity:Firstly I must say that modern systems with SWD/JTAG debugging via GDB are fast and awesome. I personally refused to use Forth until my development system was as fast or faster than the above because I loathe slow design environments.1) You have a complex RTC chip, or it may be in your MCU, either way the Ref Manual is ambiguous about something and you can't get a certain thing to work the way you need to. This is a common issue, the manual may be Chinese and 'converted' to English poorly etc.Forth allows you to quickly 'play around with the RTC config' by writing and reading registers in real time, until you find out what really happens, (at which point the manual usually begins to make obvious sense). It is very fast with no compile, flash, try, redo cycles.2) You want to adjust a timing loop, the scope is connected all you need to do is play around with numbers in a register. Forth allows you to do this in real time and 'get a feel for the hardware'. I know you can do this with GDB etc, but it's utterly trivial in Forth.3) The prototype is ready and many configuration numbers have been estimated but it still needs fine tuning on the actual Turbo Encabulator as the inverse phase detector values are uncertain. With Forth you can use a Android Tablet running a Serial Terminal and enter the values in by hand at the actual machine in the gearbox factory. You don't need to drag your design environment over there just to do the fine tuning.4) You've just been given a project and you have a hundred ways to make it, a hundred different parts you could use and you're racked with indecision at this point. At least this has always been a common experience for me, that first step before anything exists.Forth allows you to breadboard and be interacting with the hardware in minutes, testing timing, getting a feel for that new chip you haven't had time to test but which might be *perfect* for this new project. I find that first step is the hardest and so I just make sure I test *something* anything that will do the job, and once I start, things seem to naturally fall in place.Not one line of C code has to be written, compiled, flashed or whatever.I guess the summary is:C users select the hardware, study the manuals, write the code, compile, flash, test, debug etcForth users just open the manuals, plug in the hardware and start interacting with it, finding what works, what doesn't ... THEN they start writing the code based on their observations.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 11:08:47 am
content: Quote from: Siwastaja on July 24, 2019, 10:34:30 amI totally agree, and Arduino users at this point are *well* outside their comfort and experience zone because they are not engineers.If they were engineers, they wouldn't be using Arduino.The cool new PCB they design looks great in all it's Kicad 3D glory, it's based on a design they found on the Internet but the motor is hunting or noise is a problem, or the regulator has bunt a TO220 size brand on the tip of their nose as they tried to locate the burning smell.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 11:32:54 am
content: Quote from: Siwastaja on July 24, 2019, 10:26:41 amI certainly wouldn't want to bore you by being overly pedantic, but I haven't repeated MODER in the line "GPIOA_MODER_MODER0"GPIOA = PeripheralMODER = RegisterMODER0 = Bitfield (bit 0)I have tried other strategies, such as GPIOA_MODER0 but sadly the CMSIS-SVD naming that STM uses won' allow it due to some repetition of BITFIELD names withing the SAME REGISTERS, so I'm stuck with using the complete nomenclature above. I can't really criticize STM because of the *massive* numbers of bitfields, I mean someone HAS to screw up somewhere sometime ?Once I would have loved your C code and system for handling MCU bitfields, but now as a Forth user, it looks very ugly and overly complex to me.I'm not claiming it IS ugly and overly complex, it only looks like it to me because I don't want to abstract anything away, I want everything in plain sight and in what I consider to be the problem definition language of my creation."All of this happenswithout any autogenerated codefrom my part", sure, but all your header files are auto-generated from CMSIS-SVD if you use ARM based chips.I admit my initial config Words are totally technical and not fun to read, that's why they go in my config.fs file where they wont insult my eyes. Not that your C header files make pleasant reading either ;-)Nevertheless I like "AF7 GPIOA_MODER_MODER0" very much as it's totally 100% descriptive, unambiguous and can be read by anyone who knows Forth, CMSIS-SVD and STM32F0 MCU hardware, intimately.Thank you for pointing out in detail the C methods you use to do the same kind of things I do in Forth,

author: Siwastaja
author_rank: Super Contributor
timestamp: July 24, 2019, 12:24:38 pm
content: Quote from: techman-001 on July 24, 2019, 11:32:54 amThis is where language features are supposed to come to the rescue. C, for example, has this great thing called preprocessor, often overlooked as an ugly hack, but in practice, it can concatenate and create strings and work around with name issues.I have an API which, in a write-once manner, automagically creates lookup tables which hold pointers with correct types to the data, size of said data, automagically calculated from the struct contents, and automagically created name string through preprocessor stringification.But features are two-edged swords. Very few would disagree if I said that C++ has so many features in it that very few understands them all.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 12:38:18 pm
content: Quote from: westfw on July 24, 2019, 10:20:57 amI'd love to try and explain this further, apologies in advance for the usual ambiguities, bad spelling and comprehension. Warning: LONG!The Forth I use. Mecrisp-stellarishttp://mecrisp.sourceforge.net/comes as a binary ready to flash to the target MCU. By default it has a extensive Dictionary of Words as can be seen here:https://mecrisp-stellaris-folkdoc.sourceforge.io/words.html#id1My CMSIS-SVD autogenerated peripheral memory map Words and my register bitfields are totally separate to Mecrisp-Stellaris and based on initial work by Ralph Doeringa few years ago.My "svd2forth" stuff uses a XLST processor to generate the format I chose by processing any XML micro.svd file.It's explained here:https://mecrisp-stellaris-folkdoc.sourceforge.io/register-generator.html#cmsis-svdI develop as shown in this pic:https://mecrisp-stellaris-folkdoc.sourceforge.io/modern-forth-development-environment.html#a-modern-forth-ideBasically I apply power to the hardware and see the Forth boot up greeting in the terminal window and I know I'm ready to start.So lets assume I'm interested in GPIOC-8, I can ether:1) search the preopened bitfields template file ... too slow2) scroll thru my preopened bitfields template file ... too hard3) In Gvim :a) In insert mode, type first part of syntax and place cursor at the end of the search phrase i.e.: GPIOC_MODER_<-- cursor hereb) Enter <ctrl x> <ctrl l> and up pops a list of similar words from bitfields.fs which contains every bitfield for the mcu listed.c) select desired line and hit enter and the following is inserted in my source: GPIOC_MODER_MODER8 ( %XX -- ) 16 lshift GPIOC_MODER bis! ; \ GPIOC_MODER_MODER8 Port x configuration bits y = 0..15Note: my system strips all comments "\ I'm a comment" from the source and uploads to the MCU at 460800 baud, (too fast to read).4) I click on the "MAKE" icon in Gvim and my source is then uploaded to the MCU which then compiles it. I have only clicked MAKE, I haven't touched the terminal window or pasted anything to it etc. The makefile strips the comments and then uses a remote connection to GNUSCREEN to upload the code.Any errors in the code will be flagged in RED text and the PC bell will beep to wake me up."GPIOC_MODER_MODER8" now appears in my Forth Dictionary in the MCU.After this is done, I can manually enter "INPUT GPIOC_MODER_MODER8" and hit enter in the terminal window and GPIOC-8 is instantly a INPUT.I can also do that in the editor window but it wont take effect until the next MAKE.To check that GPIOC-8 is now a input I can enter : "gpioc_moder." and I'll get a nice pretty printed register state as below (taken from a working system where bit 7 has been configured as a INPUT in exactly the same way.GPIOC_MODER (read-write) $0000400015|14|13|12|11|10|09|08|07|06|05|04|03|02|01|0000 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00Tethered Python:Forth can run standalone on the target MCU as Mecrisp-Stellaris does. This means the MCU needs to have enough Flash to hold the 20KB Forth binary plus room for the user code. I use the STM32F051 which has 64KB Flash. A 1K line Forth program is considered long, So I have tons of room.This is where C wins hands down because a C 'blinky' may be as small as 300 bytes but a Forth Blinky would probably need 20030 Bytes, substantially more.However we also have 'Terthered Forths" where a HOST contains all the intelligence and is "tethered' to a TARGET chip with a cable supplying power and JTAG etc.In this case the Forth Terminal appears to be talking to the Target, and interaction exactly like I have described above can take place when in "target' mode. GPIO's can be set, cleared tested and so on.However the actual target code speed will be slower than if Forth was running on the target.The payoff is that this competes with C in optimizations and code size on the target so a "Blinky" done this way in Forth would probably be a binary size of 80 bytes for the complete standalone self booting image with all the init code, interrupt vectors etc. It's also a binary file, no Forth, no terminal for your customers or competitors to play around with. You're also not bound by the GPL license regarding binaries you produce with it.The HOST can be instructed to produce a standalone binary file at any point and flash it to the target.We actually have a working Tethered Forth here:https://mecrisp-across-folkdoc.sourceforge.ioThe really cool thing is that the HOST is a Ti Tiva Connected Launchpad which cross compiles (using Mecrisp-Stellaris) for a Ti MSP430 TARGETNow I see no reason that a 'Tethered Micro Python" shouldn't exist and work the same way, then it too can produce binary file sizes as small as it can optimize.This would mean that small Flash chips with say 16K could be used by a Tethered Python just like C or a Tethered Forth.Note: Mecrisp-Across, our Tethered Forth works perfectly with a virgin MSP430 straight out of a new factory tube, no code is preloaded, the chip is totally blank. In other words, no bootloader or anything.Python Web scraper:Awesome, I'm not a big Python fan, I don't like the whitespace terminators, but I'm not criticizing Python, I use and love some indispensable apps that are written in Python so it is clearly very capable and coder friendly.Python is certainly the Poster Child of the Revolution these days hence my surprise that no Tethered Python for small MCU's exists that I know of.I'm slowly learning LISP which represents my highest HLL language aspirations as a electronics technician. LISP is the closest cousin to Forth one can find in that they are both able to reprogram themselves.By that I mean the Forth Word ": + - ; " when executed like this:2 2 + . ( 2 + 2 then print the result with . )Will give zero and not 4. Why would you want to do this, I wouldn't but it demonstrates what I said above. Try that with your language of choice, can you redefine + as - ?

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 12:50:37 pm
content: Quote from: Siwastaja on July 24, 2019, 12:24:38 pmI'm definitely agreeing with you that C/C++ is complex and gets more complex as bits are tacked onto it to do everything. It's far too complex for me.I don't need to use anything but my XLST processor to fix the problem at it's source, (and I've been tempted) but what would be the result ?NON STANDARD CMSIS-SVD which would make my Forth Source unique and non-standard. My source code wouldn't match the technical references, it would be a abhorrence, a misshapen ugly thing that the Forth crowds would burn at the nearest stake with me beside it.So I won't be doing that anytime soon. But really, it's not overly onerous, I just use the full CMSIS-SVD nomenclature, automatically.Then my only problem is reading your complaints that it's too long ;-)

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 01:01:20 pm
content: Quote from: Bassman59 on July 23, 2019, 10:03:25 pmI lost interest replying to you after reading your first line.Instead of pointless diatribe with me, perhaps you'd be better off rechecking that your workers haven't been snipping bits from your prized and inordinately expensive roll of "oxygen free, silver plated, HIFI loud speaker wire" ... again.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 01:10:10 pm
content: Quote from: langwadt on July 23, 2019, 09:26:20 pmActually Oracle had this to say about Forth "Said Oracle @https://docs.oracle.com/cd/E63648_01/html/E63649/gpsgy.html"The OpenBoot CLI is based on theindustry-standard interactive programming language called FORTH.Combining sequences of commands to form complete programs provides the capability for debugging hardware and software."You'd think Oracle would know ?Using your logic the billions of people who use a computer or cellphone have recent experience programming not-Forth ?

author: langwadt
author_rank: Super Contributor
timestamp: July 24, 2019, 03:02:54 pm
content: Quote from: techman-001 on July 24, 2019, 01:10:10 pmjust because oracle says it industry standard doesn't make not obscure, very very few people are programming forth for bootloaders

author: Sal Ammoniac
author_rank: Super Contributor
timestamp: July 24, 2019, 05:13:29 pm
content: Quote from: techman-001 on July 24, 2019, 09:11:00 amOkay, call it the de facto industry standard, then. It's clear that the majority of professional (that's what I meant by "industry") embedded development has been and is still done in C.QuoteWhy is this an issue for Forth? Forth has been around longer than C, so why isn't it standardized to the same degree C is? Doesn't the IEEE, ANSI, ISO, etc., care about this?QuoteWhy isn't Forth easy to market? What is it about the language that make it unmarketable?QuoteI'm not talking about hobbyists here--I'm talking about professional embedded developers, who don't typically use Arduino hardware or software. Sure, Arduino made it easy for hobbyists to get into embedded programming, but that was never an issue for professionals. Professionals will learn whatever they have to to get the job done, no matter how difficult it may be.QuoteAgain, that may be true for amateurs, but professional developers generally don't care about libraries. Every company I've worked for in my 35 year embedded career did not use vendor libraries--we wrote our own peripheral driver code from scratch. Most vendor libraries are utter crap anyway.QuoteInteractivity, or lack of it, has never been an issue in professional embedded development. A good debug environment provides all that's necessary here. Nowadays that's JTAG interfaces to debug capabilities built into the MCU; back in the day it was in-circuit emulators.QuoteThis sounds like metaphysical mumbo jumbo. Perhaps that's why Forth has always had the reputation of being a "hippie" language in the professional development circles I've worked in.QuoteWhy is it hard to master? Perhaps that should tell you something about the design of the language...QuoteThis, IMO, is the chief reason why Forth isn't taken seriously by the embedded community.QuoteAnd I thought Perl looked like line noise. Sheesh...QuoteCommon doesn't mean best, but C has stood the test of time whereas Forth has not. C has perpetually been at the top of the professional embedded development language lists, while Forth is lost in the noise. A rounding error.

author: SiliconWizard
author_rank: Super Contributor
timestamp: July 24, 2019, 05:48:18 pm
content: Quote from: techman-001 on July 17, 2019, 05:08:04 amWell, yes. No offense! I chose not to reply further, as I thought this would just all end up ruining the thread for no benefit to the OP, but the thread has seriously gone popcorn-worthy, so I'm replying now.And then this is probably the polite thing to do.Quote from: techman-001 on July 17, 2019, 05:08:04 amJust because it's open source doesn't mean advertising doesn't apply. "Promoting" may be a better word here? Alright, promoting it will be.Had you not introduced your post with this:Quotewhich I think was pretty off and made some of us chuckle, I would probably have not posted what I did. You're entitled to your opinions, but this one was a bit too much.The other point is that you would probably have made a better point and sparked much more interest if you had kept your initial post shorter and more neutral, even though, given the original title and questions of the OP, it was already a little off-topic IMO.The following posts unfortunately didn't help. Looks like the thread is now ruined beyond repair, so I'm not going to discuss technical points regarding the merits of Forth further in this thread as others have.Maybe try and be a little less offensive and take things a little less personally.I would also suggest you opened a dedicated thread instead . I'm sure that would work way better and maybe spark genuine interest instead of triggering hostile replies.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 24, 2019, 11:38:00 pm
content: Quote from: SiliconWizard on July 24, 2019, 05:48:18 pmYou are indeed very polite in your response, it's so sweet the saccharin is dripping down my screen and leaving a bitter aftertaste.Promoting Free technology isn't a bad thing. Promoting happens all the time here with free giveaways and all manner of sly commercial advertising. Do you want this forum to operate in a technical monoculture full of C users who only discuss C and whom many have no clue what CMSIS really is ?Maybe you do, because in your only post to the OP, you wrote "Declaring each register individually is of course possible, but it would look kind of clunky: eg: GPIOA_BSRR (well to each their own)". How have you helped the OP gain understanding of CMSIS ?The OP, regarding CMSIS in his post:https://www.eevblog.com/forum/microcontrollers/starting-with-stm32-cmsis/msg2550690/#msg2550690asked "... I just need to find which register is should talk to (im assuming its something like GPIOA) but i can't find that information anywhere in the stm32f407xx.h file linked in the CMSIS and I can't find an authoritative resource anywhere online that tells me either ...".I have TONS of information about CMSIS-SVD on my site, and I have a great deal of experience parsing CMSIS XML with XLST to provide output to suit *any* language used for embedded.You accused me of 'promoting' when I linked it this information here, so I must disagree that this topic has drifted seriously off topic.If the OP wants to use CMSIS on the 'bare metal' there is no better solution than Forth, or even Assembly Language. Forths advantage with CMSIS is that it is *INTERACTIVE* in real time, unlike Assembly Language ( or C). The OP said he wanted to " start programming the STM32 chips " and if he begins with CMSIS and Assembly then he is in for a very LONG and frustrating learning curve.I have tried to explain my poor choice of words over the conceited chuckling I hear from C some users. Of course C interacts with hardware, however C is not 'interactive' in the accepted meaning of the word.I'm not interested in garnering Forth interest, my post was about CMSIS. I couldn't care less if you don't use Forth (which has been around since the late 1960's).If you re read vixo's post again you will see he if after information on how to use CMSIS and that my post directly addresses CMSIS at the bare metal level in this link.https://www.eevblog.com/forum/microcontrollers/starting-with-stm32-cmsis/msg2550690/#msg2550690If any C (only) users here are feeling offended, foaming at the mouth and turning green while reaching for the keyboard, do yourself a favor, learn some other programming languages like LISP, Haskell or Ocaml. Expand your mind because there is a world of software and capabilities out there that you can't currently imagine.

author: Siwastaja
author_rank: Super Contributor
timestamp: July 25, 2019, 06:17:57 am
content: It is kinda true that C is notmadefor hardware interaction. Originally, C was designed as a high-level language, to write programs that access OS services through standard libraries. Even the built-in datatypes had random, incompatible widths, no hardware interoperability in mind. C just developed into a strange mix of high-level, and hardware interaction language, mostly inofficially, and it shows in standardization.But does this matter? I think the actual state of things is more important than historical intent; although understanding the historical context can beinteresting.Standardization and marketing arenotstrong points of C. Standardization is lazy, sucky, and leaves a lot of work for non-standard extensions and outright "abuse" of standards. Now this isn't a too big of a practical problem, we just do it that way and call it a day, but purists don't like it. And marketing, what marketing? C wasneververy trendy.The thing with C is, there are very few or no fanboys. I have never heard anyone calling C "elegant". Everyone says "it's just what we use" or "it's acceptable", or "good enough". No one finds it soothing or tao.

author: techman-001
author_rank: Frequent Contributor
timestamp: July 25, 2019, 08:50:02 am
content: Quote from: Siwastaja on July 25, 2019, 06:17:57 amI have to agree that the actual state of things is more important than historical intent.Back in the day, here in Australia, Borland C for DOS was everywhere in shops, along with bookshelves packed with every kind of C book. Maybe it was different elsewhere.