[Elek.]: Ontwikkeling van een GPS fietscomputer – Intro en de boot loader (fase 1)

Door Anteros op zaterdag 27 juni 2015 18:20 - Reacties (20)
Categorie: Technisch, Views: 4.385

Introductie

Mijn eerste blog op Tweakers. Een probeersel om te zien of het wat voor mij is. Op zich ben ik niet zo'n schrijver maar het leek me leuk om het eens te proberen.

Anyway, waarom een blog over het ontwikkelen van een GPS fietscomputer? Wel, in mijn vrije tijd pak ik regelmatig mijn racefiets om er op uit te trekken. Het is voor mij een stuk ontspanning en ik kan erg genieten van de snelheid en de vrijheid die het me geeft. Omdat ik regelmatig op nieuwe plekken kom die niet (erg) bekend zijn voor mij, gebruik ik een Garmin Edge 810 GPS fietscomputer met navigatie. Ideaal om thuis een route uit te stippelen en deze vervolgens te volgen met behulp van de fietscomputer.

Maar helaas, het ding doet niet alles wat Garmin beweerd. Althans, niet stabiel. Als datalogger of als map-viewer werkt deze prima, maar de echte navigatiemogelijkheden zoals actieve begeleiding laten het vaak afweten. Sterker nog, soms laat heel de Edge 810 het afweten. Wat er ook nog eens bij moet komen is dat Garmin erg, erg slecht omgaat met klachten en softwareproblemen. De laatste firmware versie voelt nog steeds aan als BETA terwijl de 810 al ruim 1,5 jaar op de markt is.

http://static.tweakers.net/ext/f/U1VNtvSmNxm40umnrdKo4URv/full.png

Dat heeft mijn o.a. doen besluiten om zelf iets te gaan ontwikkelen. De discutabele software is echter niet de enige reden. Een andere reden is dat er diverse (motiverende) features niet, of niet goed geÔmplementeerd zijn. In mijn ogen kan dat (veel) beter en ik heb enkele features in mijn hoofd zitten die het fietsen – en sporten in het algemeen – extra kunnen stimuleren en nog leuker kunnen maken. Een laatste reden is dat ik graag embedded software ontwerp/ontwikkel en graag met elektronica bezig ben. De stap om het zelf te proberen was daarom snel gemaakt.

Ik werk ruim tien jaar als professioneel embedded software engineer en kreeg meteen kriebels om enkele interessante concepten verder uit te werken. Niet alleen op functioneel niveau, maar ook op architectuur niveau. Ook de bijbehorende hardwareontwikkeling lijkt me een leuke uitdaging.

Nu weet ik (van mezelf) dat vele (hobby-)projecten vroegtijdig stranden. En om eerlijk te zijn, vind ik dat helemaal niet erg. Je leert er altijd van en het houdt je scherp. Het is in mijn ogen dus nooit een nutteloze exercitie. Mocht het echter wel zover komen dat er een werkend prototype is, dan ben ik voornemens om serieuze stappen te maken voor een vervolgtraject. Dit zou dan een soort van kickstarter-traject kunnen zijn met als eerste doel een echt produceerbaar product te maken. Het tweede (voor mij utopisch) doel zou zijn om te groeien tot een bedrijfje wat meer onderscheidende producten voor de sportwereld gaat maken.

Overigens weet ik heel goed wat er allemaal bij komt kijken als je een product wilt maken vanuit een prototype: verificatietesten, schok-/vibratie-/emc-/IP67-/etc-testen, normeringen, maakbaarheid, re-designs, issues, lead-time, fine-tunen, handleidingen, reduceren van component-costs, (design-)documentatie, backend, support, etc, etc. Teveel om op te noemen. Het is in ieder geval een grote, moeizame en kostbare stap om van prototype naar product te gaan. Maar goed, zover is het nog (lang) niet :).

Wat kan je verwachten van deze blogs?

In het kort, niks :). Ik ga het traject in zonder bestaande code of architectuur en ik wil dus alles zelf ontwerpen, programmeren en testen. Uiteraard ga ik ook gebruik maken van bestaande, open-source, free-to-use software. Dit gehele ontwikkelproces wil ik af en toe delen middels enkele blog-posts om anderen wellicht te inspireren. Het kan ook zijn dat ik juist een blog-post schrijf om mijn frustratie weg te typen of om advies te vragen (je bent nooit te oud om te leren :)). Omdat ik de meeste tijd wil besteden aan het project, heb ik niet de tijd om de gehele context met alle ins en outs te beschrijven. Het kan dus goed mogelijk zijn dat er bepaalde informatie afwezig is, welke cruciaal is voor de context of het begrip voor de gemaakte keuzes. In dat geval, op voorhand mijn excuses. Uiteraard kan ik later het een en ander nader toelichten mocht dat nodig zijn.

Dus: verwacht niks, maar mocht er een blog-post verschijnen dan hoop ik dat het interessant genoeg is om te lezen of vragen te stellen.

Tot zover de introductie, op naar het interessante gedeelte :P

Projectinformatie en huidige status

Een lijstje met hardware eigenschappen welke ik voor ogen heb voor dit project:
  • GPS voor snelheid, locatie, logging en navigatie
  • BT voor communicatie met sensoren (BLE) en een telefoon
  • ANT+ ondersteuning voor sensoren
  • Transflective color LCD met een nog onbekende resolutie
  • Micro SD-card interface voor kaarten, opgeslagen ritten en statistieken, etc
  • WiFi
  • Diverse interne sensoren zoals luchtdruk, temperatuur, etc
  • Er is nog meer maar dit schiet me zo ff te binnen
Omdat hardwareontwikkeling tijdrovend en duur is, ga ik eerst gebruikmaken van een ontwikkelbord in combinatie met externe modules zoals WIFI, BT (LE), ANT+, GPS en een LCD. Zo'n ontwikkelbord bevat verder vaak een RS232 poort, USB, EEPROM, I2C, GPIO, SDCARD, etc. en is dus ideaal om te gebruiken voor het ontwikkelen van een prototype.

