STM32F405RG

I did at one point assume that STM32F105Rx and STM32F405Rx was identical on schematics – they actually are with the exception of two pins. Notice the VCAP pins connected to capacitors at bottom – on a STM32F103 or STM32F105 these are connected to ground.

Graphical Programming Languages

I have always fancied making a graphical programming language. I have also used a few of these as well as done some experimental development myself.

The first challenge is that graphics tend to take up a majority of your time, so you need to carefully select or build a graphic 2D foundation before you start. Unlike a text based language where you can start with any editor and experiment with syntax, you will have to create a complex, 2D graphical design tool before you see your errors. So in my previous attempts I ended up doing a lot of fun graphic work and very little programming language development.

The second challenge is that while some parts do very well in graphic tools, others struggle a bit more. Let me give you examples:

Screen based user interfaces will usually do very well on the design side and is well accepted. Graphic designers have had great success in this for years.

Database design do well because you have established diagram techniques that is well suited to describe a relational database. This is also an area where it is rather easy to auto-generate software due to the high repeatability of tables, columns, relations etc.

Logic is however more difficult. You have little or no auto-generation support, and while a diagram of some kind make the illusion that this is easy it also hides a lot of details. Experienced developers will often work faster in any text based editor, something that defeat the very purpose of our graphical toys.

My conclusion is that I still believe we can dramatically increase our productivity with graphical languages. But, a graphical Language needs to be merged with a text based one – and the graphical part need to be designed with input from a thoroughly study of what new challenges they create for the developers.

Communication Adapter

I have a lot of electronics that I had little time to work on. This communication adapter is one of them. Using a STM32F405RG it communicate between 6 different wired/wireless methods.

The picture on the top show the 3D model, the picture on bottom show the PCB. I had this stack of PCB’s next to me for a while, so I want to assemble the board and see if it work.

  • 10/100Mbps Ethernet using Wiznet W5500
  • USB connection using CH340G
  • Wireless Ethernet using either ESP-01 or ESP-12E
  • NRF24L01 using either breakout or mini adapter.
  • CAN HS with Galvanic Isolation
  • RS485 with Galvanic Isolation
  • MCU STM32F405RG
  • 1Mb Flash
  • 196Kb SRAM
  • 168Mhz ARM M4
  • 8 Leds
  • Full BasicPI SWD Adapter
  • A lot of fun in the waiting.

I will be assembling this tomorrow so look for my next entry…

Plain Libraries

One lesson learned from C#/Java versus other languages is that we need to include standard libraries as part of the language standard. C/C++ do not do this and suffer the consequences of lower portability between platforms as a result. The challenge is that libraries will be larger than the VM itself and many of them will need to be implemented in C/C++. The smaller MCU’s can not be expected to support the same C libraries as we expect to find on Linux/Windows level implementations.

The Assembler and RTL will sort this automatically. As we use a repository we also decide platform and what it contains. The assembler will generate an error if we attempt using content not present on a system. And the RTL will fail at binding the same rejecting any module that require content it does not support.

The following libraries are planned

System has a mandatory content and optional content – all of which is implemented in the host language to allow Plain access to the core system parts. System will cover all basic features needed to actually write a module – including access to RTOS and generic system.

HMI – Human Machine Interface cover standard keyboard, mouse and display as well as buttons, leds etc. Due to the nature of Plain we can easily create a user interface on Raspberry PI operated from an embedded device or wise versa – HMI cover standards to do this so we don’t end up with too much proprietary solutions.

Database library giving us access to any standard database as well as our own proprietary ones. The library will cover a standard way to access data and a standards to include proprietary solutions to ensure that modules accessing a database is portable. The proposal will also include a proprietary, distributed database solution that either can be used stand-alone or as a real-time, distributed front-end to 3rd party solutions. Again- due to the nature of Plain it is straight forward for an embedded device to access a database located anywhere in the network – but, we need to include this in the Plain language definition to secure portability.

