KINGx - Das inoffizielle PlayStation Forum & News Portal
[TuT] Hello World in C - Druckversion

+- KINGx - Das inoffizielle PlayStation Forum & News Portal (http://www.kingx.de/forum)
+-- Forum:    PS Vita / PSP (/forumdisplay.php?fid=1)
+--- Forum: Homebrew (/forumdisplay.php?fid=8)
+---- Forum: Development (/forumdisplay.php?fid=34)
+----- Forum: Dev-Tutorials (/forumdisplay.php?fid=59)
+----- Thema: [TuT] Hello World in C (/showthread.php?tid=28302)


[TuT] Hello World in C - Unbekannt - 06.12.2010 20:18

Vorwort
In diesem Tutorial zeige ich euch, wie ihr ein einfaches Hello World programmiert. Wer hilfe zu einzelnen Befehlen braucht, frägt mich hier im Thread, aber einige Grundbegriffe wurden hier erklärt.

_____________________________________________________

Konditionen:
Für das Tutorial wird benötigt:

_____________________________________________________

Los gehts!



Nun fanfen wir an, die Header-Files einzufügen. Ohne die Header-File Dateien können die Befehle wie Printf nicht erkannt werden.

PHP-Code:
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspcallbacks.h> 


Das #include bedeutet, dass eine Datei "inkludiert" bzw. eingebunden wird. Die zwichen dem größer/kleiner-Zeichen stehenden Dateien befinden sich in der SDK.

Nun definieren wir den Befehl "pspDebugScreenPrintf" zu "Printf":

PHP-Code:
#define printf pspDebugScreenPrintf 


pspDebugScreenPrintf ist die Funktion, die wir verwenden, um Text auszugeben.

Nun fügen wir die Module_Info hinzu, dort wo Hello World steht kann auch jeder beliebige Namen stehen, es ist also der Programm-Name.

PHP-Code:
PSP_MODULE_INFO("Hello World",0,1,1); 


Danach deklarieren wir main() mit int.

PHP-Code:
int main() 


Int bedeutet INTEGER und deutsch: "ganze Zahl".

Nun schreiben wir eine Anweisung die zwichen den Klammern steht

PHP-Code:
int main() {
Anweisung


also

PHP-Code:
pspDebugScreenInit();
    
pspDebugScreenClear();
    
SetupCallbacks(); 


Erklärung.

pspDebugScreenInit() ist die Funktion die es erlaubt auf dem Bildschirm etwas "auszugeben". pspDebugScreenClear() bereinigt den Bildschirm. Und SetupCallbacks() erlaubt es uns die Home-Taste zu verwenden (ein Callback).

Nun kommen wir zu der Tat, wir möchten Hello World auf dem Display ausgeben:

PHP-Code:
printf("Hello World\n");
sceKernelSleepThread(); 


printf() "druckt" der in den Klammern stehenden Text. Das \n ist ein Escape-Code und macht einen Zeilenumbruch nach "Hello World".

Nun schreiben wir return 0 um das Programm abzuschließen:

PHP-Code:
return 0


Jetzt haben wir schon alles gemacht, schreiben eine zu-geschweifte Klammer (}) und es fehlt nur noch eine Makefile:

PHP-Code:
TARGET helloworld
OBJS 
main.o
 
CFLAGS 
= -O2 -G0 -Wall
CXXFLAGS 
= $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS 
= $(CFLAGS)
 
EXTRA_TARGETS EBOOT.PBP
PSP_EBOOT_TITLE 
Hello World
 
PSPSDK
=$(shell psp-config --pspsdk-path)
include $(
PSPSDK)/lib/build.mak 


Ganzer Script:

Spoiler: (anzeigen)
Nun müsste das Hello World funktionieren, kann sein dass ich einpaar Fehler habe, kann sie nicht verbessern, ich habe keine PSP mehr Sad.

Umlaute in C

Auch in C gibt es Umlaute. Umlaute werden als Sonderzeichen gewertet und können über Hexadezimal geschrieben werden.

ä : \x84
ö : \x94
ü : \x81
Ä : \x8E
Ö : \x99
Ü : \x9A
ß : \xE1

Beispiel:

PHP-Code:
//Äußerung
 
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspcallbacks.h>
 
#define printf pspDebugScreenPrintf
 
PSP_MODULE_INFO("aeusserung",0,1,1);
 
int main() {
    
pspDebugScreenInit();
    
pspDebugScreenClear();
    
SetupCallbacks();
    
printf("Dies ist eine \x84u\xE1erung...\n");
    
sceKernelSleepThread();
    return 
0;


Ausgabe: Dies ist eine Äußerung...


RE: [TuT] Hello World in C - dark-awesome - 06.12.2010 20:40

Also so müsste er aussehen:


PHP-Code:
#include <pspkernel.h>
#include <pspdebug.h>

#define printf pspDebugScreenPrintf

/* Define the module info section */
PSP_MODULE_INFO("Hallo Welt"011);

/* Define the main thread's attribute value (optional) */
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER THREAD_ATTR_VFPU);

int main(int argcchar *argv[])
{
    
pspDebugScreenInit();

    
pspDebugScreenPrintf("Hello World\n");

    return 
0;




RE: [TuT] Hello World in C - Unbekannt - 06.12.2010 20:42

stehn :
Also so müsste er aussehen:


PHP-Code:
/*
 * PSP Software Development Kit - http://www.pspdev.org
 * -----------------------------------------------------------------------
 * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
 *
 * main.c - Basic ELF template
 *
 * Copyright (c) 2005 Marcus R. Brown <mrbrown@ocgnet.org>
 * Copyright (c) 2005 James Forshaw <tyranid@gmail.com>
 * Copyright (c) 2005 John Kelley <ps2dev@kelley.ca>
 *
 * $Id: main.c 1888 2006-05-01 08:47:04Z tyranid $
 * $HeadURL$
 */
#include <pspkernel.h>
#include <pspdebug.h>

#define printf pspDebugScreenPrintf

/* Define the module info section */
PSP_MODULE_INFO("Hallo Welt"011);

/* Define the main thread's attribute value (optional) */
PSP_MAIN_THREAD_ATTR(THREAD_ATTR_USER THREAD_ATTR_VFPU);

int main(int argcchar *argv[])
{
    
pspDebugScreenInit();

    
pspDebugScreenPrintf("Hello World\n");

    return 
0;

Den hast du aus dem DevKit kopiert. Meiner sieht etwas anderster aus.

Back to Topic:

Habe den ganzen Code hinzugefügt.


RE: [TuT] Hello World in C - dark-awesome - 06.12.2010 20:43

Na weil du dir nicht sicher warst ob der richtig ist Smile


RE: [TuT] Hello World in C - Unbekannt - 06.12.2010 20:47

Hast du es getestet? Müsste theoretisch klappen.


RE: [TuT] Hello World in C - PSP_Joker - 06.12.2010 20:48

Also da ich nicht für PSP coden kann, weiß ich nicht in wie fern der Code stimmt, aber die Erklärungen dazu sind mal wieder nicht ganz das wahre.

Überprüf mal was du zu den Klammern und zu return geschrieben hast. Das andere hab ich schon nicht mehr genauer gelesen.


RE: [TuT] Hello World in C - dark-awesome - 06.12.2010 20:51

Also meiner muss gehen aber deinen Unbekannt werde ich jetzt mal testen.


RE: [TuT] Hello World in C - Unbekannt - 06.12.2010 20:54

PSP_Joker :
Also da ich nicht für PSP coden kann, weiß ich nicht in wie fern der Code stimmt, aber die Erklärungen dazu sind mal wieder nicht ganz das wahre.

Überprüf mal was du zu den Klammern und zu return geschrieben hast. Das andere hab ich schon nicht mehr genauer gelesen.


Also habs nochmal überprüft. Habe es umständlich erklärt.

int main() {
Anweisung
}

Das mit Callbacks habe ich glaube falsch. Muss nochmal nach schauen.


RE: [TuT] Hello World in C - dark-awesome - 06.12.2010 21:25

Also er lässt sich nicht zu EBOOT machen Scriptfehler also Unbekannt nochmal nachschauen Smile


RE: [TuT] Hello World in C - Unbekannt - 06.12.2010 21:28

Probiermal anstatt printf, pspDebugScreenPrintf. Am besten schreibst du hier den Fehler rein.


RE: [TuT] Hello World in C - dark-awesome - 06.12.2010 21:46

es liegt an SetupCallbacks(); irgendwas scheint da zu fehlen.


RE: [TuT] Hello World in C - Unbekannt - 06.12.2010 21:58

Meinst du diesen Fehler?:



Das liegt daran, dass er die pspcallbacks.h nicht findet, man muss es so einstellen dass die Header-Daten mitcompiliert werden.


RE: [TuT] Hello World in C - dark-awesome - 06.12.2010 22:05

So sollte er aussehen aber er findet die callback Header datei nicht.

PHP-Code:
//Hello World

/* Dies sind die einzellnen includes ohne die würde garn nichts gehen */
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspcallbacks.h>

PSP_MODULE_INFO("Hello World",0,1,1);
 
#define printf pspDebugScreenPrintf

/* Exit callback */
int exit_callback(int arg1int arg2void *common) {
sceKernelExitGame();
return 
0;
}

/* Callback thread */
int CallbackThread(SceSize argsvoid *argp) {
int cbid;

cbid sceKernelCreateCallback("Exit Callback"exit_callbackNULL);
sceKernelRegisterExitCallback(cbid);

sceKernelSleepThreadCB();

return 
0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
int thid 0;

thid sceKernelCreateThread("update_thread"CallbackThread0x110xFA000);
if(
thid >= 0) {
sceKernelStartThread(thid00);
}

return 
thid;
}

/* int main() { sagt den Compiler da hier das Haupt Programm beginnt */
int main() {
    
pspDebugScreenInit();
    
pspDebugScreenClear();
    
SetupCallbacks();
  
    
/* Dies ist der Text der Ausgegeben wird und ( \n ) steht
    dabei für New Line also neu Zeile */
    
pspDebugScreenPrintf("Hello World\n");
    
sceKernelSleepThread();
    
    
/* return 0; und } stehen hier für das Ende des Hauptprogrammes */
    
return 0;




RE: [TuT] Hello World in C - Unbekannt - 06.12.2010 22:15

Du brauchst die pspcallbacks.h, ich habe sie vergessen oben hinzuzufügen als Download.


RE: [TuT] Hello World in C - Unbekannt - 06.12.2010 23:52

"Unerlaubtes Pushen" *Tschuldigung*

Hat es jemand ausprobiert, funktioniert es endlich?


RE: [TuT] Hello World in C - dark-awesome - 07.12.2010 00:25

So wenn du mir jetzt noch sagst wo die hin muss dann gerne ich mache das ja mit PSPDEV und da gibt es so viele Ordner.
Habs geschaft.

Hier nochmal ein Code mit noch ein Paar erklärungen:

PHP-Code:
//Hello World

/* Dies sind die einzellnen includes ohne die würde garn nichts gehen */
#include <pspkernel.h>
#include <pspdebug.h>
#include <pspcallbacks.h>

 
#define printf pspDebugScreenPrintf

PSP_MODULE_INFO("Hello World",0,1,1);

/* int main() { sagt den Compiler da hier das Haupt Programm beginnt */
int main() {
    
pspDebugScreenInit();
    
pspDebugScreenClear();
    
SetupCallbacks();
  
    
/* Dies ist der Text der Ausgegeben wird und ( \n ) steht
    dabei für New Line also neu Zeile */
    
pspDebugScreenPrintf("Hello World\n");
    
sceKernelSleepThread();
    
    
/* return 0; steht dafür das der Code abgeschlossen wird und } steht für hier ist das Ende des Hauptprogrammes */
    
return 0;




RE: [TuT] Hello World in C - Unbekannt - 07.12.2010 01:01

return 0; steht nicht für das Ende des Hauptprogramm, es steht primiär dafür, das der Code abgeschloßen wird.

int main() ist sowas wie eine Einleitung des Codes.


RE: [TuT] Hello World in C - dark-awesome - 07.12.2010 01:04

Unbekannt :
return 0; steht nicht für das Ende des Hauptprogramm, es steht primiär dafür, das der Code abgeschloßen wird.

int main() ist sowas wie eine Einleitung des Codes.


Ja das meine ich (ich geb zu das es verwirren kann ich werde es um ändern)

PS: und int main() sagt dem Compiler das hier das Hauptprogramm beginn hab ich erst letztens in einen Buch gelesen.


RE: [TuT] Hello World in C - Unbekannt - 07.12.2010 01:18

main() ist damit gemeint, dass es sich um das Hauptprogramm handelt "main.c".
Wie ich gesagt habe int main() ist eine Einleitung.


RE: [TuT] Hello World in C - dark-awesome - 07.12.2010 01:21

So kann man das auch sagen aber im Endeffekt ist es das gleiche.


RE: [TuT] Hello World in C - knopper - 07.12.2010 11:03

Gibt's eigentlich auch Umlaute für die Ausgabe mit 'printTextScreen' im Graphic-Modus???


RE: [TuT] Hello World in C - HacKmaN - 07.12.2010 14:22

Unbekannt :
return 0; steht nicht für das Ende des Hauptprogramm, es steht primiär dafür, das der Code abgeschloßen wird.

int main() ist sowas wie eine Einleitung des Codes.


Return 0; steht nicht für Abgeschlossenen Code. Es bedeutet nur dass der Compiler hier diverse Werte wieder vom Stack in die Register zurückschreibt, den Rückgabewert in $v0 schreibt und auf die Rücksprungaddresse springt:

Code:
; die Register wieder zurücksetzten
; z.B. lw $bla, 0xDEADBEEF($sp)

li $v0, 0   ; $v0 = Rückgabewert

; Zurückspringen, wegen dem Branch-Delay-Slot wird die Instruction
; danach auch noch ausgeführt
jr $ra
addiu $sp, $sp, blaaa    ; stack wiederherstellen, wird wegen delay slot ausgeführt


Es wird nur wieder die 2. Instruction nach dem Sprung auf die Funktion wieder aufgerufen.

Also z.B.

Code:
blaaa:
    jr $ra      ; zurückspringen
    li $v0, 0  ; $v0 = 0

module_start:
    subu $sp, $sp, 4  ; platz für einen Integer im Stack schaffen
    sw $ra, 0($sp)     ; Rücksprungaddresse auf dem Stack sichern

    li $v0, 1  ; $v0 = 1
    jal blaaa  ; PC + 8 nach $ra schreiben und springen
    nop        ; no operation, wegen load delay slot
    
    lw $ra, 0($sp)      ; Rücksprungadresse wieder zurücksetzten
    jr $ra                  ; Zur Firmware zurückkehren
    addiu $sp, $sp, 4  ; delay slot, stack wiederherstellen


Die Main ist auf der PSP eigentlich NICHT der Beginn des Hauptprogramms. Der Programmcode auf der PSP startet bei module_start, und wenn das Modul gestoppt wird, wird module_stop ausgeführt. Dass PSPSDK erledigt es allerdings alles für dich, da steht dann im Code etwas der Art

Code:
/* Auf adresse 0xblaaaaaa, deshalb sub_blaaaaaa */
int main(int argc, char *argv[])
{
     // dein Code
};

In Assembler:

sub_blaaaaaa:
    ; dein Code

int module_start(int args, void *argp)
{
     int thid = sceKernelCreateThread("main_thread", 0xblaaaaaa, Priority, Stacksize, 0, NULL);
     if(thid >= 0)
           sceKernelStartThread(thid, args, argp);
    
     return 0;
};

in Assembler:

module_start:
     subu $sp, $sp, 12    ; Platz für $ra, $a0 und $a1 im Stack schaffen
     sw $ra, 0($sp)        ; $ra sichern
     sw $a0, 4($sp)        ; $a0 sichern
     sw $a1, 8($sp)       ; $a1 sichern
    
     li $a0, 0xdeadbeef   ; Die Addresse vom namen-string in $a0 laden
     li $a1, 0xblaaaaaa   ; Adresse der main
     li $a2, Priority         ; logisch

     jal sceKernelCreateThread

     li $a3, Stacksize      ; delay slot, wird vor jal ausgeführt
    

     bltz $v0, loc_blaaa  ; Prüfen ob $v0 kleiner als 0 ist
    
     move $a0, $v0        ; $a0 = $v0
     lw $a1, 4($sp)        ; $a1 = der alte wert von $a0
     lw $a2, 8($sp)        ; $a2 = der alte wert von $a1
     nop                       ; load delay slot
    
     jal sceKernelStartThread
     nop                      ; branch delay slot

     loc_blaaa:
         ; Register zurückschreiben
         lw $a0, 4($sp)
         lw $a1, 8($sp)
         lw $ra, 0($sp)

         li $v0, 0                ; v0 = 0
         jr $ra                    ; zur firmware zurückspringen
         addiu $sp, $sp, 12   ; delay slot, stack wiederherstellen


Ich hoff jetzt ist es etwas besser verstanden :/


RE: [TuT] Hello World in C - Dr. Soup - 07.12.2010 14:57

Wenn ein Module gestoppt wird wird module_stop ausgeführt falls exportiert. Und bei einem jal (Jump and Link) gilt $ra = PC + 8 (zweite Instruction nach dem jal, da sich PC + 4 im Delay Slot befindet).

PS: Sorry für die kleine "Besserwisser-Attacke" :D


RE: [TuT] Hello World in C - HacKmaN - 07.12.2010 15:00

Dr. Soup :
Wenn ein Module gestoppt wird wird module_stop ausgeführt falls exportiert. Und bei einem jal (Jump and Link) gilt $ra = PC + 8 (zweite Instruction nach dem jal, da sich PC + 4 im Delay Slot befindet).

PS: Sorry für die kleine "Besserwisser-Attacke" Big Grin


Danke für die Verbesserungen Smile
Ich bessers mal aus siesta


RE: [TuT] Hello World in C - dark-awesome - 07.12.2010 15:03

Du scheinst dich ja gut aus zu kennen. Smile


RE: [TuT] Hello World in C - Fixie - 07.12.2010 15:04

Wo gib's ein Tutorial ohne Fehler?
Kann HTK nicht trauen...


RE: [TuT] Hello World in C - dark-awesome - 07.12.2010 15:45

Der Code von mir und die der anderen stimmen ja aber die Erklärung war wohl nicht so richtig.


RE: [TuT] Hello World in C - HacKmaN - 07.12.2010 15:47

killagodzilla :
Wo gib's ein Tutorial ohne Fehler?
Kann HTK nicht trauen...


Lern C lieber erst fürn PC, am besten ist C von A bis Z.


RE: [TuT] Hello World in C - Unbekannt - 07.12.2010 15:58

Danke Hackman. Habs etwas falsch erklärt, aber müsste Funktionieren.


RE: [TuT] Hello World in C - _Kai_ - 07.12.2010 18:26

Unbekannt :
Hast du es getestet? Müsste theoretisch klappen.


Unbekannt :
Das mit Callbacks habe ich glaube falsch. Muss nochmal nach schauen.


Warum postest du ein Tutorial dass du nicht mal getestet hast / dir sicher bist dass es auch richtig ist ? Du willst doch den Anfängern helfen und sie nicht verwirren oder ? Noidea


RE: [TuT] Hello World in C - pspbricker - 07.12.2010 19:06

Mit deiner Erklärung für die Einrichtung von von einem PSP Compiler liegst du komplett falsch. Der Compiler würde höchstens eine Binary für den PC erzeugen. Bitte zu den richten Tutorials verlinken, als in der Welt zu verbreiten, dass man für die PSP mit einer Header Datei Eboots erstellen kann Link http://pspking.de/toolchain.html

Zitat:
Die zwichen dem größer/kleiner-Zeichen stehenden Dateien befinden sich in der SDK.

Falsch. Wenn der Datei Name in in solchen Klammern geschrieben wird "<>" dann schaut der Compiler in $PATH nach, ob dort die Datei zu finden ist. Bei normalen Anführungszeichen wird im momentanen Ordner nachgeschaut.

Zitat:
main() ist damit gemeint, dass es sich um das Hauptprogramm handelt "main.c".

Die "main" Funktion kann in jeder beliebig genannten Datei sein, man muss sie nur richtig verlinken.

Sowelche Tutorials gibt im Forum oder im Internet 1000mal besser und genauer.

-Thread closed-