Gezien de toepassing, een GPS fietscomputer met navigatie mogelijkheid, is een energiezuinige maar relatief krachtige microcontroller vereist. Omdat zo'n fietscomputer normaliter klein moet zijn, is het niet handig om een grote print met diverse externe componenten te hebben. Integratie is key en daarom kies ik voor een microcontroller met geÔntegreerde FLASH, RAM en diverse periferie. Daarvan zijn er tig op de markt, maar aangezien ik de meeste ervaring heb met ARM ťn omdat ik toevallig al een ARM ontwikkelbord heb liggen, valt voorlopig mijn keuze op een Cortex M3 van ST. Een STM32F207 om precies te zijn. Deze microcontroller heeft de mogelijkheid om extern geheugen aan te spreken mocht de hoeveelheid interne RAM niet voldoende zijn.

http://static.tweakers.net/ext/f/NoAhPcgCqMQADktACRCq7KZk/full.png

De software, volledig geschreven in C, wordt gelaagd ontwikkeld met diverse abstracties. Dit werkt hergebruik van software componenten in de hand en maakt het relatief eenvoudig om later voor een meer performante microcontroller te kiezen, mocht dat nodig zijn.

De eerste stap was het inrichten van de ontwikkelomgeving waar ik nu bijna klaar mee ben. De gebruikte tooling is allemaal freeware: Gevirtualiseerde Linux als ontwikkel-host, Eclipse voor de IDE, ARM cross compiler voor compilatie en linken, MAKE/MAKEFILE voor de build environment en GIT als VCS. Voor code documentatie maak ik gebruik van Doxygen terwijl ik LibreOffice gebruik voor mijn design documentatie.

Omdat ik bottom-up ga ontwikkelen is de volgende stap het ontwerpen en programmeren van de boot loader. Dit is een cruciaal stukje software welke diverse verantwoordelijkheden en mogelijkheden krijgt. De boot loader maakt het tevens voor mij mogelijk om snel nieuwe firmware te flashen zonder gebruik te maken van speciale apparatuur.

Boot loader – High Level

De boot loader is het eerste stukje software wat uitgevoerd gaat worden als de microcontroller spanning krijgt. Deze heeft daarom een primaire taak om de microcontroller en eventuele andere componenten zoals het externe geheugen te initialiseren. Na deze initialisatie geeft de boot loader de controle over aan de applicatie.

In veel deep-embedded applicaties wordt de boven genoemde initialisatie uitgevoerd door de applicatie zelf en is er geen boot loader. Dat is een ontwerpkeuze maar in mijn ogen niet altijd de juiste. Waarom? Wel, een boot loader biedt namelijk vele mogelijkheden:
  • Het voorkomen van het bricken van een product als er een firmware update uitgevoerd wordt
  • Hardware en platform abstractie van een of meerdere componenten en periferie
  • Eenvoudige manier om een nieuwe applicatie firmware te flashen
  • Een applicatie interface beschikbaar stellen voor primaire functies (soort van BIOS)
  • Data 'hiding' door bepaalde data alleen via een interface beschikbaar te stellen aan de applicatie (secure firmware update, device profile data, key management, hardware revisie, etc)
  • Etc.
Het is eerlijk om ook enkele nadelen te noemen:
  • Start proces is wat complexer
  • Boot loader neemt wellicht kostbare FLASH ruimte in
  • Opstarttijd kan wat langer zijn (maar scheelt vaak maar enkele ms)
  • Build systeem is wat complexer (aparte linker files, makefiles, etc)
  • Van tevoren goed nadenken over de geheugenindeling
Doordat het hebben van een boot loader echter zoveel meer mogelijkheden biedt, wegen de nadelen niet op tegen de voordelen. Een boot loader gaat er dus komen :-)

Omdat de boot loader en applicatie apart gelinkt worden zijn het twee aparte entiteiten – ze delen geen object code –. Om ervoor te zorgen dat ze elkaar niet in de weg gaan zitten wanneer ze gedeelde resources zoals het geheugen aanspreken, moet van tevoren goed nagedacht worden hoe de boot loader en applicatie gebruik gaan maken van deze resources. Ook moet duidelijk zijn hoe beide images opgeslagen worden in het FLASH geheugen.

Voor mijn ontwikkelplatform gaat die geheugenindeling er voorlopig als volgt uitzien:

http://static.tweakers.net/ext/f/tQgbXSf2HQVPWlRbBw9GGaI9/full.png

Ik begrijp dat het bovenstaande plaatje wellicht enige uitleg behoeft.

De boot loader en applicatie hebben ieder een aparte sectie gereserveerd gekregen in het interne FLASH geheugen van de microcontroller. Deze secties liggen vast en zijn gedefineerd in de twee zelfgeschreven linker files. Omdat de boot loader in principe nooit geŁpdatet wordt in het veld, moet goed nagedacht worden over deze secties. Een te grote boot loader sectie zorgt ervoor dat er minder over blijft voor de applicatie sectie. Omgekeerd hetzelfde. Een goede balans vinden is dus cruciaal om eventuele problemen in de toekomst te voorkomen.

De boot loader heeft een klein gedeelte genaamd “BL API”. Dit is tabel met functie-pointers welke verwijzen naar functies in de boot loader code. Dit gedeelte staat altijd aan het eind van de boot loader sectie, ongeacht de lengte van de boot loader code. De ruimte tussen de “BL API” en de boot loader code wordt opgevuld met filler bytes zoals 0xFF. Door het op deze manier te implementeren 'weet' de applicatie altijd de “BL API” te vinden ongeacht de werkelijke grote van de boot loader code. De applicatie hoeft dan ook niet geŁpdatet te worden als de boot loader geŁpdatet wordt.

http://static.tweakers.net/ext/f/PwbRtSRKBjMhgaDVdyepFdsO/full.png

De applicatie kan gebruik maken van de “BL API” om bepaalde services van de boot loader aan te spreken. Denk dan b.v. aan asymmetrische decryptie (handtekening verificatie), toegang tot (gedeelde) externe permanente opslag zoals een EEPROM – hardware abstractie voor de applicatie –, uitlezen van de hardwarerevisie, producttype, het uitvoeren van een firmware update (FWU), toekennen van boot loader extensies, etc. Deze tabel is opgeslagen in de boot loader sectie maar zowel de boot loader linker file als de applicatie linker file bevatten verwijzingen er naartoe.