Communication. We have an implicit inclusion of easyIPC since it is used by Plain VM, but we need a way to access & control other communication protocols.

Advanced math library – hard to avoid in any system that require math. Standards to let any module access and execute advanced math using resources available in the system.

 Others ? I believe the more stuff we can define & support through standards the better.                        

 

Plain Assembler Design

This is not my first language as I done some proprietary scripting and experimental parsers in the past. This did not lead anywhere expect to influence how I want Plain Assembler to be designed.

The drawing above illustrate the main components.

Repository is a fancy word for a database. Plain is unique as it start by demanding a database in XML format to describe our platform. This file get read into the internal repository before parsing starts. As we parse we build the complete repository that also can be saved back out in XML format and used for the next assembly process so that we don’t have to re-parse everything. Using XML rather than a binary format makes sense because it enable me a way to inspect content + parsing xml is actually far faster than reading a binary file – I know this will surprise some.

The parser read the system diagram and module(s). Each module generate a RTL file that is used to download the plain module(s) one by one. Parsing needs to be 2-pass. We first parse the file and secondly solve “forward assumptions”.

The code generator uses the repository to generate a RTL (Real Time Linker) file. The RTL file is sent to the VM that will link together the final binary module that we execute.

All in all it is a bit of work, but it is not that complicated once you get started. The key is that we need to be systematic as we will have parsing and code generator for each statement – which is why I want to use C++ because we take advantage of object orientation and let each statement be a C++ class that sustain parsing, repository management, code generation and in general everything for that statement. Using C++ this way also give me a single file for “if” etc making it easy to track and maintain. It creates more code, but it makes a lot of sence as the code get readable and easy to maintain.

Plain Roadmap

I Introduced the Plain concept 28th January, we are now 2 months into the making and I start seeing the end of the draft and need to consolidated a specification. I like where I am heading with Plain as it has grown from an experimental idea into something that I look forward to use myself. But, I have a big load of C & C++ coding before we get there.

Plain VM is started and is being written in C. I initially had plans to manage a minimum on STM32F030F4 with only 16Kb Flash – I am not sure that is realistic. I probably CAN get a minimalistic version to run on this device, but lets see – I have to weight in how much work it will be.

Plain Assembler will be written in C++ running as command line on Windows and Linux. The same with the command line utilities. The only dependency will be a library I made some time ago that is dedicated for embedded C++ stuff.

Plain – Functions

Functions in Plain are similar to functions in any language with a few important differences. A function in Plain will return an event with parameters, meaning we return a different set of parameters depending on what even we raise.

The second difference is that we let a function call be an implicit state-engine where we override optional or mandatory event with an “On” statement.

The third difference is that we allow a function call to act like a control statement by merging the body between the call and the first On into the function. This allows us to create new control statements.

The fourth difference is that I want to introduce named parameters.

And we need a way to make a function accessible from expressions.

use System
Func Parallel(uint32 Timeout)
            Timer(Timeout)
                        ExecuteBody
                        While ThreadsRunning()
                                   Sleep(10)
                        End
                        Raise Synchronize()
            On Timeout()
                        Raise Parallel.Timeout()
            End
On Timeout()
On Synchronize() Mandatory
End

Parallel ( Timeout=10000 )
            for x=1 to 20
                        spawn Math[x] transaction arr[x]
                                   arr[x] = Compute(x)
                                   state (Compute)
                                   on Error(..)
                                               // todo
                                   end
                        update
            end
On Timeout()
            //
On Synchronize()
            //
End

This example create a function Parallel that use experimental Syntax “ExecuteBody” to “call” the embedded, main body. After that we loop checking if threads are running – again using experimental RTOS functions. The example use a different function Timer that also act as a control statement itself. I could have used “Parallel(10000)”, but chose to write “Parallel(Timeout=10000)” since the parameter name add readability.

