### Link1| Link2| Link3 »

# Ismerkedés a NuTiny-SDK-NUC140
fejlesztői modullal

# 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:

- 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!

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...