Callbacks 01/09/2017

I have recently been returning to programming microcontrollers. Had an idea of creating a client for the SerialNet to STM32F4 microcontrollers and immediately got side-tracked into the issue of callbacks in C++.

In C++11 and later we have std::function. It works very well in normal environments. You can throw a bunch of different callable types at it and it allows you to call them uniformly. It does have some drawbacks though. For microcontrollers the most grave one is the need for heap allocation. When you assign e.g. a function object that can be arbitrarily large this is a neccessity. But is does make it unsuitable for many MCU:s. Other issues are using virtual dispatch which forces us to have vtables and std::function can be a bit on the large side. (e.g. gcc uses 24 bytes on 64 bit architectures.)

Coming from MCU and C programming, a traditional way to implement callbacks are to use normal function pointers. You store a pointer to a free function and later call it in some other context. This works well in C style procedural programs.

It is common to supply a void* pointer as first argument to distinguish a data object to operate on in these callbacks. For example, interrupt service routines can be thought of a callbacks. The STM32 MCU family can have 5-10 USART hardware devices on one chip. Each of these have one ISR being called.

Using OO techiques one might want to write one class called 'UsartDriver' implementing a driver and instantiate one object for each hardware module. Assume one member function called 'UsartDriver::isr()' is supposed to be called during IRQ calls. In practice that means each ISR should call the same member function but use a different object in the call. It boils down to traditional function callbacks needs an additional pointer and it uses the the void* to point out the object to operate on.

I started to hack away on this and got a really neat solution usable for microcontrollers. The details and code are at github. Go to the github repository to continue reading.

 

SerialNet utveckling

Uppdatering AkazaNet (SerialNet) 28/07/2017

Lång tid har passerat sedan sista inlägget men dags nu.

Har ägnat en del av den lediga tiden till att fortsätta med SerialNet. Några rent praktiska åtgärder som nya hyllor och fram med gamla datorer gör att arbetsplatsen börjar få drag av elektroniklaboratorium. Speciellt efter vårens instats med att få bra stöd för arduino/raspberry-pi baserat arbete.

SerialNet recap: Gör att man kan köra TCP/IP över delade serielänkar så som RS 485 eller open-collector kopplade serieportar. Det öppnar för mer intelligent kommunikation trots att man bara har 2 trådar för kommunikation och att noderna enbart har en serieport. (Tänk microkontroillers, arduinos, etc). Det finns lösningar att även kombinera strömförsörjning där ute så behövs kabeln ändå, så varför inte kommunicera över den? Annars är en 4-tråds RS485 delad buss + strömförsörjning ett rätt billigt alternativ till ethernet med alla dess switchar och kontakter.

Ett av mina testfall sedan tidigare är en ssh inloggning från en dator till en annan så det fungerar fortfarande. Det visar tydligt att TCP/IP går att få över.

Vad har hänt sedan senast? Några större förändringar:

  • TUN/TAP stöds idag native. Så man kan starta applikationen och den ser till att koppla in sig på TCP/IP stacken själv. Inget mer extra pyssel med verktyg som socat el. dyl. Efter start kan man med 'ip' och 'route' sätta sina parametrar på det nya interfacet.
  • Automatkonfiguration av klientadresser. Liknande DHCP men begränsat. En klient som inte har en statisk adress får nu en dynamisk tilldelad. (Detta är fortfarande kraftig alfa, men första klienten får sin adress).
  • Protokollet skiljer nu på 3 olika typer  av datatrafik, tap, tun, raw. Det ger möjlighet att samtidigt ha ett TCP/IP subnät över bussen, samtidigt som olika noder har elaberade raw kanaler där man passar data fram och tillbaka. 
  • Råa kanaler med data mellan noder via pty:s. När man startar serialnet och sätter upp råa kanaler kan den skapa en 'pty'. Det är samma typ av accesspunkt som t.ex. serieportar använder under Linux. Så efter start av Serialnet kan ett annat program anpassat för serieportar öppna en av dessa ptys och arbeta mot den på samma sätt som en serieport. Skillnaden är att Serialnet tar hand om hanteringen av den gemensamma bussen. Kanalen upplevs som en privat kanal mellan 2 olika pty:s på 2 olika noder.

Fått gräva i rätt obsyra delar av POSIX/Linux för pty/tap. Här är man glad att C++ är så nära besläkat med C och att det går att accessa OS på så låg nivå. T.ex. Java med dess JVM hade inte varit roligt att komma åt funktioner för t.ex. pty:s eller ändra ägaren till ett tap interface.

Just stödet för pty:s känns rätt viktigt när man arbetar mycket med microkontrollers. Det finns gott om programvara som kör på en liten enhet och sedan presenterar data över en serieport. På andra sidan sitter ofta ett mottagarprogram som ansluter till serieporten. Med detta kan man lätt återanvända mottagaren men nu köra över en gemensam buss istället.

 Så vad är kommande punkter?

  • Som vanligt, stabilisering, dokumentation testning sker löpande. Användbarheten och dukumentation av pty:s behöver förbättras. Dynamisk allokering av adresser har luckor kvar att fyllas.
  • Finns idag många som kör Arduino. En trevlig sak vore en klient som ett bibliotek för Arduino. Den erbjuder en virtuell serieport mot arduinokoden och kopplar sig mot masterns klient. På den sidan får man då automatiskt upp en pty på mastersidan att prata med. Borde göra det lättare för prototypbygge kring nätverket, Motsvarande drivare för STM32 processorer skulle vara intressant.
  • Nätverksstödet börjar kännas rätt så bra. Har få problem med det idag. Vill dock kunna starta som demon under boot. Ska bara fungera är en trevlig målbild. Annars är IPv6 önkvärt framöver.

Koden hittar man som vanligt på github. Den släpps under GPLv3 så de flesta kan använda den för att prova ut, hobbyprojekt etc. Vill man göra något där licensen är ett problem så kan en kommersiell licensiering diskuteras.

Länk till koden.

 

 

Tillståndsmaskiner 20/11/2016

I samband med arbete på masterdelen av SerialNet behövde jag åter igen ta fram mjukvara som hanterar sitt tillstånd utifrån serier av inkommande event. En klassisk lösning för detta är tillstådsmaskiner. De har varit en stapelvara inom elektronik och programmering i många år. De har välkända för och nackdelar.

Några exempel är:

  • Välkänd modell för att koppla isär programflödet från lagrade state. (icke blockerande)
  • Bra på att hantera kod som har många naturliga flöden istället för ett huvudflöde.
  • Events är och lätta att serialisera för att passa mellan processer och trådar. Lätt att dela upp programmet.

Några välkända nackdelar:

  • Saknas naturligt stöd i C/C++. Snuttifiering av kod. Man hoppar runt väldigt mycket.
  • De ökar i kompexitet snabbt med storlek. Antalet kopplingar ökar O(events * tillstånd)
  • Ofta kan modellen upplevas som 'trång'. Det blir många tillstånd för lite funktionalitet.

De fungerar ofta bra för maskingenererad kod. I det läget ser utvecklaren de grafiska diagrammen och koden automatgenereras. Tyvärr är den typen av verktyg sällan billiga/lämpade för mindre prototypprojekt där koden ändras ofta. Jag har själv använt dom rätt så flitigt då de ofta kan hjälpa till att undvika andra problem. Har tidigare tagit fram ett ramverk för dessa för handskriven kod baserat på idén "ett state är en funktion". Ursprungliga idén kommer från Miro Samek.

Trådar vs Events.
Några inledande idéer kring vad de är bra för. En av de grundläggande frågorna som delar upp utvecklare i grupper är 'trådar' vs 'events'. Ofta finns det flera parallella aktiviteter som pågår i ett program. Problemdomänen brukar vanligtvis ha rätt mycket oberoende uppgifter som man vill lösa. Samtidigt så är språken C/C++ i grunden sekvensiella till sin natur, då de modellerar en exekveringsenhet som utför det instruktionsflöde som programmet har. De primitiver språket har i form av loopar och funktioner är ett sätt att gruppera funktionalitet. Men språket är i grunden fortfarande seriellt.
Trådar är den primitiv som tillåter modellering av samtidig exekvering. Varje tråd får var sin uppsättning med register, programräknare och en egen stack. Sedan ser det ut som om varje tråd oberoende utför sina uppgifter. Så förespråkare av trådar för modellering av domänspecifik parallelism tycker ofta att en tråd ska utföra varje domänspecifik oberoende uppgift.

Sedan finns det andra lägret som även tittar på den extra komplexitet som trådar innebär. Med trådar behövs synkronisering med t.ex. mutexes, atomic etc. Dessa är dyra för hårdvaran att utföra samt har en del designproblem som gör det svårt att garantera att inte 'deadlocks' inträffar.
I grund och botten är en tråd en abstraktion över en exekveringsenhet, inte en abstraktion uppe i problemdomänen. Används de för finmaskigt, resulterar detta i rätt kraftiga prestandaproblem med ökat tryck på cachar och nödvändingheten att dela kod/data mellan olika exekveringsenheter.

Själv lutar jag åt eventhållet på lägre nivåer i programmet. Trådning tar man till när man har lite större mängd kod som behöver isoleras från annan kod, eller har latencykrav.

Så för en modul eller del av ett program brukar jag grovt dela in koden i 'lågnivådelar' som enbart  är rak kod utan blockerande anrop och utan större vägval i koden. Väldigt 'imperativt' eller 'peka med hela handen' typ av kod.
Nästa nivå upp där sker mycket av den tidsbaserade logiken. Här passar tillståndsmaskiner bra. Genom att de inte blockerar tråden, kan flera ligga parallelt och sköta den delen av problemdomänen se är skapade för. De är eventbaserade. Det ger möjligheten att lättare flytta runt dom utan att det får följdverkningar på övriga koden. Överst ligger main eller en tråd-main och driver en scheduler som distribuerar körtiden för tråden. Detta är enda stället som man sover i någon större utsträckning.

Ovanstående visar en uppdelning utifrån 'callstack' perspektiv med main överst och anrop nedåt. Rent lagermässigt och med logiska beroenden i koden, ser det annorlunda ut. Schedulern är en lågnivåkomponent och interfaceklasser bildar botten i denna uppdelning.

