RobotLib HAL

Uit RobotMC.be
Ga naar: navigatie, zoeken

Zie deze pagina voor een overzicht van alle RobotLib documentatie op deze wiki.

Hardware Abstraction Layer

De hardware abstraction layer van RobotLib zorgt voor een gelijke 'ondergrond' op verschillende processoren. Hierdoor kan RobotLib ongewijzigd draaien op verschillende processoren en kunnen ook robot toepassingen zonder aanpassingen worden overgezet. De HAL bestaat uit een verplicht (mandatory) en een optioneel deel.

Mandatory HAL

Dit zijn de functies die noodzakelijk zijn voor de RobotLib core om te functioneren en omvat:

  • link- en startup files.
  • HalCoreInit functie, die alle verplichte funties initialiseert:
    • een seriele verbinding
    • een periodieke interrupt (systick)
    • een microseconde-counter
  • GetUsCounter functie om de microseconde counter uit te lezen
  • MotorInit,MotorPwm en EncoderRead functies

Optional HAL

Dit zijn functies die vaak gebruikt worden, maar niet in iedere robot. De HAL beschrijft de manier waarop deze functies worden aangeroepen (de API). Bijvoorbeeld de HAL_i2c functies zijn:

  • void I2cInit()
  • int I2cSendReceive(int I2cSlaveAddress, int TxCount, int RxCount, char *TxBuffer, char *RxBuffer)

Deze functies worden door optionele RobotLib functies gebruikt (zoals TextLcd, waarmee een LCD scherm via i2c wordt aangestuurd) en kunnen ook in de toepassing worden gebruikt. Dit deel van de HAL wordt nog uitgebreid. Zo wordt binnenkort de API voor AnaloogDigitaalConvertors toegevoegd, en wellicht op termijn een API voor een gyroscoop, accelerometer en electronisch compas.

Een HAL maken voor een nieuwe processor

Wat nodig is om een HAL toe te voegen voor een nieuwe processor, hangt af van het startpunt en de kenmerken van de processor en zal daarom steeds verschillend zijn. Hieronder is een aantal MileStones (mijlpalen) beschreven die houvast geven bij het toevoegen van HAL voor een nieuwe processor.

MileStone 1

De eerste milestone is het knipperen van een LED.

Hiervoor is het volgende nodig:

  • Compileren van de source code met behulp van de RobotLib scripts (.do files).
  • Linken van de objecten met behulp van de RobotLib scripts (.do files) en linker files (.ld).
  • Correct werkende opstart-code voor de processor

Let op: het is handig om tijdens de integratie van een nieuwe HAL makefile.do aan te passen zodat niet alle robotlib files worden meegelinkt. dit kan met het toevoegen van een # voor het betreffende addlist commando

# addlist(robotlib_files)  

Enkele robotlib files zijn wel nodig bij de integratie. Deze worden (stap voor stap) toegevoegd in de sectie 'createlist(project)'

createlist(project) {     
   main.cpp   
   Prj_Hal_motors.cpp   
   Prj_Stubs_Globals.cpp   

   # We hebben enkele robotlib files nodig...
   "($RL_path)format_write.cpp"                   # printf()
   "($RL_path)Hal_System.cpp"                     # SystemTest(0) functie 
   "($RL_path)Utilities.cpp"                      # diversen
   "($RL_path)Queue.cpp"                          # voor gebufferde serial communicatie
}

MileStone 2

De tweede milestone is seriele communicatie, waardoor zichtbaar wordt wat er gebeurt.

Hiervoor zijn uart routines nodig. Kies bij voorkeur voor routines die werken op basis van polling, omdat:

  • Polling routines eenvoudiger zijn, waardoor de kans op fouten minder is.
  • Polling de extra complexiteit van interrupt afhandeling door de processor nog even uitstelt.
  • Polling routines informatie direct doorgeven. Dit is met name relevant zolang we nog bezig zijn met de configuratie van de processor, waarbij deze vast kan lopen.

In Milestone 4 worden deze routines uitgebreid met routines op interrupt basis.

MileStone 3

Milestone 3 zijn werkende systeem- en HAL core functies. De functie SystemTest(0) is hiervoor het belangrijkste test-instrument.

  • systeemfuncties testen (constructors, floats, initialisatie van variabelen)
  • MicroSeconde klok
  • Miliseconde interrupt
  • malloc()

MileStone 4