http://static.tweakers.net/ext/f/O6LiStbUUohIzj0tUA7OYog5/full.png

Wat nog opvalt aan de boot loader en applicatie images zijn de IVT's (Interrupt Vector Tabellen). Elk image heeft zo'n tabel. In deze tabel staan functie-pointers naar ISR (Interrupt Service Routine) functies voor de relevante (externe) interrupts. Ook de reset-vector staat erin. Omdat zowel de boot loader als de applicatie hun eigen interrupt handlers hebben, krijgen ze dus ook ieder een eigen IVT. Voordat de boot loader de applicatie image aanroept, wordt de microcontroller eerst geherconfigureerd zodat deze de applicatie IVT gebruikt als er zich een (externe) interrupt voordoet.

Als laatste de check-sums. Zowel de applicatie image als de boot loader image hebben een check-sum veld. Deze check-sums worden berekend na het genereren van de binaries door het build systeem om vervolgens eraan toegevoegd te worden. Het doel ervan is om tijdens het booten te kunnen bepalen of er code-corruptie is ontstaan in ťťn of beide images. Het kan namelijk voorkomen dat er door b.v. straling ťťn of meerdere bits omvallen in het flash geheugen. Dit kan zich dan uiten in willekeurig gedrag van de microcontroller of zelfs een complete crash. De boot loader berekent run-time de check-sums van zichzelf en de applicatie image om deze vervolgens te vergelijken met de opgeslagen check-sums. Zijn ze hetzelfde dan gaat boot proces verder. Zijn ze niet hetzelfde, dan stopt het boot proces en wordt er een error gegenereerd. Mocht de applicatie image corrupt zijn dan kan de gebruiker deze opnieuw flashen. Is de boot loader echter corrupt, dan houdt het op.

http://static.tweakers.net/ext/f/slENhojRSh0Qahh5eFf8auAi/full.png

Nu het RAM gedeelte. Bovenaan is een stukje “exclusief BL” te zien. Dit is een gedeelte van het RAM geheugen wat exclusief gereserveerd is voor de boot loader. Het is de bedoeling dat de applicatie hier niet van leest of in schrijft – echter kan de gekozen microcontroller dit niet hardwarematig voorkomen (geen MMU) –. Dit stukje RAM geheugen wordt middels een linker file geconfigureerd. De boot loader gebruikt dit om tijdelijke runtime data in op te slaan als de applicatie gebruik maakt van de BL API – de zogenaamde 'statische'-variabelen –.

Als laatste het mirrored RAM gedeelte. Normaliter is deze 'mirror' mode niet nodig, ook niet voor een standaard applicatie firmware update (FWU). Moet echter de boot loader geŁpdatet worden, dan moet deze speciale mogelijkheid wel aangesproken worden. Het is een optie van de STM32F2xx en deze maakt het mogelijk om het interne RAM geheugen te mappen op dezelfde adressen als het interne FLASH geheugen – dit ligt iets genuanceerder maar voor deze blog is het voldoende –. Dit maakt het mogelijk voor de boot loader om eerst zichzelf te kopiŽren naar het interne RAM geheugen om vervolgens de mirror-mode aan te zetten. Executie van de boot loader gaan dan onverstoord vanuit het RAM geheugen verder. Hiermee komt het interne FLASH beschikbaar om gewist en opnieuw geprogrammeerd te worden. Op deze manier kan je dus zowel de boot loader als de applicatie opnieuw flashen. Merk op dat wanneer de boot loader opnieuw geflashed wordt, er wel een kans op bricken bestaat.

Wat verder….

Zoals ik al eerder aangegeven heb, is mijn ontwikkelomgeving en build systeem op orde en kan de volgende stap genomen worden. Deze stap behelst het creŽren van de linker-files en het opzetten van de boot loader architectuur. Mijn volgende blog gaat dan ook wat dieper in op de linker-files en hoe deze gebruikt worden in zowel code als de linker. Tevens zal ik wat dieper ingaan op de boot loader architectuur en de eerste resultaten van de implementatie.

Slot

Uiteindelijk is het toch meer type-werk geworden dan gedacht maar desalniettemin hoop ik dat het (een beetje) interessant was. Mijn streven is om de volgende keer meer plaatjes en minder tekst te plaatsen :)

Anyway, bedankt voor het lezen.

References en links:
Eclipse C/C++
ARM cross compiler
GIT
STM32F2xx BSP+FreeRTOS+CMSIS (STM cube)
STM32F2xx reference manual – Cortex M3 reference manual

Volgende: [Elek. GPS fietscomputer] Linker, HAL en huidige boot loader status 07-'15 [Elek. GPS fietscomputer] Linker, HAL en huidige boot loader status

Reacties


Door Tweakers user Hertog6, zaterdag 27 juni 2015 18:57

Interessant! Ik ga jou project zeker even in de gaten houden! :D

Door Tweakers user FastFox91, zaterdag 27 juni 2015 20:02

Succes! Tijd geleden had ik bedacht dat het handig zou zijn als Garmin de code opensource zou maken. Ben benieuwd hoe ver je komt.

Door Tweakers user Thedr, zaterdag 27 juni 2015 20:19

Erg interessant en leuk project! Ga het zeker volgen :)
Ik denk dat het voor veel tweakers (mijzelf incluis) leuk is om te zien hoe je de ontwikkeling opzet van een embedded systeem.
Het typewerk is misschien wat veel, maar besef dat je hiermee ook voor jezelf een aardig stuk documentatie en achtergrond creeŽrt. Daarnaast: als je het een ander uitgelegd kunt krijgen dan pak je het later zelf ook een stuk makkelijker op.
Er is afgelopen week overigens een stuk krachtiger variant van de Cortex M3 uitgekomen: de Cortex M7.
Kom trouwens bij problemen/vragen ook gerust eens buurten in de EL-Kroeg

[Reactie gewijzigd op zaterdag 27 juni 2015 20:23]


Door Contagion, zaterdag 27 juni 2015 21:18

Interessant, maar waarom kies je voor een 'niet zo krachtig' platform als de Cortex M3? Uiteraard is het op deze hardware best mogelijk, maar ik denk dat je makkelijker/sneller zou kunnen ontwikkelen als je uitgaat van een SoC en Linux als OS, zoals de Olinuxino's van Olimex of een Aria G25 van Acme Systems. Beide SoCs kosten zeer weinig en voor een Olinuxino zijn er aardige (touch) LCD's te verkrijgen die je direct kan aansturen.