Åter till tillståndsmaskinerna. Klassiska platta tillståndsmaskiner blir snabbt för krångliga. Det finns ett antal förbättringar som ökar deras användbarhet:

  • Entry/exit events. Vid varje tillståndsbyte genereras dessa. De tillåter enklare resurshantering inom states via RAII.
  • Interna eventköer. Har man dessa tillåts man att posta events till sin egen maskin. Då kan man lättare samla kod under extra event handlers. Köer undviker också 'reentrancyproblem' när de skickar event till varandra. Ser man sedan till att postfunktionen är trådsäker är det en utmärkt trådgräns.
  • Hierarkiska tillståndsmaskiner. Tillåter att states kan existera i varandra och att olika states kan bevaka olika events.

Med dessa förbättringar kan man lösa meningsfulla problem och ha en översiktlig kodbas. Hierarkiska tillståndsmaskiner beskrevs först av Harel på 80 talet och han kallade dem 'StateCharts'. Senare i UML så kallas de tillståndsmaskiner men är definerade som hierarkiska med entry/exit events.

Idén med Statecharts är att ett tillstånd (kallat bastillstånd) kan ha ett antal undertillstånd. När ett undertillstånd är aktivt och ett event kommer in, så kollar man först efter en eventhanterare i undertillståndet. Finns inte det, så får bastillståndet försöka hantera det. Det kan finnas flera undertillstånd till ett bastillstånd och man kan hoppa runt bland dessa. Detta fungerar äver rekursivt vidare med godtyckligt djup.
Stora fördelen är att event som alltid kan komma och som ska behandlas lika kan hanteras i ett bastillstånd och då kan undertillstånden begränsas till de event som rör dem.

Nog om teorin bakom StateCharts. Med dessa funktioner är de rätt användbara. Så frågan är,  hur beskriver vi dom i C++ kod? Vilka primitiver i C++ passar här och på vilket sätt?

Tillstånd är i grunden data. De ligger över tid och fungerar som en behållare av funktionalitet som vi vill använda när tillståndet är aktivt. Till det kommer extra data som håller koll på vilket tillstånd är aktivt.
Event är egentligen en händelse, men tillsammans med själva händelsen följer ofta med en del data. Själva hanteringen av Events (event handlers) är dock mer funktionslikt. Så när ett event skickas in behövs kod för att utvärdera vad ska hända för varje tillstånd.
Tittar vi på en klass i C++ är detta en samling data samt funktioner. Den har också en kontruktor/destruktor.
Det är klart lockande att låta konstruktor/destruktor modellera entry / exit funktioner.

Eventhanterare är naturliga funktioner. Hur vill vi göra detta? Jag använder en klass för Events. Sedan behöver denna innehålla något sätt att skilja på olika typer av events. Jag kommer använda en 'enum' för att enumerera olika typer. Naturlig kan tyckas att göra subklasser av en basklass Event. Detta har dock provats förr. Det introducerar prestandaproblem då det tvingar fram dynamisk allokering av Events samt dynamic casts. Med intern eventkö är heapallokering svår att undvika.
Grundproblemet är att man får 'double dispatch' på både state och eventtyp. C++ har bara 'single dispach' med
virtuella funktioner. Det de brukar landa i är en 'if / else' kratta med 'dynamic_cast<>' på eventtyperna. Detta är uruselt i C++ ur ett prestandaperspektiv. Planen är att detta ska fungera i embedded så väljer enum istället.

Så med eventtyper i form av enums vi skulle behöva koppla denna enum till olika medlemsfunktioner. Inte helt lätt
att få till automatiskt. Jag väljer istället att varje state får en 'event' funktion, sedan får användaren frihet att titta på eventobjektet och välja metod för dispatch till olika eventhanterare. En enkel 'switch' fungerar ofta bra. I eventet kan man låta en smart_ptr följa med om man absolut vill ha olika klasser för olika eventtyper.

Så, hur ska understate och basstate modelleras?
Flera har försökt med arv. Detta är dock fel. Räcker med att titta på livstid för objektet. Ett basstate har en strikt större livstid än alla sina understates. I arv är livstiden samma för basklass som för subklass.

En variant är också att substate instansieras som medlemmar i basstate. I detta läget kommer livstiden för substate i alla fall rymmas inom basstate. Men vi behöver forfarande kunna hoppa runt mellan substates inom ett basstate. Det innebär construction/destruction. Så rena medlemmar funkar inte, ev. någon form av pekare med new/delete. Kan tänka oss en union av substates inom basstate och sedan explicita anrop till placement new/delete. Detta kan fungera. union ser till att utrymmet blir rätt till största objektet. Sedan placement new / delete. Nu är unions lite röriga. Det är nog en framkomlig väg, men jag har valt en annan.

Lagring av aktiva states kan bättre liknas vid en programstack. För varje funktionsanrop läggs en ny stacknivå till ovanpå. Alla överliggande stacknivåer måste bort innan en viss stacknivå kan tas bort. Så en stack med de för stunden aktiva tillstånden fungerar bra. Med detta blir eventhantering rättfram. Anropa event() på varje state från toppen till botten tills en signallerar att eventet har hanterats.

Konsekvenser:
Så vi har följande:

  • Event : Små objekt av en gemensam typ med en enum som anger eventtyp. Propageras genom kopiering genom eventköer.
  • States: Skapas från klasser, konstruktor/destruktor ger entry/exit events. event levereras till en event() funktion.
  • Vi har en stack med de för stunden aktiva states.
  • En huvudklass 'StateChart' där vi postar events och som äger alla states.

Här kan man notera att för en viss nivå, är enbart ett enda state aktivt vid varje tillfälle. Det destrureras innan det nya statet konstrueras. Det öppnar en optimeringsmöjlighet. Vi vill undvika dynamisk minnesallokering varje gång
vi byter state. Det jag gör är att reservera ett minnesblock för varje nivå av samma storlek som det största statet på den nivån (ung. som union gör). Sedan vid övergångar andvänds 'placement new / delete' för att skapa objekt. Det har ett par fördelar:

  • Prestanda : en enkel övergång innebär ett anrop till en destruktor och en konstruktor. Vi rör inte heapen.
  • Säkerhet : Ingen risk för 'out of memory'. I miljöer som inte tål heapallokering efter startup är detta fortfarande möjligt.

Med denna optimering borde jag kunna få prestanda som liknar den jag hade i min tidigare funktionspekarbaserade approach. Tittar man på C++ metod för att bygga objekt så är minnesallokering och sedan konstruktörer. Med allokeringen är det bara ett funktionsanrop kvar. En fördel med att använda en klass för states är livstidshantering. Vi kan lägga till egna data och objekt som medlemmar till klassen. De konstrueras och destrueras tillsammans med klassen. Så C++:s idiom med RAII fungerar väldigt bra här.

Ett basstate är ansvarigt för en operation och har understate som utför den. Supportdata kan då skapas i t.ex.
basstate och så städas de upp automatiskt när det är klart. Med stöd att underklasser kan få tillgång till basstate via pekare/referens så kan de operera på data där. Det kan liknas med att passa en pekare/referens till en funktion vid funktionsanrop.
En skillnad mot min tidigare implementation med funktionspekare så behöver inte ramverket generera events för entry/exit. Så ramverket behöver aldrig röra själva eventen. Så det är valfritt om användaren vill ha en enum i sin eventklass.

Rent praktiskt har jag implementerat detta i SerialNet koden och ligger på github. Så vill man titta närmare finns koden där. Funderar på att ta ut den till ett eget repository då den är allmänt användbar. Är idag skrivet i C++14. Tror däremot de flesta koncept skulle fungera bra i C++98. Behöver då byta ut en del 'using' mot 'typedef' och 'auto' mot kontreta typer. Det som kan ställa till det är att jag kapslar in 'new' i funktionsobjekt för att få type-erasure. Använder lamdas och std::function där, men det borde gå att bygga explicita klasser som gör samma sak.

 

Uppdatering SerialNet 06/11/2016

Har gått ett antal veckor nu och det har gått framåt med SerialNet projektet. Bakgrunden är idén att en busskopplad 2-tråds serielänk som ger TCP/IP koppling är önkvärd och kan vara en bra lösning i vissa situationer. Se tidigare poster för detaljerna.
Störst nytta med denna länk gäller sammankoppling av små system, typiskt Embedded Linux eller MCU baserade system. Med de senaste årens framsteg inom Embedded Linux är det nog en hyfsad andel som är tillräckligt billiga för att detta ska spela roll. Men även MCUs kan dra nytta av TCP/IP uppkoppling billigt, främst för att underlätta integration uppåt.

Så vad har hänt? Några highlights:

  • Första testsystem med RS232 signaler, kopplade som en 'wired or' gemensam buss uppsatt tillsammans med USB<->serie adaptrar.
  • Skapat en Linux-utility i C++14 som kopplar samman ett TAP interface från Linux TCP/IP stack till serieporten där USB<->serieadaptern sitter. Innehåller allt stöd för hantering av serieportar, addresshantering och möjlighet att starta en master som organiserar trafiken.
  • Adaptiv hantering av vem som får skicka. Aktiva (well behaved) klienter får prioritet framför enheter som inte snabbt returnerar token.
  • Första test där en ssh session skedde från 1 dator till en annan över serielinan.
  • Lyckats kompilera utility till ARMv7 (RaspberryPi2) och gjort inloggning till RaspberryPi via ssh.
  • Publicerat koden till serialnet på github under GPLv3 licens. Tanken är att låta folk prova ut, ge feedback och utnyttja serialnet i open source sammanhang. Vill man hacka vidare själv går det att klona repot och fortsätta utvecklingen under GPLv3 licensen. Jag har fortfarande full copyright på källkoden så vill man använda detta i en kommersiell miljö så går det att ordna.
  • Första test med 3 enheter. (Stationär dator / laptop / RaspberryPI2) Gick att parallellt starta ssh sessioner från stationär dator till laptop och RaspberryPI:n. I samband med detta var det en förbättrad kabel som tydligt visar att det är 2 trådar som används.
  • Tittat lite djupare på olika scenarios där detta kan vara användbart. Destillerat fram 3-4 scenarios som verkar vara bra för denna kommunikation. Börjat på presentationsmaterial kring dessa.