I mentioned “named parameters” – we sometime have functions with many parameters that can be given a default value in declaration. The classic solution is that if you want to override default parameters you start from left to right leaving out those on the far right side – I want to introduce is an option to do this by using an embedded assign to the parameters name.

func foo(uint32 something=10, uint32 somethingelse=20, uint32 mypar=30)
...
end

foo(mypar=40)

In this example the assembler will create a call to foo with 10,20,40 as parameters as we use the name of the 3rd parameter to specify only this. We can leave parameter 1 & 2 out because they have a default value – if they did not the assembler must give an error – missing parameter.

As to making a function accessible from inside an expression I suggest using either “Raise Continue” or “Return” – with one parameter. I am considering syntax like “x,y = foo()” where we Return multiple parameters – but, let us wait a bit with that one.

func foo(uint32 x)
            raise continue(x)
Event continue(uint32 x)
end

uint32 xx = foo(2)

We still have loose ends here, but I finally start to see syntax that I feel solve the Parallelism riddle and add something to Plain. The actual functions Parallel and Timer will be C functions – we will need to include a library of System functions anyway. At the end I also need to review if this actually serve the main objectives of Plain – ideas are ideas – they do not always stand their ground.

Plain – Parallelism Part 3

I must admit that I find it hard to create syntax supporting parallelism that I like and does what I want. I have looked into other languages for ideas, but the solutions are either too implicit or to manual. I insist on having a syntax that force us to write code in a way that automatically will solve the technical issues involved – and yet provide us with an option to manually control things if we need to – and I insist on code being readable.

My previous example uses “Spawn” to mark a statement or block that we execute in background. I used this on transaction, but we could in theory apply that as a prefix/postfix to any statement to create a background process. I need the background process because I need the logic that control and respond to a remote function Call that is not blocking.

for x=1 to 20
            spawn transaction arr[x]
                        arr[x] = Compute(x)
                        state (Compute)
                        on Error(..)
                                   // todo
                        end
            update
end

If I limit this to transaction I also force the usage of a mechanism that will sort out the multi-threading issues and using spawn as a prefix (or postfix maybe) to transaction avoid that we need to create a new control mechanism.

The challenge here is that I will be allowing 20 background processes while I continue executing the foreground process – so we will have 21 VM’s active with a bit of code. At some point we might need to collect those process and wait until they are all completed as well as respond to error situations.

Parallel( timeout=10000)
            for x=1 to 20
                        spawn Math[x] transaction arr[x]
                                    arr[x] = Compute(x)
                                    state (Compute)
                                    on Error(..)
                                               // todo
                                    end
                        update
            end
On Timeout()
            //
On Synchronize
            //
End

My first proposal was Parallel..end. End will not work so I replace it with “Synchronize”. – just playing around with ideas here – but using our new State mechanism might be an idea except that “State” is already used for a purpose. I can however use implicit state and allow Parallel to be a function where we allow the main code block to be embedded inside a function. I will need added syntax to functions, but this would allow us to treat timeout and synchronize as events + give us a powerfully new mechanism to actually create new control structures in Plain itself.

Plain – State Engine Part 2

Introducing “State..On” syntax to catch events makes a lot of sense. State will wait until one of the listed events happens before it process that event and continue.

Call MyFunction1(..)
Call MyFunction2(...)

State MyState1(MyFunction2)
On Error(...)
            // 
On Timeout(...)
            //
End

 This example will test for Error, Timeout and Continue. Continue is implicit if it don’t have parameters to avoid that we need to code an empty block. State will wait until one of these three events are raised.

In the example above I only respond to events from MyFunction2 and events from MyFunction1 will be ignored. Events have a name and parameter list that is a signature. If this signature is the same for several functions we can collect events.

Call MyFunction1(..)
Call MyFunction2(...)

State MyState1(MyFunction1,MyFunction2)
On MyFunction1.Error(...)
            // 
On MyFunction2.Error(...)
            // 
On Timeout(...)
            //
End