Voor een project op mijn werk waarbij een beetje grafische toepassing nodig was, zijn we ook uigekomen op een Olinuxino met bijbehorend LCD, simpelweg omdat je dan op basis van alle Linux tools en libraries snel een product kunt ontwikkelen. Voor het LCD bijvoorbeeld op basis van framebuffer en DirectFB. Dan skip je ook het hele gemiep om bijvorbeeld fonts te renderen etc. Vervolgens bak je je software via buildroot tot een image die je simpel op een SD kaart zet en kan booten. Bootloaders als uboot etc. zijn ook gewoon vrij beschikbaar.

Door Tweakers user Anteros, zaterdag 27 juni 2015 22:04

@Iedereen: Bedankt voor jullie reacties!

@Thedr: Ik las vandaag in de "EL-kroeg" dat idd de M7 uitgekomen is. Zover ik weet is de STM M7 Cube library nog niet beschikbaar, maar goed, dat zal vast niet lang meer duren. Wellicht dat ik in een later stadium eens goed naar de M7 ga kijken, mocht dat nodig zijn.

@Contagion: Ik ben bekent met buildroot/U-boot/BareBox, Linux development (incl Preempt RT) en Linux compatible development boards - Pas met een AM335x dev-board gewerkt en professioneel ontwikkel ik ook applicaties voor embedded Linux op onze eigen borden -.

Er is echter een duidelijke reden waarom ik daar niet voor gekozen heb: de prototype hardware moet lijken op wat gebruikt gaat worden in een echt product. Linux vergt meestal een wat zwaardere processor en meer externe componenten (NOR/NAND FLASH, DDR(2/3)-RAM, relatief grote SMPS, enz). De PCB zou veel te complex en duur worden terwijl zoiets ook zeer lastig 8+ uur te voeden is met een accu (GPS en het LCD-scherm staan continu aan). Dat niet alleen, het geheel zou waarschijnlijk ook te groot worden. Een laatste argument is dat het voor deze toepassing ook helemaal niet nodig is om Linux te gebruiken. Door een kleine boot loader te maken icm met een Real-Time Operating System - in mijn geval FreeRTOS - kom je al heel erg ver terwijl je veel minder FLASH/RAM en processing power nodig hebt. Een bonus is dat het geheel ook nog eens een stuk minder complex is.

Wat overigens wel mogelijk is, is om in een later stadium een Cortex M4 of nu de M7 te kiezen. Dit is relatief eenvoudig en waarschijnlijk een middag/dag werk.

Door Tweakers user Contagion, zaterdag 27 juni 2015 23:09

Ik begrijp dat het niet nodig is en dat je voor een minimale configuratie gaat. Ik zou ook dat een interessante uitdaging vinden, maar aan de andere kant zou het de ontwikkeltijd misschien erg verkorten. De ACME SoM kost per 1 echter ook nog geen 28 euro, heeft RAM aan boord, is slechts 40x40mm en is met zeer weinig extra hardware op je PCB aan te sluiten op SD/LAN/USB etc. Het verbruik is nog geen 80mA (zonder LCD en GPS uiteraard en LCD zit nie standaard op die SOC).

Je kan natuurlijk ook gewoon een Android telefoon pakken en de app Locus op instaleren, maar daar is weinig lol aan ;).

Door Tweakers user Biersteker, zaterdag 27 juni 2015 23:15

Topblog!
Ik zit toch met een paar vragen, aangezien je toch een eigen handheld /mounted device wil maken.
- hoogtemeter ?
- (active) sensors? (Ik denk aan usecases in skigebieden, reccotags uitpeilen als het moet. )
- Batterijtijd?

Dingen als haversine zijn in pricipe vrij "duur". (Tip: Hou wel echt rekening met veel gps calc op je cpu ;) )

Door Tweakers user Anteros, zaterdag 27 juni 2015 23:36

@Biersteker: Thanks :) Een hoogtemeter komt er inderdaad in middels een luchtdruksensor. Ik heb verder nog niet echt nagedacht over additionele interne sensoren met uitzondering van luchtdruk en temperatuur. Maar goed, tegen die tijd komt dat vanzelf. De firmware wordt op zo'n manier opgezet dat het erg eenvoudig is om extra sensoren mee te nemen.

Batterijduur wordt een uitdaging. Nu heb ik diverse ideeŽn om het stroomverbruik terug te dringen, zoals: adaptieve backlighting, CPU in slaap brengen wanneer mogelijk, automatisch schalen van de CPU frequentie, het tijdelijk uitschakelen van hardware componenten en periferie, enz. Maar goed, voorlopig is dat nog niet aan de orde.

Vwb GPS calculaties kan het ook nog een uitdaging worden. Ik ben een tijd geleden bezig geweest om een navigatieprogramma op Android te ontwikkelen en was al zover om de kaart real-time dynamisch te tekenen met zoom, rotatie en positiebepaling. Tevens was het mogelijk om echte great-circle afstanden tussen meerdere GPS locaties uit te rekenen met behulp van haversine. Er zijn wel wat manieren om de boel te versnellen maar de trade-off is een lagere nauwkeurigheid. Je kan bv werken met integers en lookup-tables. Een uitdaging, maar tot zover geen blocking issue.

Door Tweakers user Sissors, zondag 28 juni 2015 13:38

Interessant onderwerp, wat random opmerkingen/vragen:

Voor jouw maakt het niet veel uit gezien je toch beide moet maken, maar waarom wordt de bootloader altijd aan het begin gezet? Voordelen die ik zie is dat het onafhankelijk van hoeveelheid flash is, en dat het makkelijker is bij het maken van de bootloader. Echter voor de applicatie is het makkelijker als de bootloader aan het einde staat, dus ik begrijp nooit echt waarom als bijvoorbeeld een STM, Freescale of een NXP een bootloader maakt die niet in ROM staat, die altijd aan het begin van het flash wordt geplaatst. Dan is het makkelijker voor de gebruiker als ze hem aan het einde zetten: Dan heeft je programma geen speciale eisen meer nodig (en door de bootloader de reset vector niet te laten overschrijven en naar de bootloader te laten verwijzen, moet dat prima werken. IIG ik heb voor de grap zoiets een keer met de NMI gemaakt voor Freescale MCUs: Dat was dan wel een simpele seriele bootloader, maar toch. Hij overschreef van de te laden binary simpelweg de NMI handler met zijn eigen adres, en dat werkte prima.

Volgende: Word je echt blij van de STM drivers? Volgens mij is het nu iig consistenter geworden, was redelijk irritant wanneer je wat schreef voor peripheral van MCU A, en dat die dan niet werkte voor identiek peripheral op MCU B omdat de drivers verschilde. Terwijl als je gewoon direct registers schreef dat wel voor beide werkte. Freescale heeft wel consistente drivers tussen verschillende MCUs, maar elke keer dat ze het versie nummer 1 ophogen veranderen ze maar meteen functie namen en argumenten.
Ik kan me voorstellen dat bij bijvoorbeeld een I2C het scheelt gezien de state machine dan al erin zit, maar met bijvoorbeeld een timer of GPIO heb ik zelf eigenlijk nog weinig nut gezien in die drivers. Vooral omdat je toch nog de manual nodig hebt en de header files gigantisch lang zijn. Dan doe ik het net zo snel zelf op register niveau. Overigens een mbed vind ik dan weer wel handig, omdat je daarbij niet meer de reference manual erbij hoeft te pakken.
Overigens, zoveel speciale apparatuur heb je toch niet nodig zonder bootloader? Kan sowieso serieel ingebakken geloof ik ook bij STM.

Dan wat meer over je ontwerp: Hoe ben je op een STM uitgekomen? Omdat je er ervaring mee hebt, of vanwege specifieke voordelen? Kan me bijvoorbeeld voorstellen in dit specifieke geval dat een dual core M0/M4 ook een optie is voor laag energiegebruik (bijvoorbeeld LPC4300).

Dat gezegd, ik heb mijn twijels of een LPC4300 genoeg rekenkracht heeft, laat staan een enkele M3. Extern RAM ga ja volgens mij ook sowieso nodig hebben. Maar ik zie dan nog steeds eigenlijk niet om een M-serie een fatsoenlijk navigatie algorithme op draaien. Ik vermoed dat net als bij een Garmin je er toch op uit komt dat tijdens het fietsen dan slechts zeer beperkte hoeveelheid navigatie kan gedaan worden.

[Reactie gewijzigd op zondag 28 juni 2015 13:40]


Door Tweakers user Anteros, zondag 28 juni 2015 14:22

Sissors schreef op zondag 28 juni 2015 @ 13:38:
Interessant onderwerp, wat random opmerkingen/vragen:

Voor jouw maakt het niet veel uit gezien je toch beide moet maken, maar waarom wordt de bootloader altijd aan het begin gezet? Voordelen die ik zie is dat het onafhankelijk van hoeveelheid flash is, en dat het makkelijker is bij het maken van de bootloader. Echter voor de applicatie is het makkelijker als de bootloader aan het einde staat, dus ik begrijp nooit echt waarom als bijvoorbeeld een STM, Freescale of een NXP een bootloader maakt die niet in ROM staat, die altijd aan het begin van het flash wordt geplaatst. Dan is het makkelijker voor de gebruiker als ze hem aan het einde zetten: Dan heeft je programma geen speciale eisen meer nodig (en door de bootloader de reset vector niet te laten overschrijven en naar de bootloader te laten verwijzen, moet dat prima werken. IIG ik heb voor de grap zoiets een keer met de NMI gemaakt voor Freescale MCUs: Dat was dan wel een simpele seriele bootloader, maar toch. Hij overschreef van de te laden binary simpelweg de NMI handler met zijn eigen adres, en dat werkte prima.
Bedankt voor je reactie. Waarom is het makkelijker voor de applicatie? Ik zie geen uitdaging voor de applicatie om te werken met een boot loader die voor de applicatie staat. De applicatie kan gewoon gebouwd en gelinkt worden zonder problemen. Sterker nog, als de applicatie geen gebruik maakt van een BL API dan hoeft de applicatie helemaal geen weet te hebben van de boot loader. Het enige wat veranderd als je de applicatie bouwt, is het start adres. Verder heeft het ook inderdaad ook de voordelen die jij al noemt: onafhankelijk van de hoeveel flash en een minder complexe memory-layout in de linker-file voor de boot loader.
Sissors schreef op zondag 28 juni 2015 @ 13:38:
Volgende: Word je echt blij van de STM drivers? Volgens mij is het nu iig consistenter geworden, was redelijk irritant wanneer je wat schreef voor peripheral van MCU A, en dat die dan niet werkte voor identiek peripheral op MCU B omdat de drivers verschilde. Terwijl als je gewoon direct registers schreef dat wel voor beide werkte. Freescale heeft wel consistente drivers tussen verschillende MCUs, maar elke keer dat ze het versie nummer 1 ophogen veranderen ze maar meteen functie namen en argumenten.
Ik kan me voorstellen dat bij bijvoorbeeld een I2C het scheelt gezien de state machine dan al erin zit, maar met bijvoorbeeld een timer of GPIO heb ik zelf eigenlijk nog weinig nut gezien in die drivers. Vooral omdat je toch nog de manual nodig hebt en de header files gigantisch lang zijn. Dan doe ik het net zo snel zelf op register niveau. Overigens een mbed vind ik dan weer wel handig, omdat je daarbij niet meer de reference manual erbij hoeft te pakken.
Ik moet eerlijk zeggen dat ik er nog geen problemen mee gehad heb. Ze implementeren de CMSIS library interface van ARM en die is zover ik weet, redelijk stabiel. Nu heb ik, voor wat betreft de M3, alleen gewerkt met de STM32F1xx en STM32F2xx. Wellicht dat het met andere microcontrollers minder makkelijk gaat. Hoe dan ook, ik vind het op zich prima werken.

Een manual over een API interface heb je soms toch wel nodig, ongeacht complexiteit. Goed, de manual kan in code beschrijven staan met b.v. Doxygen, maar af en toe eventjes de manual erop naslaan is iets waar je denk ik niet aan ontkom.

Overigens ben ik geen voorstander om in applicatiecode direct registers aan te spreken. Ik zou dit altijd abstraheren middels macro's/(inline) functies en/of de directe registertoegang zo laag mogelijk in de layers te plaatsen (HAL). Het komt de leesbaarheid en portabiliteit van de code ten goede.
Sissors schreef op zondag 28 juni 2015 @ 13:38:
Overigens, zoveel speciale apparatuur heb je toch niet nodig zonder bootloader? Kan sowieso serieel ingebakken geloof ik ook bij STM.
Zover ik weet niet bij de STM32Fxxx. Zie deze link voor meer informatie. Je heb voor de eerste keer altijd een JTAG/SWD programmer nodig om in ieder geval wat code in FLASH te krijgen. In mijn geval zou dit dan dus de boot loader zijn.
Sissors schreef op zondag 28 juni 2015 @ 13:38:
Dan wat meer over je ontwerp: Hoe ben je op een STM uitgekomen? Omdat je er ervaring mee hebt, of vanwege specifieke voordelen? Kan me bijvoorbeeld voorstellen in dit specifieke geval dat een dual core M0/M4 ook een optie is voor laag energiegebruik (bijvoorbeeld LPC4300).
Eigenlijk heel simpel, ik ken deze processor aardig goed en ik heb er een ontwikkelbord voor liggen. Dit is voldoende om al heel ver te komen. Mocht later blijken dat de M3 op 120MHz niet snel genoeg is of omdat ik FLASH ruimte mis, dan kan ik altijd nog een snellere variant uitzoeken. Daarom is het ook key om eenvoudig porteerbare en leesbare code te schrijven zodat je relatief snel kan switchen van CPU en/of platform.
Sissors schreef op zondag 28 juni 2015 @ 13:38:
Dat gezegd, ik heb mijn twijfels of een LPC4300 genoeg rekenkracht heeft, laat staan een enkele M3. Extern RAM ga ja volgens mij ook sowieso nodig hebben. Maar ik zie dan nog steeds eigenlijk niet om een M-serie een fatsoenlijk navigatie algorithme op draaien. Ik vermoed dat net als bij een Garmin je er toch op uit komt dat tijdens het fietsen dan slechts zeer beperkte hoeveelheid navigatie kan gedaan worden.
Het klopt dat ik extern RAM nodig ga hebben en dat heb ik ook, 1MB (genoeg voor nu). Nogmaals, zodra ik tegen de beperkingen van het bord aan ga lopen, kan ik alsnog verder kijken.

Voor wat betreft de navigatie... je moet het ook niet gaan vergelijken met een autonavigatiesysteem. Geen stembegeleiding, geen fancy 3D stuff, enz. Voor dit doel is dat ook helemaal niet nodig. Sterker nog, fietsers willen begeleiding voor een route die ze vaak zelf uitgestippeld hebben. Ze willen hun statistieken kunnen zien zonder de hele tijd de kaart voor hun neus te hebben. De fietscomputer moet dan op de juiste momenten de fietser laten weten waar en wanneer ze af moeten slaan. Goed, de huidige Garmin mogelijkheden en mijn ideeŽn gaan verder, maar hier komt het op zich wel op neer.

Full blown fancy navigatie is inderdaad niet mogelijk met een M3, M4 en wellicht ook niet op een M7.

[Reactie gewijzigd op zondag 28 juni 2015 14:28]


Door Tweakers user Sissors, zondag 28 juni 2015 15:27

Anteros schreef op zondag 28 juni 2015 @ 14:22:
[...]


Bedankt voor je reactie. Waarom is het makkelijker voor de applicatie? Ik zie geen uitdaging voor de applicatie om te werken met een boot loader die voor de applicatie staat. De applicatie kan gewoon gebouwd en gelinkt worden zonder problemen. Sterker nog, als de applicatie geen gebruik maakt van een BL API dan hoeft de applicatie helemaal geen weet te hebben van de boot loader. Het enige wat veranderd als je de applicatie bouwt, is het start adres. Verder heeft het ook inderdaad ook de voordelen die jij al noemt: onafhankelijk van de hoeveel flash en een minder complexe memory-layout in de linker-file voor de boot loader.
En dus een complexere memory layout in de linker-file van de applicatie lijkt mij. Maar voor jouw situatie ben ik het er verder mee eens, maar in een generieke situatie betekend het dat je wel altijd je programma moet compileren afhankelijk van de bootloader. Terwijl als ik nu bijvoorbeeld een LPC11uXX pak, dan kan ik ťťn en dezelfde binary laden via JTAG, SWD, serial bootloader (uit ROM) en USB bootloader (uit ROM). Zet je er echter een bootloader op aan het begin van zijn flash, dan doet de applicatie binary het niet meer.
Overigens ben ik geen voorstander om in applicatiecode direct registers aan te spreken. Ik zou dit altijd abstraheren middels macro's/(inline) functies en/of de directe registertoegang zo laag mogelijk in de layers te plaatsen (HAL). Het komt de leesbaarheid en portabiliteit van de code ten goede.
Je zal toch alle target-specifieke code moeten herschrijven. Het in macros doen gaat er ook maar vanuit dat je nieuwe target dezelfde opbouw heeft van de peripheral. Je target specifieke code goed gescheiden houden met de niet-target specifieke code is natuurlijk zeker iets wat je moet doen.
[...]


Zover ik weet niet bij de STM32Fxxx. Zie deze link voor meer informatie. Je heb voor de eerste keer altijd een JTAG/SWD programmer nodig om in ieder geval wat code in FLASH te krijgen. In mijn geval zou dit dan dus de boot loader zijn.
Ah my bad, dacht dat STM ook ROM bootloaders had net als NXP.
Voor wat betreft de navigatie... je moet het ook niet gaan vergelijken met een autonavigatiesysteem. Geen stembegeleiding, geen fancy 3D stuff, enz. Voor dit doel is dat ook helemaal niet nodig. Sterker nog, fietsers willen begeleiding voor een route die ze vaak zelf uitgestippeld hebben.
Ik weet ongeveer wat een Garmin doet (heb er zelf geen, maar genoeg in mijn omgeving wel). Maar uit je blog begreep ik juist dat je meer wilde dan dat. En ik vraag me af hoeveel rekenkracht puur de navigatie zelf doet als hij dat moet doen. Al zal het natuurlijk wel zo zijn dat je in principe alleen wil dat hij als je van de route afwijkt, je verteld hoe je terug op de route moet komen, gezien zoals je zegt de fietser waarschijnlijk die route bewust heeft uitgekozen, en niet de kortste route wil.


Edit: Overigens gewoon allemaal uit interesse. Hobbymatig gebruik ik verschillende ARM MCUs, en ik denk dat ik daar best redelijk mee werk, maar dit gaat mijn niveau een stapje te boven :). Ik neem ook aan dat het vooral ook een kwestie gaat zijn van het goed opknippen in stukjes? Maar goed, dan nog steeds een enorm project om in je eentje te doen.

[Reactie gewijzigd op zondag 28 juni 2015 15:33]


Door Tweakers user Anteros, zondag 28 juni 2015 16:12

Sissors schreef op zondag 28 juni 2015 @ 15:27:
[...]

En dus een complexere memory layout in de linker-file van de applicatie lijkt mij. Maar voor jouw situatie ben ik het er verder mee eens, maar in een generieke situatie betekend het dat je wel altijd je programma moet compileren afhankelijk van de bootloader. Terwijl als ik nu bijvoorbeeld een LPC11uXX pak, dan kan ik ťťn en dezelfde binary laden via JTAG, SWD, serial bootloader (uit ROM) en USB bootloader (uit ROM). Zet je er echter een bootloader op aan het begin van zijn flash, dan doet de applicatie binary het niet meer.
Nee, niet een complexere memory layout in de linker-file. Het is dan gewoon een standaard linker-file die geen referenties of zelfs weet heeft van een boot loader. En elke standaard linker-file heeft memory-secties gedefineerd met startadres en lengte.

Wat jij beschrijft in jouw voorbeeld kan nog steeds, incl boot loader zonder speciale behandeling van de applicatie. Je bouwt de applicatie zoals altijd maar je gebruikt een ander offset adres in je linker-file (die heb je normaal overigens ook in de linker-file. Het is eigenlijk gewoon het base-adres veranderen in een ander adres). Alle firmware update mechanismes die ik ken hebben de mogelijkheid om een image te schrijven waar dan ook in het flash geheugen. Je geeft gewoon tijdens het flashen het startadres mee. In plaatst van een adres zonder boot loader, geef je nu een adres mee voor na de boot loader. Je applicatie wordt nu gewoon op het nieuwe adres geschreven zonder verdere rariteiten.

Anyway, hopelijk worden mijn intentie duidelijker in een van de volgende blog-posts.
Sissors schreef op zondag 28 juni 2015 @ 15:27:
[...]

Je zal toch alle target-specifieke code moeten herschrijven. Het in macros doen gaat er ook maar vanuit dat je nieuwe target dezelfde opbouw heeft van de peripheral. Je target specifieke code goed gescheiden houden met de niet-target specifieke code is natuurlijk zeker iets wat je moet doen.
Klopt, je zal die inderdaad moeten herschrijven. Maar het is een stuk eenvoudiger en leesbaarder om die code op 1 plek te wijzigen, dan heel je applicatie te doorzoeken naar target-specifieke-code. Vandaar mijn vorige opmerking.
Sissors schreef op zondag 28 juni 2015 @ 15:27:
[...]

Ik weet ongeveer wat een Garmin doet (heb er zelf geen, maar genoeg in mijn omgeving wel). Maar uit je blog begreep ik juist dat je meer wilde dan dat. En ik vraag me af hoeveel rekenkracht puur de navigatie zelf doet als hij dat moet doen. Al zal het natuurlijk wel zo zijn dat je in principe alleen wil dat hij als je van de route afwijkt, je verteld hoe je terug op de route moet komen, gezien zoals je zegt de fietser waarschijnlijk die route bewust heeft uitgekozen, en niet de kortste route wil.
Ik wil ook wel meer dan dat, maar de basis is niet echt veel anders. Tegen de tijd dat ik me met dat punt bezig ga houden dan kan je waarschijnlijk wel het een en ander lezen in een blog-post. Het doel is niet het navigeren, het doel is een GPS fietscomputer te ontwikkelen die op professioneel niveau gebruikt kan worden en tevens mensen aanzet/stimuleert om te (gaan) sporten.
Sissors schreef op zondag 28 juni 2015 @ 15:27:
Edit: Overigens gewoon allemaal uit interesse. Hobbymatig gebruik ik verschillende ARM MCUs, en ik denk dat ik daar best redelijk mee werk, maar dit gaat mijn niveau een stapje te boven :). Ik neem ook aan dat het vooral ook een kwestie gaat zijn van het goed opknippen in stukjes? Maar goed, dan nog steeds een enorm project om in je eentje te doen.
Ik ben blij met je interesse :) Het hele boot loader / applicatie verhaal is simpel. Zoiets zit relatief snel in elkaar. Het meeste werk gaat zitten in het maken van een goede architectuur. Een architectuur die voorziet in uitbreiding, code re-use, portabiliteit, leesbaarheid maar ook rekening houdt met de performance requirements en beperkingen van het platform. Een leuke uitdaging en wellicht ga ik het een en ander wel beschrijven in een blog-post.