Det som ligger närmast i 'roadmap':

  • Behöver kunna visa upp ett demo. Trol. 3 enheter, en enhet med Wifiaccess och i denna sker en level-2 bryggning mellan Wifi och serialnet enheten. Sedan delas IP adresser ut via DHCP-servern i Wifiroutern till alla enheter.
  • Testa av riktig RS485. Finns HW, borde fungera, men ska testas.
  • Formalisera byggprocessen. Vore trevligt att kunna installera serialnet genom 'apt-get install ...'

Sedan finns det några lite mer långsiktiga mål:

  • Port till MCUs. (Trol. C implementation, client only)
  • Dynamisk addressallokering av lokala adressen. Automatisk konfiguration vid anslutning/urkoppling. (IP adress kan hanteras av DHCP)
  • HW adaptrar som tillåter signaler + matning över samma ledare.

Portning till MCU

Detta känns som en viktig del i projektet. Det är till stor del MCU:s som kan dra nytta av billig installation av kommunikation. Det finns ett behov att enkelt kunna ge TCP/IP koppling till små billiga enheter.
Målbilden är t.ex. STM32 MCU med FreeRTOS + bundlad TCP server. Kopplat till detta är en enkel serieportsdrivrutin samt serialnet som kopplar ihop serieporten till TCP/IP stacken. För demonstration bör t.ex. COAP protokollet kunna passa. Det gör att man kan exponera ett REST liknande API till sensorer/aktuatorer på MCU:n som sedan kan accessas via t.ex. Firefox.
Kostnadsmässigt är dessa enheter billiga, ofta mindre än $1. I det ljuset är anslutning en relativt stor del av kostnaden. Samtidigt har dessa MCU:s mycket minne jämfört med förr.
Absolut enklaste inkoppling mellan MCU:s kan vara en enkel kopparledare på ett kretskort. Internt kopplas GPIO pinnen för TX som 'open drain' och en MCU aktiverar pull-up resistor. Med denna setup kan flera MCU:s på samma kort fullt ut delta i TCP/IP kommunikation.

Dynamisk adressallokering

En viktigt egenskap i slutändan är enkelhet i installation samt konfiguration. Det ska räcka att koppla in en enhet till kabeln för att den ska upptäckas på nätet, registreras och rätt konfiguration ska sättas. Det mesta av detta sker på högre nivåer. Det som rör serialnet är upptäckt och lokal adressallokering. IP adressen hanteras via DHCP när väl ethernetpaketen kan börja skickas.

Några ord om autokonfigureringen. Detta är den enda gång hittills då timing mellan paket spelar roll i normal kommunikation. En enhet som ansluts har ingen address och har ingen anledning att bli anropad av mastern. Dessutom kan flera enheter ligga på bussen och vänta på address (t.ex. efter power-on av hela bussen) Den lösning som är vald är att ha ett paket för adressallokering med en relativt lång timeout efter frågan. Sedan används random backoff och 'collision-detect' för att en enhet i taget ska få sin address. Varje enhet behöver någon form av unik identifierare för att detta ska fungera. Det är dock fullt lösbart.

Sedan behövs någon form av hantering av addressens livstid. När väl addressen är tilldelad är det relativt lätt att få till ett protokoll för att kontrollera hur länge adressen är giltig. Med mastern som har kontroll på alla adresserna så får man automatiskt en koll på vilka enheter som lever och som har varit borta. Så mastern får gratis en 'heartbeat' tjänst via adresshanteringen och tokenskickning.

HW adaptrar med power supply

Bör finnas en hel del installationer där ett antal små enheter sitter inom 10 meter från varandra. Längre än så så börjar kabelkostnaden dra iväg och trådlöst börjar bli den naturliga lösningen. Hybrider kommer troligtvis bli vanliga (lokala grupper kopplas med kabel och trådlöst för de längre avstånden mellan grupper.) Notera för hybrider, med bryggkoppling av nätverksinterface upplevs hela nätet som ett ethernetnätverk så överliggande lager behöver inte se övergångarna mellan medier, annat än i fördröjningar i paketen.

Det kabeln tillför är att en grupp kan dela på infrastruktur. En enhet har kraftförsörjning, ev. backupbatteri och sedan skickas matning och kommunikation ut lokalt. Om en microkontroller kostar $1 så är man inte alltid intresserad av en 230V adapter till var och en.
Ska man nu dedikera bussen till matning så bör den klara det bra. Skissar på adaptrar som kopplar till en buss med 8V-20V systemspänning. Tillåter att hyfsad effekt förs över utan att kabeln ökar i storlek. Varje enhet har en 'step-down' spänningskonverter som tar ner spänningen till 5V/3.3V eller vad som behövs. Med detta kan man vara rätt så frikostig med hur kraften genereras.
T. ex. direkt inkoppling av 12V accumulatorer eller standard 19V laptopladdare. En adapter kan koppla till bussen på ena sidan och ge GND, serial RX/TX samt +3.3V på andra. Med detta kan det vara lätt att integrera mot existerade konstruktioner. Jag kan tänka mig ett par 3 olika sätt att utforma bussen medan gränsnittet mot MCUn är samma. T.ex. RS485 + kraft, open drain serial eller Powerline communication över kraftkabeln. Det hela kommer ned till kostnad i det enskilda fallet.

En viktigt egenskap är mekanisk inkoppling. Helst ska man kunna montera på en enhet på en existerande kabel utan att behöva klippa den. Har tittat på IDC kontakter (insulation dispacement contacts) som  ett alternativ men inte hittat något klockrent än. Kan dock vänta med att lösa detta för stunden.

Sammanfattning

Det går framåt, inga större hinder än (än tid). Jag tror fortfarande att detta kan göra nytta. Är det någon därute som kan se användningsområden och är intresserad av att komma vidare så hör gärna av er. Annars finns koden på Github att titta på.

 

Kod till TCP/IP över serielänkar. 16/10/2016

Jag har tidigare skrivit om mitt experiment med TCP/IP över en seriell buss. Har nu fått ihop något som i alla fall går att diskutera kring. Så är man intresserad så har jag laddat upp koden till Github. Så vill man kan man klona git-repot, bygga i en Linuxmiljö och provköra. Notera dock att viss hårdvara krävs.

För mer info, se github.

 

 

busstopologi

TCP/IP över Serielänkar 10/10/2016

Har den senaste tiden suttit och ägnat en del tid åt ett eget projekt. Huvudsakligen vill jag kunna använda en delad buss med seriegränsnitt för att kommunicera mellan olika enheter och använda TCP/IP i processen. Jag kom till en milstolpe nyligen där jag kunde använda ssh för att logga in på en annan dator över en seriebuss med RS232 signalnivåer. (eget hopkok.) Länken är en delad buss med en master, en uppsättning som bör fungera bra över RS485 nätverk.

Det finns 2 uppenbara frågor som jag tror dyker upp första gången man hör detta:

  • Varför? Vad är meningen? Trådade TCP/IP nätverk är redan ett löst problem.
  • Serielänkar? Det är 60 tals teknik. Vad är det för mening att hålla på med dessa idag?

Mitt motiv att sätta igång med detta kommer från observationer från Embedded och IoT världen. Det är lite oklart vad som skiljer dessa, men de kommer från olika bakgrund där embeddedvärlden har sina rötter i elektronikvärlden och har närmat sig mjukvara från lågnivåprogrammering, medan IoT kommer från server/cloudsidan och närmar sig via kommunikationsprotokoll.

I mötet mellan dessa kommer det uppstå nya frågor och utmaningar att lösa. Elektronikvärlden är väldigt driven av att minimera kostnader för hårdvara. Samtidigt sker utvecklingen inom cloudvärlden så snabbt det är ibland svårt att hitta fasta punkter som gäller över längre tid där.

Kraven på enhetlig addressering av enheter, end to end kryptering samt rika möjligheter att fråga enheterna vad de klarar av gör att TCP/IP kommer sakta men säkert ta sig ut till ändnoderna. Så det finns ett underliggande tryck på att göra enheterna mer självständiga och att de har gemensam adressering så centrala tjänster inte ska behöva ta till specialbehandling.
Även kryptering hela vägen ut till ändnoden är viktig. Transporten mellan blir mer och mer fragmenterad och sköts ofta av 3:de part. Med kryptering hela vägen ut blir designen av transportkedjan mycket mindre känslig och designen blir flexiblare. Dessa delar är redan lösta i internetvärlden. Väljer man TCP/IP som bas finns mängder av detta färdigt.

Så det finns anledning att ta internet hela vägen ut, men varför serielänkar? Måste finnas bättre sätt? Uppenbara alternativ är Wifi, Blåtand, ethernet, 3-5G eller fria radioband (868MHz).
Här kommer en vattendelare mot tidigare klassisk datorbaserad utveckling. IoT världen är mycket mer heterogen. Det finns plats för många lösningar. Tricket är att hårdvaran behöver anpassa sig till den fysiska verklighet där den befinner sig i, så länge man kan nå enhetlighet högre upp i stacken. Jag har här valt TCP/IP som den sammanstrålande punkten. På lägre nivåer behövs friheten att anpassa sig till fysisk verklighet. Idag i embeddedvärlden finns designfriheten, men man söker fortfarande att hitta enhetliga gränsnitt att visa upp uppåt.

En första skillnad man kan göra är mellan trådade och trådlösa länkar. Trådat har varit den klassiska lösningen, trådlöst den nya moderna som lovar enklare installation, mobilitet och en aura av att vara i framkant.
Väljer man trådlöst behöver man fortfarande hantera energiförsörjningen. Är dina enheter stora och kräver redan elanslutning, då funkar trådlöst bra. Man sparar den extra kabeln som annars kan behövas. Behövs mobiliteten, så är kabeln ivägen.