Milestone 4 maakt de basis af met gebufferde (queued) seriele communicatie. Dit heeft als grote voordeel dat het printen van tekst zo goed als geen vertraging geeft voor de uitvoering van de robotbesturing, zolang de seriele poort niet wordt verzadigd.

Als deze stap is afgerond, kunnen alle robotlib files weer worden toegevoegd door in makefile.do # weg te halen voor

  addlist(robotlib_files)   

Bij het compileren worden nu wellicht meldingen gegeven van ontbrekende definities. Dit zijn normaal definities die in 'Prj_RobotLib_conf.h' worden opgenomen.

Vervolg

Er ligt nu een goede basis om op voort de bouwen. De volgende stap is uitbreiden van de HAL met 'robot' specifieke zaken. Het aansturen van de motoren en het uitlezen van de encoders is een mandatory ('verplicht') deel van de HAL. De HAL definieert de Application Programmer Interface of API. De API beschrijft de namen, parameters en gedrag van de functies die hiervoor worden gebruikt.

De routines (voor de motorensturing en encoders) zelf zijn geen onderdeel van de HAL. Het zijn Prj_ files, die de gebruiker kan aanpassen aan zijn specifieke robot, zonder dat de HAL daarbij aangepast hoeft te worden of onnodige beperkingen geeft. Bij een HAL hoort wel een een werkend voorbeeld van deze routines, zodat de gebruiker een goede basis hebben om mee te starten.

Daarnaast bevat de HAL de API voor veel gebruikte peripherhals, zoals I2C, ADC, Servo-PWM. Veelal zijn deze API functies aangepaste voorbeeldprogramma's van de processor fabrikant.

Checklist:

  • buzzer
  • rc5
  • lcd
  • motor pwm
  • motor encoders

Motor

Implementeer de functies PrjMotorInit() en PrjMotorPwm() (in Prj_Hal_Motors.cpp).

Voeg de volgende aanroepen toe aan main() (op je juiste plaats, zie voorbeelden van main):

PrjMotorInit();
 
Mover.Takt();              // UniversalMover
  
CliTakt(STDIN_GETCHAR());  // drive command line interface  

Met een terminal programma en seriele verbinding krijg je toegang tot de CommandLineInterface. Hierin zijn diverse commandos beschikbaar ter ondersteuning van de integratie.

  • Gebruik het CLI commando 'umpwm <l> <r>' om de pwm waarde in te stellen voor testen.
  • Indien umpwm niet direct beschikbaar is, kan het worden toegevoegd met het commando 'addtests'.
  • Debug 'klasses' kunnen worden ingeschakeld en uitgeschakeld met resp. 'dset <n>' en 'dclr <n>'.
  • dset 11 (DebugSet 11) toont de aanroep van PrjMotorPwm() met de gebruikte parameters.
  • controleer of de pwm puls op de gewenste pinnen komt.
  • controleer of GPIO pinnen voor vooruit/achteruit goed werken. Gebruik hiervoor de testwaarden 1 en -1. Het niveau van de GPIO pin bij PWM 0 is ongedefinieerd (kan hoog of laag zijn; de pin is niet zwevend en zal niet van niveau veranderen).

Encoders

Implementeer de functie PrjEncoderRead() (in Prj_Hal_Motors.cpp). De initialisatie van de Encoders wordt toegevoegd aan PrjMotorInit().

Voeg de volgende aanroepen toe aan main():

OdoTakt();              // read encoders & process result
  • dlevel 7 1 / Debug.SetLevel(7, DBG_WARN); toont het resultaat van de aanroep van PrjEncoderRead(); en de invloed van de encoder op de positie worden getoond. Deze routine print alleen informatie als de robot (1 van de wielen) beweegt.

RC5

Implementeer de functies Rc5PinInit() en Rc5PinGet() (in Hal_GPIO.cpp).

Voeg de volgende aanroepen toe aan main():

  Rc5PinInit();  // HAL interface part
  Rc5Init();     // RobotLib function

  RcDispatchTakt();          // handle chars from Remote Control
  • dlevel 1 3 / Debug.SetLevel(1, DBG_DEBUG); - print '^' bij flank op Rc5PinGet()
  • dlevel 1 2 / Debug.SetLevel(1, DBG_INFO); - print ontvangen karakters van de RC5 afstandsbediening.

(todo: configuratie van toetsen)

I2C