In this example I respond to events from both MyFunction1 and MyFunction2. Error are processed separate, but I use the same On for Timeout. I need to think about this event collection mechanism because it also open for an error where we collect by accident.

Assuming that one of the functions have a mandatory event we should still be able to verify that this is implemented. The assembler only need to generate some kind of todo list during assembling that either is cleared or generate an error as we reach end of the module.

We already have a call instruction with a event table so it’s no big deal implementing a new instruction “State” with the same. For now I need to let this idea mature a bit and see if it hold ground.

A still have a few loose ends:

  • I sound a bit inconsistent to use “Event” to catch some events and State..On to catch others.
  • I probably need a “default” event to Catch unexpected events.
  • I need a mechanism to Catch and Clear any event whatsoever and rules about how unprocessed events behave – I can’t have a Queue that keeps growing.
  • Other Things?

to be continued in part 3

Plain – State Engine Part 1

Don’t worry if some of the stuff in here does your head in – it’s doing my head in as well. At present Plain is no more than a collection of ideas with a lot of loose ends that we hopefully will manage to bring together.

We do a lot of multi-threading in Plain – we do so through distributed processing, parallelism and events. This is one of reasons I want the syntax and the assembler to deal with this – as a Plain developer I want to focus on what we do without having to worry about the details or if I get things like multi-threading wrong. My objective is that we should use C/C++ for the complex modules and hardware integration while we use Plain for system wide Logic. And I want programming to be simple so we can get more done with less resources.

We do however have one loose end – Events. The events returning from a call is not multi-threading, but event callback’s from C code will be. This is technically the same challenge we face in Parallelism – if we control 20 operations it also means we are waiting on 20 events while we continue with something else or just sit idle waiting.

Moving on a bit I also have an issue with the On statement. In it’s current form it is attached to Call – But, what if I want to do a lot of operations and just collect events & process them later? We often talk about Parallelism as the same operations in parallel, but with remote function calls we could actually start a call, start the next etc and decide that now is the time to wait for everything we have started to finish. To do so I need a mechanism that is not bound to the Call instruction.

Letting On be an instruction and introducing an Event queue will almost fix this – I am not to happy with the event queue, but as we send parallel operations out we actually need a mechanism in the VM to collect events and queue them.

As for Syntax we have used On & Event – I intended for Event to be the declaration and On to be the catching – but for C code we have used Event for the implicit catching as well. I need to tidy up my syntax and be more consistent.

I also have the Mandatory event catching that becomes a challenge if we detach On from Call – but I am sure we can solve this somehow.

use System
Module MyModule

            Event CModule SomeEvent()
                        println ("I got an event from C")
            End

End

This is how I planned to bind Plain code to C code. The idea was that RTL should look for a declaration of CModule.SomeEvent with no parameters and forward any call to this into Plain code. This will work, but it seems inconsistent with the use of  a separate On statement.

use System
Module MyModule

            Event CModule.SomeEvent()
                        println ("I got an event from C")
            End

            Call MyRemoteFunc()

            println ("Called MyRemoteFunc")

            On MyRemoteFunc.Error()
                        println("Hello from MyRemoteFunc")
            End
End

The “Event” declare a piece of code that can be called from C anytime – the On test if it exist an event and if it does we process it – top down. The challenge here is however that we might test for MyRemoteFunc events to early – if the event is raised after we execute On we will not catch it – so we need to introduce a state mechanism that wait for events.

use System

Module MyModule

            Event CModule.SomeEvent()
                        println ("I got an event from C")
            End

            Call MyRemoteFunc()

            println ("Called MyRemoteFunc")

            State ...
            On MyRemoteFunc.Error()
                        println("Hello from MyRemoteFunc")
            End
End

We did earlier have a Call..On that I now replace with a State..On. This will simply wait until one of the events in it’s list happens. I can still keep my Call..On syntax as an implicit State. One of my key objectives with Plain is “State-engine and event based logic” and introduction of a State instruction & event queue starts to sound like a big move in the correct direction.

 to be continued in part 2