Däremot de scenarios där en mängd enheter installeras en gång, de ska sitta länge (10+ år) så batterier kan behöva bytas. De kan sitta otillgängligt så elförsörning är inte trivialt. De kan vara små så kraftelektronik (230V) blir en stor del av kostnaden. Dessutom kan de styra/reglera enheter som inte drar mycket ström, men tillräckligt för att batterier inte ska fungera. Det räcker med en liten skärm eller enkare motor som används ofta för att batterier kan behöva bytas årligen eller oftare.

Så behöver vi ändå dra en kabel för elförsörjning, då kan ett partvinnad extra par lätt följa med. Med denna kan man göra utvecklingen betydligt lättare och slippa vanliga radioproblem. Konkurrens om ethern, störningar, skärmande metallskåp, olika radioförhållanden vid olika årstider etc etc. Allt detta försvinner.

Så, det bör finnas nischer där kabel är motiverad. Men det är väl redan löst? Ethernet, kanske tillsammans med PoE (Power over ethernet) och man får samma effekt?
Kostnad är hindret. Ethernet har utvecklats till en kraftfull standard. Men allt fokus ligger på bättre prestanda medan smalbandig kommunikation till billig penning aldrig har varit i fokus. Ethernet idag är stjärnuppbyggt med switchar som en nödvändig byggsten. Med PoE drar prislappen iväg. Med stjärnnät blir det också gärna mer kabel än vad en busstopologi skulle ge.
Det jag siktar på är samma uppbyggnad som de gamla 10Mbit coaxsystemen, men med partvinnad tråd och lägre hastighet. För IoT finns massor med tillämpningar där att kunna prata är det viktiga, inte att prata fort.

Några exempel där detta kan passa:

  • Fastihetsautomation. Sensorer för luftkvalitet, temperatur, låsstyrning smarta hem.
  • Intelligenta energisystem. Solcellsinstallationer där enskilda paneler har kontrollers och enskilda batterier kontrolleras. Dessa enheter behöver kunna prata med varandra.
  • Laddinfrastruktur elbilar. Enskilda laddstolpar behöver kunna kommunicera med centralsystemet.

Eller varför inte:

  • Säkringarna i ett säkringsskåp kan informera om sin status. Elmätare på rad som bygger upp ett nät.
  • Ett modulärt system av microkontrollers på PCB som kan kopplas ihop av kund. Har dessa en standardiserad buss kan konfigureringen förenklas.

Gemensamt är att själva noderna är små och billiga. De är statiskt monterade. De behöver kommunicera, men inte stora mängder. Ev. är de svåra att komma åt för underhåll.
Fortfarande ska så klart konfiguration vara modern. Det ska räcka att koppla in enheterna så kan de sedan självkonfigureras eller slå upp sin konfiguration via onlineservrar.

Här hjälper teknikutveckligen oss på traven. Moderna mikrokontrollers som är billiga har trots det rätt mycket minne. Så det finns plats att införa t.ex. TCP/IP, kryptering och diverse applikationsprotokoll trots att mikrokontrollern är liten och billig. Med kabelbaserad energi fungerar också Linuxsystem med små fysiska dimensioner.

I det här läget blir en klassisk UART den minsta gemensamma nämnaren. Den ger möjlighet att läsa / skriva enskilda bytes. Så det enda vi behöver lägga till är det lågnivåprotokoll som binder samman existerande TCP/IP stackar med ett byte in/byte ut gränsnitt nedåt. Med detta på plats finns en stor flexibilitet att utforma hårdvaruinstallation, medan mjukvaran kan byggas upp av standardkomponenter ovanpå.

Men hur var det med den andra frågan. Detta måste väl finnas sedan 30 år tillbaka?
Det är inte nytt. Det finns som lösning is diverse tillämpningar. T.ex. går det att köpa automationboxar för industrin som skeppar TCP/IP över RS485 länkar. Dessa kostar dock 500+kr och har en formfaktor som inte passar.
Har inte hittat färdiga open sourcelösningar. För punkt till punkt finns T.ex SLIP eller PPP. Men har inte hittat något för busssystem.

Så målet är en protokollstack på låg nivå. Den enda kommunikationen nedåt är en byteström in/ut. Inga sidokanaler tillåtna (extra interruptlinor, eller breaksignaler). Endast timeout mellan paket kan användas som sidokanal, och helst sällan. Detta tillåter att man tunnlar byteströmmen vilket ökar flexibiliteten. Kommunikationen ska gå genom ett gemensamt medium med flera enheter kopplade till samma medium. Allt för att förenkla eventuell kabeldragning och installation. Idealt ska man kunna montera på en enhet med t.ex. en crimptång utan att behöva klippa kabeln till bussen.

Uppåt är gränssnittet ethernet frames. Det ska gå att koppla in detta på existerande TCP/IP stackar som redan finns på marknaden. Med detta borde man kunna öppna upp för nya system där modern mjukvara kan fungera tillsammans med traditonella installationer och med prispressade komponenter. Det borde kunna hjälpa till att lyfta traditionella embeddedsystem in i IoT världen.

Som sagt, prototyputveckling pågår. Fick upp en standard ssh session från en Linuxdator till en annan över en fysisk seriell buss nyligen. Det inkluderar kryptering/handskakning med val av algoritmer och sedan konsollaccess av fjärrdatorn. Allt medan en buss-master dirigerade vem som får sända paket.

Kommer ta upp utformningen av protokollet i kommande poster.

 

MQTT

Protokollet MQTT för IoT 14/02/2016

Tänkte gå lite djupare in på tekniska detaljer kring protokollet MQTT och dess användning i min power control applikation. Det är ett protkoll som fått mycket uppmärksamhet inom IoT (Internet of Things).

Kort om min applikation: Skriven i python och kör i Google App Engine (GAE). Godtycklig användare scannar en QR kod med telefonen och hamnar på en webbsida genererad av applikationen. Via URL:en vet applikationen vilket uttag som QR koden hör till. Användaren gör inställningar och klickar sedan på 'On' för att slå på uttaget.

Nu kommer det intressanta. När som helst, 24/7-365 måste applikationen kunna få fram ett meddelande till den lokala kontrollern som styr uttaget. Den är troligvis bakom brandväggar. Med modern uppbyggnad av webben går det på tvärs mot den normala riktningen för att öppna upp förbindelser. Enkla lösningen med 'poll' är väldigt dyr bandbreddsmässigt, speciellt om mobila bredband används så det är inte ett alternativ för mig. Här kommer MQTT till min räddning.

Det består av en central 'broker' som agerar server och ett antal klienter som ansluter. Modellen är väldigt lik modellen för chatprogram och protokoll som XMPP, ICQ eller Jabber. Klienten kopplar upp (MQTT bärs ofta direkt på TCP) och ansvarar för att hålla koppling levande. Sedan utför klienter 'subscribe' på ett antal valfria 'topics'. Andra klienter postar 'publish' på topics och brokern har till uppgift att skicka meddelanden till intresserade mottagare. Topics organiseras i ett träd och man kan välja att utföra subscribe med wildcards på ett helt delträd av topics. De liknar väldigt mycket hur absoluta sökvägar för filer är uppbyggda i filsystem.

I mitt fall innebär det dels en publik MQTT broker och dels klienter för de lokala noderna som har hand on uttagen. Sedan en klient för molnapplikationen. Med lite ordning och reda i hur topics sätts upp, kan all kommunikation lösas mellan lokala nätet och molnapplikationen via MQTT. Vi har en dubbelriktad förbindelse som ständigt är öppen utan att lasta nätet i onödan. Har nu testat detta och det fungerar alldeles utmärkt. Uppsatt system med lokal Raspberry Pi, uppkopplad med 3G modem. 12 timmar senare och kommandot att slå på uttaget gick fram direkt. Det fungerar som tänkt. Jag använder mosquitto broker och de CLI-kommandon som förljer med. Paho-MQTT klient för pythongränsnitt vilket har fungerat riktigt bra.

Tyvärr stödjer inte GAE MQTT direkt, men en enkel python webserver agerar brygga och forwarderar http anrop till MQTT brokern.

Lokal MQTT broker

Funderade vidare. Den lokala 'gateway' jag använder är en Raspberry Pi med en Razberry Z-wave controller. Det är ett av flera protokoll jag vill använda. Framtida alternativ är modbus/RS485 lösningar, tcp/ip inom lokala nätverket eller GPIO pinnar. I framtiden kan det finnas behov av lokal logik så att lokala gatewayen slår av brytare efter viss tid/förbrukning trots att internetförbindelse är borta. Den traditionella metoden här är att klumpa samman allt detta i en monolitisk C/C++/Python applikation och lösa det där. Men såg att detta kan snabbt bli rörigt.

Valde denna gång att ta MQTT spåret ett steg till. Utöver den globala brokern startar jag en lokal broker på min Raspberry Pi, enbart för intern kommunikation mellan program. Hela systemet är i stora drag eventbaserat och vår lokala broker bildar helt enkelt den eventbuss som fördelar events.

Finns flera fördelar:

  • Extremt enkelt att få ut loggning / debugga eventflöden. Starta en konsoll och utför subscribe på alla topics och både loggning + debug blir enkelt utan att röra normala koden.
  • Lätt att dela upp programmet i mindre komponenter. Har inte haft något behov av trådning än, utan UNIX filosofin fungerar med många småprogram som ökar isoleringen och underlättar vidare utveckling.
  • Bra utbyggbarhet. Med de hierarkiska topics så kan man lätt bygga ut systemet.

Så har hittills skelett för följande lokala program:

  • En server som lyssnar på globala och lokala MQTT brokers och passar intressanta meddelanden mellan dessa. I dagsläget behövs bara inkommande data men blir nog dubbelriktad när sensordata ska skickas upp.
  • En server som lyssnar på lokal broker och utför kommandon mot brytare via Telldus utrustning. Använder där 'tdtool' för att utföra kommandon.
  • En server för Razberry Z-wave kontroller. Lyssnar på lokal MQTT broker och styr brytare via Z-wave genom http anrop in i det REST baserade API som Razberry erbjuder.

Så, fungerar det? Ja. Är det överarbetat? En hel del kan tycka det. Men jag är övertygad om att det är en lösning som går att växa i. Speciellt enkelheten att logga och injektera meddelanden för test kommer att löna sig i längden. Som vanligt är det 'proof of concept' hitills så det är en bit kvar till att bli robust.

