Hardveres nyomkövetés és Semihosting
Az alábbiakbanMi 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 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:
- A semihosting.h fejléc állomány deklarálja a semihosting műveleteket megvalósító SH_xxx függvényeket.
- Az stdio.h állomány becsatolására akkor van szükség, ha a printf() vagy scanf() könyvtári függvényeket akarjuk használni.
- Az SH_Sendstring() függvénnyel egy karakterfüzért írathatunk ki a hoszt gép képernyőjére.
- Alternatív módon, a printf() függvénnyel is végezhetünk kiíratásokat. Ekkor ne felejtkezzünk meg az stdio.h fejléc állomány becsatolásáról!
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...