Door Tweakers user i-chat, maandag 29 juni 2015 07:04

toch vraag ik me af, waarom wifi als je an BLE wilt, zijn er geen 'goedkope' ble-only chips die (veel zuiniger) beter zijn dan hybride wifi chips. als je naast BLE nog steeds extern wilt comuniceren kun je volgens mij beter een 2g slot erin steken, al lijkt het me effcienter om gewoon je gsm als hub te gebruiken, bijna elke mobiel kan dat al standaard, dus waarom extra logica en drivers. waar je die ook achterwegen kunt laten.

verder lijkt het me een leuk concept en ik ben erg benieuwd waar je bijv je kaart en eventueel navigatie-data wilt gaan betrekken? google, osm, ?

Door Tweakers user Anteros, maandag 29 juni 2015 07:48

@i-chat: BLE is nodig voor zowel de BLE sensoren - denk dan aan b.v. cadans-sensor, hartslagsensor, snelheidssensor, enz - als om tijdens het fietsen met een telefoon te communiceren. WiFi is 'nodig' om thuis de fietscomputer te syncen met een backend via het WiFi-netwerk en om via een PC de fietscomputer te configureren. Uiteraard zou dit ook kunnen met een telefoon, maar WiFi maakt het gebruiksvriendelijker. Een 2G slot lijkt me helemaal niet handig, o.a. door de relatief grote sim-kaart en radio. Overigens zou ik eerst in mijn prototype BLE kunnen implementeren om later pas WiFi toe te voegen.