Generellt har MQTT varit en trevlig bekantskap. Speciellt med CLI-programmen 'mosqitto-pub' och 'mosquitto-sub' samt textbaserade protokoll har det varit riktigt lätt att komma framåt. Prestanda? Helt ok. Kanske 1s fördröjning från klick på webbsidan i mobilen till lampan slockar eller tänds. Helt ok för min del.

 

Intelligent kraft 07/02/2016

Var ett tag sedan senaste inlägget. Några ord om de senaste ämnet (byggsystem). Har blivit mer övertygad om att kombinationen Cmake och Ninja är rätt väg att gå för lite större embeddedsystem på MCUs. Var skeptisk till att Cmake var tillräckligt flexibelt vid länkning men sökning gav flera open source byggsystem. T.ex. stm32-cmake. Detta gäller både för Windows och Linux som host. Har man Windows tenderar komplicerade make-byggen bli extremt långsamma så ännu viktigare där att beräkna dependencygrafen separat från själva inkrementella bygget.

Besökte FOSDEM nyligen och där pratade de om FROSTED. Ett embedded OS för Cortex M3,M4 med Posix-gränssnitt. Klart lovande initiativ.

Nog om byggsystem och embedded. Har parallellt med mitt berotec uppdrag de senaste 3-4 månaderna grävt ner mig i en teknisk lösning som potentiellt kan öppna många spännande fortsättningar. Det är senaste idén från en längre tids undersökande av flera olika intressanta områden:

  • Stockholms startup scen. Det har nog undgått få att Stockholm idag är en av de hetare städerna för startups, speciellt inom Mjukvaror, IoT, webbaserade tjänster och andra snabbt rörliga områden.
  • Behov att sätta mig in i modern molnbaserad utveckling. Har länge dragit ett streck vid http och slutat undersöka. Men idag är hela web/moln utvecklingen så allmänn att viss allmän praktisk erfarenhet behövs för utvecklare. Har man ambitioner mot systemdesign måste man känna till dess egenheter på ett rätt djupt plan. Behövde helt enkelt sätta tänderna i utveckling mot molnet.
  • IoT: Detta buzzword som ett fåtal använde redan på 2000 talet inom universitetsvärlden (SICS här i Stockholm). Industrin pratate M2M, telemetri etc. Ser det själv (grovt generaliserat och delvis felaktigt) som 'The revenge of the embedded developer'. Embedded har delvis blivit hett. Tror dock att nuvarande drive snarast kommer från seversidan och att embedded är inblandat, mest beror på att verkligheten tränger sig på i datamodellerna. (Detaljer som batteridrift, strömförbrukning, access till internet sista km, enhetspris etc)
  • Elon Musk och hans visioner. En man som många har åsikter om. Han har själv många vitt skilda och på ytan galna åsikter. Men är det något han har lyckats med är det att leverera trots motstånd. För närmare, googla Tesla, SpaceX, Solar City, PayPal. Jag köper hans analys av energianvändningen och att det kommer bli elektricitet som gäller. Tidplanen är oklar men troligtvis betydligt snabbare än vad gemene man tror. En milstolpe är då bensinbilar allmännt betraktas som att röka idag. Luktar illa och används undantagsvis enbart för att man måste. Skulle inte vara helt förvånad om det sker innan 2025.
  • Utöver elbilar, så kommer massor med personliga transportsätt anpassade för stadsliv. Elcyklar och de leksaker som hoverboards, elektriska enhjulingar och skateboards, är alla ett sätt att uppnå 2-3ggr gånghastighet utan att bli svettig. De flesta (utom cykeln) går att ta med på bussen och tunnelbanan. Sverige med snö på gatorna får betraktas som undantag i det stora hela. Tror dessa fyller ett djupare behov än att enbart vara leksaker.
  • Delningsekonomin: Menar inte 70-talstanken att vi alla är en stor familj som delar med oss. Det jag menar är att nu med IoT och den kontroll/övervakning vi kan ha på våra saker, tillåter att vi kan hyra ut / låta andra använda dem under kontrollerade former. Med webben och sökmotorer som matchar utbud och efterfrågan, samt övervakning av uthyrningen så kostar det inte längre oss någon uppmärksamhet, vår viktigaste resurs, att administrera det löpande. En del uppsättning innan och ev viss schemaläggning men inget behov att prata med dessa främlingar. Det öppnar möjligheter. Detta kommer också ge en indirekt effekt av att mer saker finns att tillgå som tjänst och att äga kan tappa sin lockelse i framtiden för många scenarios.

Håller på och skissar på ett system kring eluttag och tekniken kring smarta hem. Genom att ta den existerade teknik som utvecklats där och utforma ett molnsystem som tillåter en att dela ut dessa enheter till andra människor så lyfter man sig från pyssel för egen del, till interaktion mellan människor. Där börjar det bli möjligt att få pengar inblandade och affärer kan skapas. Jag har själv valt eluttag som utgångspunkt men resonemangen är generella.

Ägnar idag  ungefär lika mycket tid åt att gräva efter möjliga applikationsområden och att lysa igenom dom efter problem som kan lösas och sätt att ta betalt, som tid lagd på rent teknisk utveckling. Som vanligt när det gäller IoT är möjligheterna överallt. Samtidigt är bertalningsviljan högst tveksam i alla uppenbara fall som inte redan hanteras av andra. Så när det gäller utveckling mot IoT så måste affärsnytta vara vägledande.

Det som jag tagit fram idag är en molntjänst som man kan skapa ett konto hos, registrera sina eluttag och ladda ner en QR kod för just ditt uttag. Koden är tänkt att sättas vid uttaget. Sedan kan godtycklig person scanna koden med mobilen och komma till en accesssida på nätet. Uppfyller personen villkoren där får denne möjlighet att kontrollera uttaget. Systemet kan även slå av efter viss tid / förbrukad energi. Det är en demonstration av idén så syftet är att kommunicera idéer idag, inte att vara stabilt eller vackert. :-)

Jag är intresserad av återkoppling på idén. Jag har redan hört att det är för billigt med el, men har ni andra bra synpunkter (speciellt nischer där detta kan platsa) är det intressant. Jag har en 45min lång presentation som går in i detaljer så är någon intresserad så pratar jag gärna. Finns också en kortare presentation om ett närliggande case som kan ge konkreta pengar. Den överliggande motiveringen är att följa 'Lean startup' metodiken. Utvecklingen är ett experiment för att identifiera intäktsströmmar och möjlighet att bygga en rörelse. Största brist idag är tillgänglig utvecklingstid (resurser) och osäkerheter kring affärskapande. Tekniken känns rätt så rättfram. Jag är öppen för olika scenarios, från att driva ett fritids open source projekt, till att det blir något riktigt av det.

För mer information, se denna sida och gå direkt till applikationen. För mer information, kontakta mig på t.ex. epost.

--- Mikael R

 

 

Hur bygger du ditt system? 27/09/2015

Har tidigare pratat om vikten av gränssnitt och möjligheten att använda 3:de parts delar i sin utveckling. Speciellt möjligheten att fortfarande vara i kontroll över sin kodbas och ha möjlighet att byta ut delar. Varför fokus på detta? Vad gör att det inte 'bara fungerar'?

Embeddedutveckling på microcontrollers (MCU:s) har, med rätta, styrts av behovet att hålla allting snålt. Lite flashåtgång, speciellt lite RAMåtgång. Och detta försvinner inte över en natt. Trycket har minskat och delvis flyttats över till utvecklingstid, men det innebär inte att det är fritt fram att lasta in allt och lite till. Det behövs fortfarande kontroll över åtgången. En effekt av detta, tillsammans med open source kulturen på en del håll, och att MCU tillverkarna stått för mycket hjälpmjukvara, är att mycket av den hjälpmjukvara som används distribueras i form av källkodspaket. Man får en zip fil, packar upp denna, lyfter in koden i sitt projekt och den blir en del av ditt byggsystem. Har fungerat relativt väl och man kommer snabbt fram till något körbart. Exempel på denna distribution är t.ex. FreeRTOS, LwIP, firmware libraries från t.ex.ST.

En annan egenhet av MCU utveckling är att målplattform ofta är rätt unik. Man har valt en krets utifrån behov och det gränssnitt man har att arbeta mot är här den registeruppsättning MCU:n har. Ofta är sammansättning av drivers, och framför allt länkskriptet, faktorer som driver utvecklingen mot att ge en unik mjukvara för varje hårdvaruenhet.

De toolchains som ofta används (IAR, Atollic, etc) lägger väldigt mycket fokus på att det ska vara lätt att komma igång. 'Hello World' med en blinkande led får max ta 10min att få upp på ett eval kort. Mindre fokus ligger på möjlighet till bygge på byggservers, stöd för unit testning eller kompilering mot flera målplattformar eller flera binärer. Detta tillsammans ger en kultur och minsta motståndets väg mot att för varje projekt betrakta kodbasen som unik för hårdvaran. Man utgår från något liknande tidigare, klipper/klistrar ihop en start och bäddar sedan in applikationslogik direkt på target. Testning sker genom provkörningar på evalueringskort eller direkt på målhårdvara.

Det här är inte en hållbar väg framåt.

För små kodbaser visst, där har inte tiderna förändrats. Men det som händer är att mer och mer ska in i hårdvaran och då måste mer fokus läggas på gränssnittsskapandet. Dels för att återanvända då ny hårdvara kommer, dels för att minska underhåll. (Hur många källkodsträd behöver vi fixa den där SSL buggen i?)

Så hur börjar man resan mot mer kontroll över sin kod? Joel Spolsky skrev för 15 år sedan en enkel lista med tumregler som har blivit ett av de mest lättillgängliga sätten att få grundfundament på plats i sin utvecklingsprocess. Har man inte dessa finns ingen anledning till finlir på andra områden. Jämför med tandborstning för personlig hygien eller bilbesiktning. Det ska bara fungera om man vill ha möjlighet att utvecklas över tiden, eller ha någon som helst kvalitetskontroll. Artikeln med listan är väl värd att läsa: The Joel Test: 12 Steps to Better Code. Vid det här laget brukar punkt 1 (Use source control software) finnas på plats. Men punkt 2 (Can you build in one step?), mera tveksamt. Får kanske ut en binär från bygget, men paketering i zip fil med release-dokumentation? Punkt 3 (Do you use a build server?) Brukar behövas betydligt mer dedikerade ledare för mjukvaruteam för att ta detta hela vägen inom MCU utveckling.

