Posté le 10/05/2023 13:16
Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2023 | Il y a 44 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements
Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd
Citer : Posté le 11/05/2023 19:06 | #
Je suis pas assez calé hardware pour donner une critique, mais ce n'est pas si simple.
La Numworks est idéal pour le Python ; La G90 supporte Python et à Python extra. Mais je ne recommanderai pas une G90 pour une personne qui veut coder en Python.
La G90 est une plate-forme super pour le gaming et pour créer des jeux/utilitaires. La Numworks, moins voir pas du tout.
Bref, je vais pas vous pondre un pavé, c'est compliqué quoi. Ça dépend du ou des besoins.
Littéralement démon du chat
Toi qui lit ça, tu est vraiment chanceux
Car une légende est née.
Je soutient Planète Casio
Mouah ha ha !
Citer : Posté le 11/05/2023 20:29 | #
Je ne suis pas d'accord, je trouve que la Numworks est loin d'être idéale pour faire du Python. D'abord il y a vraiment trop peu de tas disponible. Et mon port de MicroPython pour la CG90 (micropy) a plus de modules que celui de Numworks, on peut tester si la syntaxe est correcte directement dans l'éditeur, il y a du parenthese matching, ...
Citer : Posté le 23/05/2023 17:44 | #
Il y a du nouveau depuis la coupure pour ceux qui ne suivent pas l'actualité sur tiplanet.
Mon port d'Upsilon pour Casio permet maintenant la sauvegarde de l'état, y compris l'historique des calculs, et la possibilité d'échanger avec le système de fichiers hote:
https://www-fourier.univ-grenoble-alpes.fr/~parisse/casio/upsilon.g3a
Citer : Posté le 26/05/2023 10:51 | #
Une chose que j'aimerais rajouter dans ce port, c'est la possibilité d'appeler des fonctions de giac depuis Upsilon. L'idée serait d'avoir un fichier binaire linké en 0x8c200000 qui serait chargé par Upsilon en RAM, et qui contient la fonction
const char * run_caseval(const char *);
qui s'occupe de faire l'évaluation par giac d'une chaine provenant d'Upsilon (par exemple quand on valide une ligne de commande dans l'appli Calculs).
Mais il faut que je puisse repérer l'adresse de run_caseval dans le binaire, et je n'arrive pas à voir comment écrire le script de ld pour ça.
J'ai créé un fichier giacmain.cc qui contient seulement une table avec l'adresse du pointeur à appeler:
const char * run_caseval(const char * s);
extern const unsigned caseval_ptr[];
const unsigned caseval_ptr[]={
(unsigned) run_caseval,
};
J'ai essayé le script ci-dessous (en m'inspirant du script pour khicas en 2 addins), mais caseval_ptr n'est pas du tout au début de la zone, il est en 8c3c8da0 . Comment faire? Merci d'avance!
OUTPUT_FORMAT(elf32-sh)
OUTPUT_ARCH(sh3)
ENTRY(initialize)
MEMORY
{
/* Loads code at 300000, skips g3a header */
/* rom (rx) : o = 0x00300000, l = 2M-32000 */
/* RAM is available at 0x8c200000, 3M maybe more */
/* use emu.ld for emulator since it's at 0x88200000 */
r8c2 (rx) : o = 0x8c200000, l = 1K
r8c2p (rx) : o = 0x8c200000+1K, l = 2048K-1K
ram (rwx) : o = 0x8c400000, l = 256k /* skip 4k at start */
}
SECTIONS
{
/* Code, in ROM */
.giacmain : {
giacmain*.o(.rodata)
giacmain*.o(.rodata.*)
} > r8c2
.text : {
*(.pretext)
*(.text)
*(.text.*)
} > r8c2p
/* Read-only data, in ROM */
.rodata : {
*(.rodata)
*(.rodata.*)
} > r8c2p
/* RW initialized data, VMA in RAM but LMA in ROM */
.data : ALIGN(4) {
_datald = LOADADDR(.data) ;
_sdata = . ;
*(.data)
*(.data.*);
_edata = . ;
} >ram AT>r8c2p
/* Uninitialized data (fill with 0), in RAM */
.bss ALIGN(4) : ALIGN(4) {
_bbss = . ;
*(.bss)
*(.bss*)
*(COMMON)
_ebss = . ;
/* Extra unused static space */
_sextra = ALIGN(32);
_eextra = ORIGIN(ram) + LENGTH(ram);
} >ram
/DISCARD/ : {
*(.debug_*) ;
*(.comment) ;
}
}
Citer : Posté le 26/05/2023 11:08 | #
Tu peux supprimer le tableau du code source et juste le créer dans le linker script. Tu vas dans la première section qui est stockée dans r8c2 (le premier bout qui finit par > r8c2) et tu y mets un LONG avec le symbole. Par exemple, si la première section dans r8c2 est un .text :
LONG(run_caseval);
/* Tu peux mettre d'autres valeurs si tu veux */
*(.text .text.*)
/* ... */
} > r8c2
Du coup l'adresse de run_caseval() sera stockée à 0x8c200000. Attention pas la fonction, juste son adresse. De tête ça devrait donner ça :
run_caseval_function **f = (void *)0x8c200000;
(*f)("1+2");
Citer : Posté le 27/05/2023 13:07 | #
Merci pour ton aide précieuse. Malheureusement j'ai une erreur
calc.ld:21: undefined symbol run_caseval referenced in expression
si je fais
SECTIONS
{
/* Code, in ROM */
.text : {
LONG(run_caseval)
*(.pretext)
*(.text)
*(.text.*)
} > r8c2p
...
Si j'enlève run_caseval, ça marche.
Bon pour le moment je vais adopter la solution transitoire suivante: utiliser main comme point d'entrée pour récupérer l'adresse de run_caseval, mais aussi pour initialiser le binaire (data et bss), de toutes façons il faut bien le faire. C'est d'ailleurs quelque chose qu'il faudrait aussi faire pour KhiCAS en 2 morceaux, le 2ème morceau doit aussi être initialisé explicitement, et c'est ce qui explique peut-être un problème étrange que j'avais évoqué avec un problème d'initialisation du code 3d.
Voilà ce que donne le début du dump, sans rien faire de spécial:
8c200000 g .text 00000000 initialize
8c200000 l d .text 00000000 .text
8c20000c l .text 00000000 dataLoop
8c200018 l .text 00000000 dataDone
8c20001e l .text 00000000 bssLoop
8c200028 l .text 00000000 bssDone
8c20003e l .text 00000000 GlibAddinAplExecutionCheck
8c200050 l .text 00000000 main
8c200054 l .text 00000000 v_syscall
8c200058 l .text 00000000 v_datald
8c20005c l .text 00000000 v_edata
8c200060 l .text 00000000 v_sdata
8c200064 l .text 00000000 v_ram_bbss
8c200068 l .text 00000000 v_ram_ebss
8c20006c g F .text 0000000c .hidden bool giac::m_lex_is_strictly_greater<giac::gen>(giac::monomial<giac::gen> const&, giac::monomial<giac::gen> const&)
...
à priori l'adresse de main sera toujours à l'adresse 8c200050 (j'ai essayé de remplacer ENTRY(initialize) par ENTRY(main) dans le script du loader mais ça ne marche pas). Et mon main est dans le code ci-dessous, donc son appel devrait permettre de localiser la fonction run_caseval
extern "C" const char * run_caseval(const char * s);
extern const unsigned caseval_ptr[];
const unsigned caseval_ptr[]={
(const unsigned) run_caseval,
};
extern "C" unsigned * datald,*sdata,*edata,*bbss,*ebss;
// data provided by linker script
// main should be called once at binary load time
__attribute__((noinline)) int main(){
// init the binary file and return address of the syscall table
// this is done by initialize in an addin, but here we must do it explicitly
unsigned * src=datald,*target=sdata;
for (;target<edata;++src,++target)
*target=*src;
for (target=bbss;target<ebss;++target)
*target=0;
return (int) caseval_ptr;
}
Citer : Posté le 27/05/2023 13:43 | #
Oups, j'ai écrit un peu vite et oublié que les symboles ont un underscore en plus sur cette plateforme.
Tu ne seras pas surpris de savoir que je déconseille fortement d'hardcoder les adresses puisque là tu as deux fichiers différents et ton linker script n'impose l'ordre d'aucune section à part la toute première (dans laquelle main n'est pas)
Citer : Posté le 27/05/2023 14:52 | #
Effectivement en ajoutant le _ ca compile, mais je ne récupère pas l'adresse de run_caseval, le hexdump me donne 0000 0000. Ca marche pour main par contre, donc je vais faire avec LONG(_main) en premier, en étant ainsi assuré que l'offset de lecture de main ne bougera pas.
Citer : Posté le 05/06/2023 17:35 | #
J'ai un peu avancé, mais je bloque pour l'initialisation de l'overlay, car edata et sdata contiennent 0 dans le code de main
__attribute__((noinline)) int main(){
unsigned * src=datald; unsigned *target=sdata;
for (;target<edata;++src,++target)
*target=*src;
for (target=bbss;target<ebss;++target)
*target=0;
...
En regardant un extrait du dump des symboles et le hexdump de l'overlay, il semble que c'est la valeur de v_datald, v_edata et v_sdata, v_ram_bbss et v_ram_ebss qu'il me faut utiliser, mais comment on les adresse depuis C vu qu'il n'y a pas de _ devant le v? (evidemment je pourrais utiliser des adresses absolues, mais c'est mal...).
Ou bien on peut peut-être appeler initalize qui a l'air de faire l'initialisation, mais je ne sais pas à quoi correspond GlibAddinAplExecutionCheck
8c200010 g .text 00000000 initialize
8c20001c l .text 00000000 dataLoop
8c200028 l .text 00000000 dataDone
8c20002e l .text 00000000 bssLoop
8c200038 l .text 00000000 bssDone
8c20004e l .text 00000000 GlibAddinAplExecutionCheck
8c200060 l .text 00000000 main
8c200064 l .text 00000000 v_syscall
8c200068 l .text 00000000 v_datald
8c20006c l .text 00000000 v_edata
8c200070 l .text 00000000 v_sdata
8c200074 l .text 00000000 v_ram_bbss
8c200078 l .text 00000000 v_ram_ebss
...
8c3cfbbc g *ABS* 00000000 datald
8c3e0000 g .data 00000000 sdata
...
8c3e03e4 g .bss 00000000 bbss
8c3e03e4 g .data 00000000 edata
8c3e03e4 l d .bss 00000000 .bss
...
8c40ed88 g .bss 00000000 ebss
Le début de l'hexdump de l'overlay (les 16 premiers octets contiennent l'adresse de la table contenant caseval et 31415927 qui me sert de marqueur qu'il s'agit bien de l'overlay giac et pas d'un fichier quelconque renommé).
0000000 3a8c 0062 4131 2759 0000 0000 0000 0000
0000010 e62f 224f 462f 14d0 15d2 14d3 3232 0389
0000020 0661 1222 faaf 0472 13d2 12d3 00e1 3632
0000030 028b 0900 fbaf 1422 536e 01e6 00e4 06b0
0000040 6365 07d7 ed65 f665 264f 2b47 f66e 05d2
0000050 2b42 29e0 0000 0000 0000 0000 0000 0000
0000060 3a8c 0062 0280 7000 3c8c bcfb 3e8c e403
0000070 3e8c 0000 3e8c e403 408c 88ed 01d0 2b40
...
Merci d'avance si tu as une piste!
Citer : Posté le 05/06/2023 19:28 | #
Hello, la "valeur" du symbole correspond à l'adresse de la "variable" associée. Donc pour
Tu dois faire
uint32_t x = (uint32_t)&datald;
/* x = 0x8c3cfbbc */
Et tu as aussi besoin de l'appeler _datald vu que le compilateur C met un underscore devant tous les noms de variables quand il nomme les symboles (sur cette plateforme).
Citer : Posté le 06/06/2023 08:05 | #
Oui, c'est fait comme ça dans le fichier de ld
/* RW initialized data, VMA in RAM but LMA in ROM */
.data : ALIGN(4) {
_datald = LOADADDR(.data) ;
_sdata = . ;
*(.data)
*(.data.*);
_edata = . ;
} >ram AT>r8c2p
Bon, ça fonctionne parfois mais j'ai des problèmes de crash, probablement liés avec la gestion mémoire. Pour l'overlay, j'utilise le "vieux" SDK avec modification du malloc de la libc qui appelle ton kmalloc alors que l'addin principal Upsilon utilise gint, je soupconne que c'est la raison. Et difficile de déduire quoi que ce soit des infos du crash:
PC = 0041eaf0
TEA= 0041eaF0
TRA=0x0
L'adresse est celle de gint_default_panic
Pour la gestion de la mémoire, dans l'initialisation de l'overlay je fais la chose suivante, qui est peut-être incompatible avec l'utilisation de Upsilon/gint
// init kmalloc
bool is_emulator = *(volatile uint32_t *)0xff000044 == 0x00000000;
uint32_t stack;
__asm__("mov r15, %0" : "=r"(stack));
bool prizmoremu=stack<0x8c000000;
int calculator=prizmoremu?2:1;
/* À appeler une seule fois au début de l'exécution */
kmalloc_init();
/* Ajouter une arène sur la RAM inutilisée */
static_ram.name = "_uram";
static_ram.is_default = 0; // 0 disable this area, 1 enable
//void *malloc_start = &sextra;
//void *malloc_end = &eextra;
//int malloc_size = malloc_end - malloc_start;
static_ram.start = &sextra;
static_ram.end = &eextra;
kmalloc_init_arena(&static_ram, true);
kmalloc_add_arena(&static_ram);
if (prizmoremu) {
/* Prizm ou émulateur Graph 90+E */
ram3M.name="_3M";
ram3M.is_default=1;
ram3M.start=0x883e0000+256*1024;
ram3M.end=ram3M.start+0x80000;
kmalloc_init_arena(&ram3M, true);
kmalloc_add_arena(&ram3M);
}
else {
/* Graph 90+E & FXCG50(?) */
ram3M.name="_3M";
ram3M.is_default=1;
ram3M.start=0x8c3e0000+256*1024;
ram3M.end=ram3M.start+0x80000;
kmalloc_init_arena(&ram3M, true);
kmalloc_add_arena(&ram3M);
}
Sachant que dans le fichier loader contient
MEMORY
{
/* Loads code at 300000, skips g3a header */
/* rom (rx) : o = 0x00300000, l = 2M-32000 */
/* RAM is available at 0x8c200000, 3M maybe more */
/* use emu.ld for emulator since it's at 0x88200000 */
r8c2p (rx) : o = 0x8c200000, l = 2048K-128K
ram (rwx) : o = 0x8c3e0000, l = 256k
}
Citer : Posté le 06/06/2023 08:26 | #
J'ai une autre info de crash plus intéressante: 040 TLB miss on read, PC=41f646 (c'est à la fin de gint_malloc), TEA=1216be9c,
0041f378 l F .text 000000c8 gint_free
0041f440 l F .text 000000d0 gint_malloc_max
0041f510 l F .text 00000144 gint_malloc
0041f654 l F .text 00000180 gint_realloc
0041f7d4 g F .text 000000f0 kmalloc_init_arena
0041f8c4 g F .text 00000018 kmalloc_get_gint_stats
0041f8dc l F .text 00000030 arena_owning
0041f90c g F .text 00000010 kmalloc_init
0041f91c g F .text 00000054 kmalloc_get_arena
0041f970 g F .text 00000094 kmalloc
0041fa04 g F .text 00000034 kfree
0041fa38 g F .text 00000094 krealloc
0041facc g F .text 0000008c kmalloc_max
0041fb58 g F .text 00000024 kmalloc_add_arena
Citer : Posté le 06/06/2023 11:23 | #
En fait, c'est peut-être un problème avec la taille de la stack. Lorsque je passe un buffer alloué sur la stack de 2048 à 1024, ça marche nettement mieux. C'est quoi la taille de la stack utilisable dans un addin avec gint? Comment peut-on la changer?