De kaarten ga ik betrekken van OSM. Ik heb een Python-script geschreven wat de rauwe OSM XML-data omzet naar een sqlite3 database. Deze database kan dan weer gelezen worden door de GPS fietscomputer.

Door burne, maandag 29 juni 2015 21:01

Ik klikte van de week een beetje rond bij Conrad (die zijn geconradicaliseerd ofzo) en ik struikelde daar over een e-ink display. Voor mijn toepassing is het niets, maar het lijkt me ideaal voor een fietscomputer. Mijn grootste ergernis aan m'n Edge 705 is de matige afleesbaarheid van het scherm. Zeker in wisselend licht (door een bos) is er vaak niets mee te beginnen.

Overigens gaat navigeren heel aardig als je enkel je route wilt bewaken als je de Open Cycle Map installeert. Dat is een OSM afgeleide.

Door Tweakers user Jogai, dinsdag 30 juni 2015 08:18

En heb je gedacht aan de mogelijkheid om nieuwe software voor je garmin device te maken?

Door Tweakers user Anteros, dinsdag 30 juni 2015 08:54

@burne: Ik heb ook wel eens nagedacht over e-ink omdat ik hetzelfde ervaar als jij: een relatief slecht afleesbaar scherm. Nadeel is dat het scherm traag is met updaten en geen kleur weer kan geven. Hoe dan ook, t.z.t ga ik er zeker naar kijken. Bedankt voor je suggestie.