Det finns orsaker till detta. Mycket faller tillbaka på byggsystemen som dagens IDE erbjuder. Ligger man kvar där, brukar det vara en hel del jobb att få igång en byggserver. Så enligt min åsikt, så är själva byggsystemet en av nycklarna för att kunna bryta vanan att bygga mjukvara direkt mot målplattformen. Ska man uppnå att en buggfix i ett hjälpbibliotek, bara behöver rättas på ett ställe, så måste den förändringen propageras automatiskt till alla relevanta binärer och då håller det inte att klippa/klistra kod mellan olika källkodsträd. Koden ska ligga i sin egen modul som används av dem som behöver den.

Så vad är alternativen? Tyvärr få, ålderdomliga, och inte speciellt bra. Under alla år jag arbetat har jag alltid landat i att 'make' får göra jobbet. En enda anledning. Programmet får jobbet gjort.

Jag svär under uppsättningen, resultatet har ofta övrigt att önska. (lägga tid på header dependency tracking den här gången? är det värt det?) Speciellt då MCU utveckling ofta sker i Windowsmiljö så kommer den extra lilla egenheten av att köra allt under Cygwin eller MinGW. Var skulle det vara \ och var / för att skilja sökvägar? Det löser sig, men det tar tid, är frustrerande och felbenäget arbete.

Övriga alternativ är oftast anpassade för desktop OS. Där finns det flera. cmake, qmake, scons, waf, etc. Men där är fokus på hantering av versionshanterade bibliotek i systemet. Sällan ser jag stöd för hantering av länkfiler, modifiering av c-startup och dessa andra frihetsgrader som brukar behövas varefter systemet växer.

Så vad vill jag ha ut av ett byggsystem för embedded? En liten önskelista:

  • Command line tool. Kan dels startas från eclipse, dels byggservrar. Mer flexibelt.
  • Out of tree build. Dvs alla genererade filer ligger _inte_ i källkodsträdet. Ska räcka  att radera en katalog för att få totalt ombygge. Underlättar för bygge mot flera targets också.
  • Textbaserade regler. Ska gå att spåra regler och de kommandon som invokeras så byggprocessen  blir transparent.
  • Full dependency tracking. Dels under kompilering av .c/.h filer. Men även av preprocessning där källkodsfiler och länkfiler samt post processing.
  • Används wildcards (t.ex. *.c för alla .c filer i katalog) ska systemet upptäcka när filer läggs till/tas bort.
  • Stöd för att direkt från .zip filer packa upp dessa, patcha och sätta upp sökvägar så  att vid ny version räcker det med att uppdatera .zip paket och en versionssiffra. Byggsystemet  ska kunna hantera resten. Detta inkluderar att beskrivningen av bygget ska ligga utanför det uppackade biblioteket. Beskrivningen av bygget är del av din mjukvara, inte 3:de partsleverantören om de levererar i form av ren källkod.
  • Stöd för bygge mot flera targets. Vill dels kunna bygga för målhårdvara, dels för evalueringskort, dels för desktopmiljöer för unit testning. Förutsätter att koden klarar detta. Frågan är om ditt byggsystem gör det?
  • Bygge av delar av systemet. Under utveckling skriver man ofta i enskilda moduler samt har en unit test driver för första checker. Ska gå att bygga detta utan att resten drar igång.
  • Det ska vara snabbt. En av de mest frustrerande sakerna att ägna tid åt är att se kompileringskommandon sakta rulla förbi, för att inte tala om försteg för dependency trackning. Koppla detta till att köra under cygwin på windows och det är många timmar som  flyter iväg. Det dödar 'flow' som är så viktigt för produktiv utveckling.
  • Ska klara att bygga flera olika binärer för samma target. Hur ofta sitter man inte med  en huvudapplikation, en produktionstestning och en emc binär? De delar 90% av koden som ligger i gemensamma moduler men har lite olika uppsättning.

Har inte hittat något byggsystem som kommer i närheten av min önskelista. Större projekt med en lokal 'make' guru kan komma i närheten men det ligger många timmar bakom. Sedan tenderar byggen att ta tid när projektet växer. Speciellt dependency tracking är ett problem.

Så, är det kört? Nej. Det går att få en dräglig miljö. Bara att det är en viss investering att få till det. Byggsystem behandlas rätt styvmoderligt och det kostar i längden. Det tar bort frihetsgrader från designen som är svåra att komma till rätta med längre fram. Har man behov av att utveckla mer än triviala mjukvarusystem så är byggmiljön definitivt en vattendelare mellan att sitta bakom ratten eller bara hänga med på färden.

Till sist. Finns ett system som jag tror kan ha potential som en komponent i ett större system. Ninja build system. Som författaren säger: Ska fungera som nedskalad make. Någon annan skriver reglerna och analyserar beroenden då ninja enbart bygger. Tack vare det så är den snabb. Så det enda som fattas är en MCU anpassad frontend. Tror att detta är en väg framåt.

 

Embeddedutveckling, nya vindar. 08/09/2015

Du sitter vid din plats. Framför dig finns en utredning som pågått inom företaget med ett förord av VD. Företaget behöver förnya sig. Produkterna behöver tas in i framtiden. De ska kopplas upp och prata med 'molnet'. Din uppgift: Genomför.

Så var börjar man? Vad är viktigt? Vad är 'molnet'? Ert företag tillverkar prylar. Det kan vara för industri, det kan vara komponenter. En del standard, en del kundanpassat. Ni är inte främmande för mjukvara eller elektronik. Det sitter en del mikrokontrollers i vissa produkter. Än så länge har det kunnat hållas relativt enkelt då det inte pratar med andra delar.

En sak som nu kommer hända. Ska man prata med molnet, så behöver man ha nätverk. Någonstans längs med vägen kommer en nätverksstack komma in som pratar TCP/IP och en del andra protokoll. Inte nödvändigtvis i mikrokontrollern, men troligtvis. Och med längre beräknad livslängd på produkten, mer mer troligt att protokollstacken behövs där. Till detta diverse protokoll, stöd för att hitta rätt motpart i molnet att prata med, säkerhet, identiteter på saker och människor. Etc...

Världen blev nu bra mycket mer komplex att hantera på egen hand. Någonstans här börjar tankarna dra sig mot tidsmaskiner, 10 år tillbaka, enklare förr eller till och med bättre förr... Där bryts tankekedjan. En annons sticker ut från en branschtidning. Säger något om 'hjälpbibliotek', 'ramverk', 'IoT'.

Här kommer först nyfikenheten. Verkar bra med färdiga lösningar. Bara att köpa och plugga i, eller? Nu invändningarna, men vår egen funktionalitet? Hur får den plats? Hur vet vi att vi inte blir bakbundna av stela yttre bibliotek eller underleverantörer som inte levererar? Sedan förnekelsen. Kan aldrig fungera att ta in dom bitarna i en mikrokontroller. Vi skriver koden själva. Behöver spara flash, behöver allt RAM. Speciellt på vår lilla kontroller. Den är riktigt bra med 10 år på nacken. Alla kan den, inte avancerad som de nya där ute. Lite trång kanske men det fungerar... Sedan illusionen. Vi lägger dit det där nya själva. Hur svårt kan det vara...

Detta slutar sällan bra. Var gick det fel? Vilket steg? Jag skulle säga vid rädslan för det nya. Vi vet vad som finns, vi vet inte vad som finns där ute. Moderna mikrokontrollers har vuxit och har blivit mer komplexa. De är inte en gammal 8051 längre. De har också mer minne/funktioner/prestanda för väldigt små pengar. Däremot fungerar det inte längre att utveckla allt från början längre. Övergången är gradvis.

Tidigare gjorde alla det, nu mer klarar specialister av det. Och de blir färre över tiden. Sa jag att de har mer minne/mer prestanda. Faktiskt mer än vi behöver? Ah, köp en billigare då är väl självklart. Nej, nu börjar avvägningen komponentpris/utvecklingstid svänga över till att den lilla vinst på komponentpris inte rättfärdigar längre utvecklingstid. Det blir färre och färre nischer där det är giltigt. Just det, stod det inte något i utredningen från VD om marknadsfönster... Kan kort utvecklingstid ha vuxit i betydelse från förr? Ok. kan offra lite minne och flash på att få hjälp.

Tagit oss över det hindret. Frågan är hur gör vi? Nu börjar det bli intressant. Vi har rörelsefrihet. Vi kan använda en del av processorns resurser för lägga in 3:de parts bibliotek som löser uppgifter åt oss. Vi kan kosta på enklare OS för att partitionera problemen och få oberoende utveckling av delar. T.ex. den där TCP/IP stacken. Fanns en på nätet, open source, som alla verkar använda. Vi kan lägga ett anpassningslager och ta den. Slipper dels skriva koden. Men framför allt, vi behöver inte en TCP/IP expert som kan alla RFC:er, vi slipper testa den, och vi kan fråga andra användare om vanliga problem med den.

Kör igång ett pilotprojekt. Väljer en hyfsat kompetent mikrokontroller. Börjar gräva i dokumentationen. Det var mycket! Users guides, programmers manual, data sheet, reference manual. En del med  över 2000 sidor pdf. En del via referens till något företag kallat 'ARM'. De har gjort delen kallad 'Cortex-M4' i mikrokontrollern. Sedan val av OS, testa FreeRTOS och lwIP som TCP/IP stack.

Sitter lite fast, tills man upptäcker exempelsamlingen och firmwarebiblioteken med exempelkoden. Med denna kan det gamla arbetssättet sträckas vidare och något fungerade kommer fram. Var rätt mycket svett och tårar på vägen att klippa och klistra ihop olika exempel men det gick. Trist bara att vi behöver göra om det för nästa produkt och nästa byte av hårdvara.

