Hardveres nyomkövetés és Semihosting 

Az alábbiakban

Mi a semihosting?

A Semihosting egy olyan mechanizmus, ami lehetővé teszi, hogy az ARM céláramkörön futó alkalmazói program ki- és beviteli kérelmei a  hardveres nyomkövetővel kapcsolatban álló hoszt számítógépen érvényesüljenek. Ez a mechanizmus lehetővé teszi többek között azt is, hogy  a céláramkörön futó programban a C könyvtári függvények (mint például a printf() és scanf() függvények) a hoszt számítógép billentyűzetét és képernyőjét használják.  Ez különösen hasznos olyan esetekben, amikor a korlátozott kiépítésű hardver nem rendelkezik a kommunikációhoz szükséges perifériákkal. A semihosting mechanizmus viszont lehetővé teszi, hogy a hoszt perifériáit használja.

A hosting befogadást, vendéglátást jelent. A semihosting, ahogy a név is jelzi, csak "félmegoldás", azaz olyasmi, mint a félpanziós ellátás.  A céláramkör használhatja a hoszt számítógép perifériáit, de ez a használat meglehetősen korlátozott és csak a hardveres nyomkövetés idejére korlátozódik.

A semihosting mechanizmus a Szoftveres Interrupt (SWI) definiált műveletei formájában van megvalósítva: az alkalmazás kiad egy SWI megszakítást, a nyomkövető eszköz pedig lekezeli a megszakítást. A nyomkövető eszköz biztosítja a kommunikációt a hoszt számítógéppel.



A semihosting  működésének vázlata
(a kép forrása: infocenter.arm.com)

A legtöbb esetben az SWI megszakításokat közvetett módon, könyvtári függvények keltik. Arra is van azonban lehetőség, hogy a az alkalmazás közvetlenül keltsen SWI megszakítást. 


Egyszerű példa a semihosting használatára


A 03_Semihosting projekt egy egyszerű mintapélda a semihosting használatára. Ehhez az előzőekben bemutatott 02_Blinky projektet egészítettük ki a semihosting használatához szükséges sorokkal. A semihosting mechanizmust használó projektünk létrehozásakor és konfigurálásakor az alábbi műveletekkel bővült az előző oldalakon ismertetett projekt létrehozási tevékenység sor:

1. A Repository ablak Peripherals fülére kattintva jelöljük ki (pipa) a COMMON szekcióból a semihosting komponenst! Ez valószínűleg magával vonja (ha nem, akkor kézzel jelöljük be!) a Retarget printf és a C Library komponenseket is. (Fentiek mellett ne felejtsük el bejelölni a GPIO komponenst is!)




2. Egészítsük ki a programot nyomkövetést segítő kiírásokkal (SH_Sendstring(), vagy printf() függvényekkel), valamint a főprogramba csatoljuk be a semihosting.h és stdio.h fejléc állományokat! Az utóbbira csak akkor van szükség, ha a printf() vagy scanf() könyvtári függvényeket használjuk.

Az alábbi listán látható a main.c állomány listája. A jobb áttekinthetőség érdekében az újonnan betoldott programsorokat három csillaggal (***) megjelöltük.

1. lista: A 03_Semihosting projekt main.c állományának listája
// 03_Semihosting:
// Semihosting example. This is the old 02_Blinky program
// extended by semihosted output messaging.
//
#include "NUC1xx.h"
#include "Driver\DrvGPIO.h"
#include "Driver\DrvSYS.h"
#include "semihosting.h" //*** SH_xxx function declarations
#include "stdio.h" //*** Needed for printf (optional)

int main (void)
{
UNLOCKREG(); // unlock register for programming
DrvSYS_Open(48000000); // set System Clock to run at 48MHz
LOCKREG(); // lock register from programming
SH_SendString("Start up the system\n"); //*** Debug message through semihosting
DrvGPIO_Open(E_GPA, 10, E_IO_OUTPUT); // GPA10 pin set to output mode
DrvGPIO_SetBit(E_GPA, 10); // GPA10 pin output Hi to turn off LED

while (1) // forever loop to keep flashing LED
{
DrvGPIO_ClrBit(E_GPA, 10); // output Low to turn on LED
printf("LED is on..."); //*** Debug message
DrvSYS_Delay(250000); // 250 ms delay
DrvGPIO_SetBit(E_GPA, 10); // output Hi to turn off LED
printf(" ...LED is off\r\n"); //*** Debug message
DrvSYS_Delay(250000); // 250 ms delay
}
}

A főprogramba beiktatott új programsorok szerepe:

3. A projektbe automatikusan felvett printf.c állományba is csatoljuk be a semihosting.h fejléc állományt, emellett definiáljuk felül a PrintChar() függvényt így:
void PrintChar(char c)
{
SH_SendChar(c); //semihosting is used!!!
}
Végeredményben a printf.c állomány eleje úgy nézzen ki, ahogy az az alábbi ábrán látható!


4. Kattintsunk a Configuration gombra (vagy a View menüben nyissuk meg a Configuration ablakot), s a Link lapon a Library feliratnál a legördülő listából a Semihosting opciót válasszuk ki!

 
5. A Configuration ablakban maradva válasszuk ki a Debugger lapot, s itt tegyünk pipát a Semihosting enable felirat elé! Nem szükséges, de a kommunikáció gyorsítása érdekében megnövelhetjük az átvitel alapértelmezett órajelét is (NuLink-Me esetén 2 MHz a maximális frekvencia).


6. Fordítsuk le (vagy újra) a programot, majd a kis zöld bogárkára kattintva indítsuk el a programletöltést és a hardveres nyomkövetést! A nyomkövetés elindítása után a CoIDE jobb alsó sarkában megjelenik egy Semihosting nevű ablak, amelyben a program futása során - kissé darabosan ugyan - de sorra megjelennek a kiírások. Akkor történik kiírás, amikor a néhány karakteres buffer megtelik...