@Jogai: Ik heb inderdaad wel eens gespeeld met de gedachte om zelf firmware te schrijven voor de Garmin. Het probleem is dat ik dan de hardware en (deels de) software moet reverse engineeren. Mede daarom heb ik ervoor gekozen om zelf de hardware en software te ontwikkelen.

Door Tweakers user i-chat, dinsdag 30 juni 2015 09:29

Anteros schreef op maandag 29 juni 2015 @ 07:48:
@i-chat: BLE is nodig voor zowel de BLE sensoren - denk dan aan b.v. cadans-sensor, hartslagsensor, snelheidssensor, enz - als om tijdens het fietsen met een telefoon te communiceren. WiFi is 'nodig' om thuis de fietscomputer te syncen met een backend via het WiFi-netwerk en om via een PC de fietscomputer te configureren. Uiteraard zou dit ook kunnen met een telefoon, maar WiFi maakt het gebruiksvriendelijker. Een 2G slot lijkt me helemaal niet handig, o.a. door de relatief grote sim-kaart en radio. Overigens zou ik eerst in mijn prototype BLE kunnen implementeren om later pas WiFi toe te voegen.

De kaarten ga ik betrekken van OSM. Ik heb een Python-script geschreven wat de rauwe OSM XML-data omzet naar een sqlite3 database. Deze database kan dan weer gelezen worden door de GPS fietscomputer.
dat je BLE nodig hebt dat begreep ik al maar misschien heb ik dat verkeerd verwoord, het hele punt was nu juist dat ik het nut van wifi niet echt snap, want daar geld toch min of meer het zelfde voor als voor 2g, het maakt zaken complexer, voor 2g vind ik dan nog iets te zeggen hebben dat je oa zonder tussenkomst van mobiel toch nog berichtjes kunt ontvangen of hulpdiensten kunt bereiken, dat wat je zegt over wifi en thuis updates installeren of routes inprogrameren, dat kan ook prima via BT, en dan is (desgewenst een 20ct bt stickje meeleveren) makkelijker dan het hele ding wifi-compatible maken bovendien als ik zoiets zou doen via wifi dan via wifi direct (dus buiten het normale verkeer via de AP om, maar dat is zelden wenselijk bij pc die wifi gebruiken,

Door Tweakers user Sissors, dinsdag 30 juni 2015 13:20

Ik zie bij dat e-ink display geen enige vorm van documentatie/datasheet.

Zelf heb ik deze: http://www.embeddedartist...isplays/lcd_27_epaper.php. En dan moet je rekening ermee houden dat die nog significant trager is dan het scherm van een moderne e-reader, waarbij ik ook mijn twijfels heb over nut voor navigatie. Hij heeft een paar seconde nodig voor een volledige update, inclusief de inverted stadia om ghosting te voorkomen. Je kan dat in principe overslaan (hebben ze verder niet gedocumenteerd, werkt wel), en dan kan hij afhankelijk van de temperatuur in 0.5-1 seconde updaten, maar dan heb je wel meer ghosting: Dat wil je dus ook niet continue doen.

Ik heb hem zelf gebruikt in een temperatuur monitor opstelling, en die update eens per 5 minuten, dus dan maakt de traagheid weinig uit. En is wel grappig dat als je het scherm loskoppelt hij gewoon zijn staat behoudt. Maar voor navigatie zie ik dat dus echt niet werken. Zelfs als je snelheden hebt van een modern EInk scherm.

Door Tweakers user golfdiesel, dinsdag 30 juni 2015 14:51

Mooi project! Ik heb zelf meerdere Garmin apparaten en ik deel je frustratie over de omgang met problemen.
Als je een overduidelijk softwareprobleem meld dan krijg je als antwoord dat het toestel omgeruild moet worden. Pas nadat het toestel 1 of 2x omgeruild is willen ze een probleem doorgeven aan de software afdeling.
Het zijn over het algemeen hele fijne apparaten maar er zijn helaas wat tekortkomingen.

Ik hoop wel dat je ook goed naar de batterijlevensduur gaat kijken, ik heb een Garmin GPSMap 62st en die doet het bijna 20 uur op 2 AA batterijen.

Reageren is niet meer mogelijk