Frågan är, är världen bättre mot 10 år sedan? Dags för fokusskifte. Hur såg utvecklingen ut för ca 15-20 år sedan inom PC/Linux världen? Då Windows 95 vad det nya heta. PC:n hade 64MB ram och 90% av applikationerna fortfarande startades via Dos. Det var då ramverk som 'COM' togs fram. Hemdatorerna hade dött av 5 år tidigare. Starka leverantörer som Microsoft, Borland och Lotus Notes växte fram (och en del senare dog).

Hur såg utvecklarens vardag ut? Det var: Bråka med OS och det API det erbjöd, välja hjälpbibliotek och knyta samman dessa. Redan 10 år tidigare hade man släppt att koda mot specifik hårdvara och trimmande av busy wait loopar mot specifik hårdvara. Man bytte PC var 3:de år som användare, var 18:de månad som utvecklare. Kort och gott, i stort sett all utveckling skedde mot API:er. Arbetet bestod i att skapa nya API:er och nyttja gamla från delar och sy ihop sin lösning. Yttre gränssnitt var filformat, GUI:s och sakta hade nätverk börjat dyka upp med protokoll. Också en karaktäristisk jakt på att identifiera det som ändras (teknik, hårdvara, användarkrav) från det som fast (programmets syfte, programmeringspråk med dess begränsningar). Allt för att kunna utnyttja det fasta att stå på då omvärlden förändras.

Så tillbaka till vår situation. Framtiden kommer rullande sakta men säkert. Och här vill jag påstå att den upprepar sig. Hårdvara sjunker tillbaka. Det långlivade är mjukvaran. Jakten på fast mark att ha som bas för mjukvarudesign ökar och de rörliga delarna trycks ut mot periferin. Stark är trenden av att dela upp världen i gränsnitt där man kommunicerar, mot implementation där man utför. Tidigare var delen med utförande stark. Nu är denna del ofta den som förändras medan gränssnitten är det fasta.

Här kommer det nya. Uppstart av projekt och tidig utveckling, där är gränssnitten (protokoll, filformat, interna API) är centrala. Med dom satta följer implementationen nästan automatiskt. (Kan behövas några varv då 'nästan' är relativt i sammanhanget). Även gränssnitt ändras och dessa versionshanteras för att utöka livslängden.

Ett sätt att anamma denna nya värld är att fokusera på vad som är föränderligt mot vad som ligger fast. Har man gett sig in i mikrokontrollerutveckling, så är det troligtvis någon idé som är lite mer långlivad. Hitta denna. Låt sedan krav och idéer flöda ner från denna mot hårdvara/mjukvara/hjälpsystem.Varje gång man byter kontext, t.ex från applikationslogik till protokollhantering, från OS till hårdvara, från molnet till periferidelar, fråga sig om det inte vore bra med ett gränssnitt. Med dessa kan sedan delar bytas ut, anpassningar skapas och produkten leva vidare i en föränderlig värld. 3:de partleverantörer kan lyftas in och delar kan apassas till varandra.

Det är inte ok längre att skriva om mjukvaran då hårdvara behöver bytas ut. Mjukvaran lever längre och hårdvara är en föränderlig del som mjukvaran ska skyddas ifrån genom någon form av gränssnitt. Här finns svaret till varför man måste våga byta fokus. Krav på utvecklingen som tvingar en till att skriva nytt från hårdvara och uppåt, klarar inte att växa och förändras in i framtiden.

Livslängden på mjukvara bara ökar då den växer, då investeringen i utveckling på den är större och behöver betala sig. Livslängden på hårdvara minskar med den höga utvecklingstakten idag. Så hur stannar vi i förarsätet och inte blir förpassade till bagageutrymmet?

  • Ta kontroll över gränssnitten. Se till att de är antingen standardiserade (billigast, bäst), eller att du  själv kontrollerar bägge sidor (dyrare, bra för rörelsefrihet och kontroll, men det kostar).
  • Var noggrann med dina egna gränssnitt. Inse att de är dyra att förändra. Fortfarande är det dyrare att inte  ha dom. Ta ett varv extra över dessa under design.
  • Vid 3:de partdelar. Du köper implementation. Men än viktigare, de vet förhoppningsvis vad de sysslar med. Så det API som erbjuds har troligtvis designidéer som skulle ta lång tid att upptäcka själv. Väldesignade gränsnitt är viktigt. Sedan bonus är att ofta är det vältestad kod och delas med andra användare.
  • Implementation kan vara extremt billigt, och extremt dyrt. Från gratis (open source) till helt   egenutvecklat. Se till att betala för de delar där det ger mervärde.
  • Avvägning av standard/egenskrivet. Standard innebär att det är mogen teknik. Vill man vara i framkant  är ofta standard svårt. Välj noggrant vilken teknik som behöver vara i framkant.
  • I jakten på standard riskerar man att hamna i bakkant. Ge det några år och det är föråldrat. Balansen framkant/bakkant/livslängd/förändring för olika delar är några av de mest centrala frågorna vid val av teknik. Och vet man inte, skapa ett API med en anpassning för säkerhets skull. Sannolikhet att gissa rätt första gången då man inte vet, är extremt låg.

Av att döma av PC/Server världen så blev framtiden bättre. Tror även att det gäller för mikrokontrollers. Måste bara våga omfamna det nya, hålla koll på det gamla, vara noggrann med sina gränssnitt och välja de delar man själv vill ha kontroll över.

 

C/C++11 threading and memory model 06/08/2015

Har ägnat några dagar åt att tränga mig in i C11/C++11 och deras gemensamma memory model och stöd för multitrådning. Har en idé om att få till en kurs för bl.a. embeddedutvecklare inom ämnet.

Det är ett intressant ämne. Att ta en gammal standard som C med rötter från sjuttiotalet och deras syn på hur en dator förväntas fungera, och sedan, med bakåtkompabilitet, lyckas få till en standard där moderna datorer kan köra program och faktiskt relativt bra kunna utnyttja alla nya cores och kunna dölja bl.a. latency. Det krävs rätt mycket fingertoppskänsla!

Ytligt sett har man tagit 'best practice' med trådar och mutexes och standardiserat detta. Så inga större överraskningar där. Där det börjar bli intressant, det är hur man har vävt in det standarden kallar 'synchronizes with', 'release' och 'acquire' i det redan existerande ramverket.

En modern dator är väldigt hierarkisk om man ser till minnet. Vill man köra något väldigt fort, så ska man röra sig inom små minnesområden och absolut inte dela något. Så fort man behöver dela med sig av data till andra cores, börjar latency dyka upp. Det talar för att en moden dator skulle må bra av ett språk med klar åtskillnad mellan det egna minnet och det minnet man delar med andra (kanske ser en renässans för Erlang?). Man jobbar för fullt i det egna minnet och sedan skickar resultatet genom delat minne till nästa instans.

Samtidigt har C/C++ en platt minnesrymd. Allt minne är lika. Det var så det såg ut för 40 år sedan och för bakåtkompabilitet kommer det fortsätta se ut så tills vidare. Språkens minnesmodell är väldigt dåligt anpassade till de begränsningar hårdvaran har. Hårdvaran har fått anpassa sig. Så istället för lokalt minne med programmerarkontroll, har vi cachar som automatiskt mellanlagrar data och försöker upprätthålla illusionen av enhetligt minne.

En naiv standardisering hade tagit trådar och mutexes och stannat där. Eventuellt fått med atomics. Prestanda hade fått lida då de krav en modern minneshierarki ställer på språket är långt ifrån den platta värld språken föreskriver.

Det man har gjort istället är att ge en vink till faktum att en tråd när den kör utan behov av att kommunicera med omvärlden, kan köra på i isolering. Så grundinställningen är att begär man inte delning av data, så kan man behålla data i sina cachar. Delningen sker genom synkroniseringen. Vid skrivning sker ett 'release' event och på mottagande sida finns motsvarande 'acquire'.

Man kan betrakta det hela som ett 2 lagers system. Ett bottenlager där allt minne som är adresserbart finns. Sedan ett privat lager för varje enskild tråd. Vid exekvering kommer varje tråd ta in det data den behöver i sin cache. När den till slut är beredd att delge omvärlden sina resultat, utför den en 'release'. Det är en signal om att publisera det som skapats till det globala minnet.

På samma sätt, en tråd som är beredd att se vad som hänt i övriga systemet utför sin acquire, vilket indikerar att den ska uppdatera sitt lokala minne med vad som hänt i det stora. På detta sätt kan man skriva effektiv kod under programmerarens inflytande där enkeltrådad körning inte behöver lida så hårt av skillnaden mellan modell och hårdvara. Samtidigt kan man, till ett pris, synkronisera sig med övriga trådar och se vad som har hänt. Har man behov av prestanda kan man komma rätt långt med de svagare synkroniseringar som minnesmodellen erbjuder.

Som sagt, grundläggande modellen är 40 år så att det knakar i fogarna är förväntat. Tycker att det arbetet som lagts på att få ett användbart språk på modern hårdvara, har burit frukt.

 

QSM Software Almanac 01/08/2015

En snabb blänkare om att QSM software almanac är ute. Det är en sammanställning av data från en stor mängd IT projekt (inkluderar här bl.a. embedded, realtidssystem och industritillämpningar) som man följt under längre tid och trackat saker som storlek/kostnad/leveranstid och andra mätningar av hur bra utvecklingen har gått. Tänk på den som 'SCB:s årsbok' över statistik från dessa utvecklingsystem. Den är gratis att ladda ner.

Några förväntade resultat. Brooks hade rätt. Att lägga till fler folk ger rätt mycket overhead.

Några intressanta a.ha upplevelser. Agila metoder funkar bra för små projekt. Sedan börjar det bli svårare just större de blir. Känns rimligt. Förvåningen var kring brytpunkten: 30'000 LOC /Lines of code. Det var väldigt lågt. Hade förväntat mig betydligt högre. Självklart är det grovt generaliserat. Men tillräckligt intressant om man sitter på ett projekt med 100'000 LOC så bör man nog gräva lite djupare i vilka delar av Agilerörelsen som verkar fungera bra och vad som anses som skakigt. Min personliga åsikt är att up-front design innan man börjar koda är definitivt något att tänka på.

Som sagt, är man intresserad av processen kring mjukvaruutveckling och vad som fungerar så kan pdf:en ge en viss verklighetsförankring i dessa tider av buzzwords och evangelister. Utvecklingen går framåt och kan man kapa några blindspår är det alltid trevligt.

 

IPv6 i praktiken 28/07/2015

Ett litet privat projekt som växte och till slut blev en rätt bra lösning.

Upprinelsen

Det hela började med att föreningen för bostaden uppgraderade sitt bredband så var och en kunde på 1Gbps bredband via ethernet. Men också full support för IPv6. D.v.s. varje bostad fick en /64 nätmask initialt och om man ville kunde man få en /56 (256 st undernät). Till det fanns även en statisk IPv4 adress. Hade redan en någorlunda genomarbetad lösning med olika undernät där t.ex. mediaenheter har 1, företaget 1. Lagring uppdelad på olika nät utifrån typ av data etc. Till saken hör också att jag vill ha trådat där möjligt, men vill helst inte dra fler nätverkskablar än nödvändigt.

Datalänklagret

Här kom standarden VLAN (IEEE 802.3q) väl till pass som tillåter flera logiska nät att dela på samma fysiska kabel. Jag vill även kunna utnyttja den bandbredd som erbjuds så utrustningen fick väljas därefter. Switchar var relativt lätt. Valde att införskaffa 3 st Netgearswitchar (2 st 8-portars GS108E, 1 st 5-ports, GS105E). Dessa placerades ut i bostaden på strategiska ställen där nätverksberoende utrustning fanns. Till detta fanns några vanliga 1Gbps D-link switchar utan VLAN stöd. En av VLAN switcharna placerades  direkt vid skrivbordet som tillåter direkt uppsättning av experimentnät för utveckling av t.ex. IoT enheter som kräver nätverksaccess. Kan nu även sätta upp portar där som direkt ger rå internetaccess om det skulle behövas.

Med dessa VLAN-switchar kunde jag konfigurera upp ett 'backbone' mellan dem med taggad VLAN trafik och otaggade portar till ändutrustningen. Sedan var det mest att bestämma sig för vilken Level 2 topologi som skulle finnas och ställa in den i IEEE-802.3q inställningarna i switcharna.

Landade bl.a. i följande grupper (har färger som interna namn):

  • Internet (röd).
  • Mediaenheter, telefoner, osäkra enher (orange).
  • DMZ för servers (gul).
  • Arbetsdatorer (grön).

Utöver det är det lätt att lägga till nya logiska nät vid experimentbehov. Den råa internetgruppen är begränsad i normalfallet till enheter som behöver den (brandväggen) men kan slås på om den behövs för experiment.

Hade sedan tidigare 2 olika WLAN routers, en för medie/telefoner och en för arbetsdatorer. Det var tidigare en rätt klumpig uppsättning där arbetsdatorer hade ett eget NAT:at nät bakom medienätet. Det är tyvärr priset av att använda konsumentprodukter som sällan klarar av routing mellan flera subnät, som internet en gång i tiden var tänkt att klara. Dessa WLAN switchar fick nu rollen som rena bryggor mellan en trådlös del och motsvarande trådade grupp. Så ett WLAN för grön och ett för orange zon.

Brandväggen/routern

Så vad administrerar allt detta? Gick tillbaka till en lösning som jag använt förut och som har fungerat bra. Hade innan ena WLAN routern som gränssnitt mot internet (Asus RT-66ac). Den ska vara en av de snabbare på marknaden och ska ha IPv6 stöd. Upptäckte 3 nackdelar:

  • Ska man skicka paket via NAT mot internet trådat, kom jag aldrig över ca 150Mbit/s. På tok för lite.
  • IPv6 stöd fanns. Bara en liten nackdel. De hade 'glömt' aktivera brandväggen så vid inkoppling var det raka rör in till inre delarna (oops). Med IPv6 finns inte vanlig NAT så den adress klienten använder är den man kan använda att anropa den inre datorn utifrån. En brandvägg är ett måste.
  • Som konsumentprodukt fanns inte stödet för att hantera flera nät på insidan. Så efter detta blev den relegerad till att vara brygga för WLAN access med diverse filtrering för att undvika objudna gäster.

Valde istället att köpa in en liten strömsnål PC och installera Linux på den. Valde Shuttle DS47 då den är passivt kyld (inga fläktar, har 2 nätverkskort och en celeron processor). Med 2 st 1Gbit nätverkskort så finns i alla fall en teoretisk möjlighet att nå 1Gpbs genomströmning. Båda dessa portar anslöts till en VLAN switch. Ena uttaget otaggat som tar emot internet, andra kortet skickar taggad trafik direkt på backbonedelen av nätet.

I Linux är det sedan lätt att sätta upp ett antal logiska nätverksenheter kopplade till VLAN grupperna som sedan skickar sina paket på motsvarande fysiska port med 802.3q taggning. Brandvägg blev shorewall. Ett välrenomerat projekt som gör det lätt att skapa brandväggsregler som sedan omvandlar till netfilter regler i Linuxkärnan. Behövs 2 parallella uppsättningar, en för IPv4 samt en för IPv6.

Så med denna uppsättning har jag ett backbone-nät genom bostaden där olika portar på switcharna ställs in att tillhöra ett VLAN nät. Alla interna nät använder sedan brandväggsdatorn som 'default gateway' och den tar hand om routing etc.

DHCP/DNS/NTP etc

En sak man rätt snabbt blir varse med IPv6 är att nu är det i praktiken omöjligt att klara sig utan DNS. Att komma ihåg dessa adresser och skriva in dem är i praktiken så långsamt att det inte är hållbart.

På brandväggen körs demonen 'dnsmasq'. Det är en kombinerad DHCP server samt DNS server. För IPv6 tar den även hand om 'router advertiement' (RA) rollen. För alla normalt sett fasta enheter i nätet har jag satt upp kopplingar från enheternas MAC adresser till egna DNS namn. Dnsmasq hanterar en 'privat' toppdomän kallad 'hemma' så 'nexus4.hemma' blir det namn min mobiltelefon får när den kopplar upp sig på nätverket. På detta sättet kan man klara sig utan statiska IP adresser. Nu upprätthåller jag dessa ändå av gammal vana för IPv4 sidan.

För kopplingen mot leverantören så har jag en /56 tilldelning så varje undernät får en /64, vilket i princip innebär 256 möjliga undernät. Använder själv 3-4 st. För IPv4 är det klassisk NAT:ning med portforwardering där det behövs. Har t.ex. egen epost-server sedan länge som behöver direktaccess.

Fördelar mot förr: Vad har blivit bättre?

IPv6 delen är kul att ha. Även om leverantören inte klarar av att leverera det idag, kan man införa det genom tunnling mot en av många IPv6 leverantörer online. T.ex. https://www.sixxs.net. Det innebär att paketen kommer utifrån som IPv4 men packas upp till IPv6. Sedan är det som om man satt på deras nät så man behöver veta vad man gör så man inte råkar hamna på det öppna internet utan skydd.

En hel del lärdomar.

Windows har bra IPv6 stöd, så till den grad att de ofta föredrar IPv6 till IPv4. Androidenheter plockar gladeligen åt sig IPv6 adresser när de erbjuds. Linux fungerar bra på grundläggande nivå men fortfarande en del brister i högre nivåns verktyg för t.ex. konfigurering. En irriterande detalj är att Debians olika mirrors inte alltid svarar på annonserade IPv6 adresser så det blir rätt mycket timeouts vid 'apt-get update'. Annars är det lite roligt att se Firefox applet '6OrNot' lysa upp med en '6' när man går in på google, facebook, netflix eller annan stor site. Svenska siter är i stort sett uteslutande '4'. Främsta praktiska nyttan är att få kunskap om hur IPv6 fungerar och att ha tillgång till ett fullgott IPv6 nät för t.ex. IoT utveckling.

Mycket flexiblare tilldelning av enheter till olika nätverk. Jag kan ha olika enheter anslutna till olika nät oberoende av var de står. VLAN uppsättningen är den största praktiska nyttan då man helt kan koppla isär frågan om var saker är och vilket nät de ska tillhöra.

Experimentportar vid skrivbordet är trevligt för allmänt utvecklingsarbete.

Sedan, för en gångs skull har jag känslan av 'det bara funkar' mycket oftare nu. De driftavbrott jag upplevt har för det mesta varit 5-10min och följts av ett mail från föreningen angående uppdatering av deras utrustning.

Till slut...

Det blev över förväntan. Frågan är, har man nytta av hastigheten? I vanligt surfande är det klart snabbare, men kanske inte tillräckligt för att motivera arbetsinsatsen. Däremot får jag ofta relativt bra utdelning mot stora tjänster där man utför bulköverföringar. T.ex. köp en programvara på 'Steam' och den börjar laddas ner. Efter ca 30s har de fattat att man kan ta emot data och nedladdningen går med ca 50Mbyte/s. Då gör det inte så mycket att det handlar om 5-10Gbyte data. Även för Google Drive är det trevligt att det uppdateras snabbt.

Så, hur fort blev det? Fick jag någon hastighet? Från bredbandskollen: 949,27Mbit/s ner, 961,18MBit/s upp. Känns ok. :-)

 

Blogg_introduktionsbild

Introduktion 28/07/2015

Akaza AB är för stunden den plattform jag (Mikael Rosbacke) använder för att nå ut till kunder som kan ha nytta av mina tjänster och kunskaper. I bloggen har jag tänkt samla lite mer flyktig information kring det jag erbjuder. Det kan handla om reflektioner på dagsaktuella områden, kortare texter kring specifika teknikområden eller beskrivningar av egna projekt. De kan vara både från kund (efter tillstånd) eller egna.

Inläggen kommer troligtvis komma i ojämnt takt varefter intresse / behov uppstår. Det brukar å andra sidan borga för bättre kvalitet när de väl skrivs.

Välkommen in!