π
<-
Chat plein-écran
[^]

Ndless KeyListener

C, C++, ASM...

Ndless KeyListener

Message non lude MishaShapo » 06 Mai 2016, 05:05

Hi, I am trying to create a keylistener in Ndless that will print an ASCII string to the USB port through NspireIO. I have looked at the Zlock and nClock examples to try and emulate them, but my code doesn't seem to work. It sends the "URTX" message and then the calculator freezes, but I do know the program is running because when I press the flag button (the button that terminates the outer while loop in my main method) then the calculator goes back to normal.

Can anyone please point out what I am doing wrong? Thank you. :)


Salut, je suis en train de créer un keyListener en Ndless qui imprimera une chaîne ASCII au port USB via NspireIO. J'ai regardé les exemples ZLOCK et nClock pour essayer de les imiter, mais mon code ne semble pas fonctionner. Il envoie le message "Urtx", puis la calculatrice se fige, mais je ne sais que le programme est en cours d'exécution parce que quand je presse le bouton de drapeau (le bouton qui met fin à l'extérieur tout en boucle dans ma méthode principale), le calculateur va revenir à la normale.

Quelqu'un peut-il s'il vous plaît souligner ce que je fais mal? Je vous remercie. :)

Code: Tout sélectionner
#include <os.h>
#include "libndls.h"
#include <nspireio/nspireio.h>
char *cmd = "";
bool quit = false;

void pushButton(){
    if(isKeyPressed(KEY_NSPIRE_0)) cmd = "0";
    if(isKeyPressed(KEY_NSPIRE_1)) cmd = "1";
    if(isKeyPressed(KEY_NSPIRE_2)) cmd = "2";
    if(isKeyPressed(KEY_NSPIRE_3)) cmd = "3";
    if(isKeyPressed(KEY_NSPIRE_4)) cmd = "4";
    if(isKeyPressed(KEY_NSPIRE_5)) cmd = "5";
    if(isKeyPressed(KEY_NSPIRE_6)) cmd = "6";
    if(isKeyPressed(KEY_NSPIRE_7)) cmd = "7";
    if(isKeyPressed(KEY_NSPIRE_8)) cmd = "8";
    if(isKeyPressed(KEY_NSPIRE_9)) cmd = "9";
    if(isKeyPressed(KEY_NSPIRE_A)) cmd = "A";
    if(isKeyPressed(KEY_NSPIRE_B)) cmd = "B";
    if(isKeyPressed(KEY_NSPIRE_C)) cmd = "C";
    if(isKeyPressed(KEY_NSPIRE_D)) cmd = "D";
    if(isKeyPressed(KEY_NSPIRE_E)) cmd = "E";
    if(isKeyPressed(KEY_NSPIRE_F)) cmd = "F";
    if(isKeyPressed(KEY_NSPIRE_G)) cmd = "G";
    if(isKeyPressed(KEY_NSPIRE_H)) cmd = "H";
    if(isKeyPressed(KEY_NSPIRE_I)) cmd = "I";
    if(isKeyPressed(KEY_NSPIRE_J)) cmd = "J";
    if(isKeyPressed(KEY_NSPIRE_K)) cmd = "K";
    if(isKeyPressed(KEY_NSPIRE_L)) cmd = "L";
    if(isKeyPressed(KEY_NSPIRE_M)) cmd = "M";
    if(isKeyPressed(KEY_NSPIRE_N)) cmd = "N";
    if(isKeyPressed(KEY_NSPIRE_O)) cmd = "O";
    if(isKeyPressed(KEY_NSPIRE_P)) cmd = "P";
    if(isKeyPressed(KEY_NSPIRE_Q)) cmd = "Q";
    if(isKeyPressed(KEY_NSPIRE_R)) cmd = "R";
    if(isKeyPressed(KEY_NSPIRE_S)) cmd = "S";
    if(isKeyPressed(KEY_NSPIRE_T)) cmd = "T";
    if(isKeyPressed(KEY_NSPIRE_U)) cmd = "U";
    if(isKeyPressed(KEY_NSPIRE_V)) cmd = "V";
    if(isKeyPressed(KEY_NSPIRE_W)) cmd = "W";
    if(isKeyPressed(KEY_NSPIRE_X)) cmd = "X";
    if(isKeyPressed(KEY_NSPIRE_Y)) cmd = "Y";
    if(isKeyPressed(KEY_NSPIRE_Z)) cmd = "Z";
    if(isKeyPressed(KEY_NSPIRE_ESC)) cmd = "ESC";
    if(isKeyPressed(KEY_NSPIRE_DEL)) cmd = "DEL";
    if(isKeyPressed(KEY_NSPIRE_ENTER)) cmd = "ENT";
    if(isKeyPressed(KEY_NSPIRE_RET)) cmd = "RET";
    if(isKeyPressed(KEY_NSPIRE_SPACE)) cmd = " ";
    if(isKeyPressed(KEY_NSPIRE_NEGATIVE)) cmd = "-";
    if(isKeyPressed(KEY_NSPIRE_PERIOD)) cmd = ".";
    if(isKeyPressed(KEY_NSPIRE_THETA)) cmd = "THETA";
    if(isKeyPressed(KEY_NSPIRE_COMMA)) cmd = ",";
    if(isKeyPressed(KEY_NSPIRE_PLUS)) cmd = "+";
    if(isKeyPressed(KEY_NSPIRE_eEXP)) cmd = "eEXP";
    if(isKeyPressed(KEY_NSPIRE_PI)) cmd = "PI";
    if(isKeyPressed(KEY_NSPIRE_QUES)) cmd = "QUES";
    if(isKeyPressed(KEY_NSPIRE_QUESEXCL)) cmd = "QUESEXCL";
    if(isKeyPressed(KEY_NSPIRE_MINUS)) cmd = "-";
    if(isKeyPressed(KEY_NSPIRE_TENX)) cmd = "TENX";
    if(isKeyPressed(KEY_NSPIRE_EE)) cmd = "EE";
    if(isKeyPressed(KEY_NSPIRE_COLON)) cmd = ":";
    if(isKeyPressed(KEY_NSPIRE_MULTIPLY)) cmd = "*";
    if(isKeyPressed(KEY_NSPIRE_SQU)) cmd = "SQU";
    if(isKeyPressed(KEY_NSPIRE_II)) cmd = "II";
    if(isKeyPressed(KEY_NSPIRE_QUOTE)) cmd = "\"";
    if(isKeyPressed(KEY_NSPIRE_DIVIDE)) cmd = "/";
    if(isKeyPressed(KEY_NSPIRE_TAN)) cmd = "TAN";
    if(isKeyPressed(KEY_NSPIRE_COS)) cmd = "COS";
    if(isKeyPressed(KEY_NSPIRE_SIN)) cmd = "SIN";
    if(isKeyPressed(KEY_NSPIRE_EXP)) cmd = "EXP";
    if(isKeyPressed(KEY_NSPIRE_GTHAN)) cmd = ">";
    if(isKeyPressed(KEY_NSPIRE_APOSTROPHE)) cmd = "'";
    if(isKeyPressed(KEY_NSPIRE_CAT)) cmd = "CAT";
    if(isKeyPressed(KEY_NSPIRE_FRAC)) cmd = "FRAC";
    if(isKeyPressed(KEY_NSPIRE_RP)) cmd = "RP";
    if(isKeyPressed(KEY_NSPIRE_LP)) cmd = "LP";
    if(isKeyPressed(KEY_NSPIRE_VAR)) cmd = "VAR";
    if(isKeyPressed(KEY_NSPIRE_DEL)) cmd = "DEL";
    if(isKeyPressed(KEY_NSPIRE_LTHAN)) cmd = "<";
    if(isKeyPressed(KEY_NSPIRE_FLAG)){ cmd = "FLAG";quit=true;}
    if(isKeyPressed(KEY_NSPIRE_CLICK)) cmd = "CLICK";
    if(isKeyPressed(KEY_NSPIRE_HOME)) cmd = "HOME";
    if(isKeyPressed(KEY_NSPIRE_MENU)) cmd = "MENU";
    if(isKeyPressed(KEY_NSPIRE_BAR)) cmd = "BAR";
    if(isKeyPressed(KEY_NSPIRE_TAB)) cmd = "TAB";
    if(isKeyPressed(KEY_NSPIRE_EQU)) cmd = "EQU";
    if(isKeyPressed(KEY_NSPIRE_UP)) cmd = "UP";
    if(isKeyPressed(KEY_NSPIRE_UPRIGHT)) cmd = "UPRIGHT";
    if(isKeyPressed(KEY_NSPIRE_RIGHT)) cmd = "RIGHT";
    if(isKeyPressed(KEY_NSPIRE_RIGHTDOWN)) cmd = "RIGHTDOWN";
    if(isKeyPressed(KEY_NSPIRE_DOWN)) cmd = "DOWN";
    if(isKeyPressed(KEY_NSPIRE_DOWNLEFT)) cmd = "DOWNLEFT";
    if(isKeyPressed(KEY_NSPIRE_LEFT)) cmd = "LEFT";
    if(isKeyPressed(KEY_NSPIRE_LEFTUP)) cmd = "LEFTUP";
    if(isKeyPressed(KEY_NSPIRE_SHIFT)) cmd = "SHIFT";
    if(isKeyPressed(KEY_NSPIRE_CTRL)) cmd = "CTRL";
    if(isKeyPressed(KEY_NSPIRE_DOC)) cmd = "DOC";
    if(isKeyPressed(KEY_NSPIRE_TRIG)) cmd = "TRIG";
    if(isKeyPressed(KEY_NSPIRE_SCRATCHPAD)) cmd = "SCRPAD";

    uart_puts(cmd);
    uart_puts("!");
}

int main(int argc, char* argv[]){

    if(argc < 1) return 0;
    cmd = "URTX";
    uart_puts(cmd);
    uart_puts("!");
    while(!quit){
        while(!any_key_pressed()){
        }
        pushButton();
    }
    return 0;
}


Avatar de l’utilisateur
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Prochain niv.: 68%
 
Messages: 17
Inscription: 06 Mai 2016, 04:58
Genre: Non spécifié
Calculatrice(s):
MyCalcs profile

Re: Ndless KeyListener

Message non lude Ti64CLi++ » 06 Mai 2016, 10:49

Bonjour,
Avec quoi compiles-tu ton code? Sous Linux ou sous Windows?
Image
Avatar de l’utilisateur
Ti64CLi++Modo
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Prochain niv.: 32.3%
 
Messages: 3441
Images: 75
Inscription: 04 Juil 2014, 14:40
Localisation: Clermont-Ferrand 63
Genre: Homme
Calculatrice(s):
MyCalcs profile
Classe: ENS Rennes
GitHub: Ti64CLi

Re: Ndless KeyListener

Message non lude Vogtinator » 06 Mai 2016, 11:17

It sends the "URTX" message and then the calculator freezes, but I do know the program is running because when I press the flag button (the button that terminates the outer while loop in my main method) then the calculator goes back to normal.


Of course, the nspire doesn't do anything else than your loop as Ndless apps aren't multithreaded by default.
You have two options here, either add a hook somewhere in the OS or start a new thread with the OS's TCC_Create_Task function, currently not exposed by ndless as not quite stable.

nClock and zLock both use the first approach, hooking the OS's code at a place that is regularily executed.
For nClock, search for "hook_nclock" in nclock.c and you'll find everything necessary to get it running.

If you want to go the second route, I made a PoC with multithreading on https://www.omnimaga.org/ti-nspire-proj ... #msg398134
You can find the addresses for other OS's in the ndless sdk (https://github.com/ndless-nspire/Ndless ... scalls/idc).
Avatar de l’utilisateur
VogtinatorPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Prochain niv.: 1.6%
 
Messages: 217
Inscription: 29 Mar 2014, 15:55
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Ndless KeyListener

Message non lude MishaShapo » 07 Mai 2016, 06:50

Hi, Vogtinator, thank you for the reply. I see that I have to use the hooks system you mentioned. I also read through another forum post on this same topic where you explained hooks https://www.omnimaga.org/calculator-c-language/ndless-hooking-tutorial-(especially-key-hooks) . I think that I understand the concept I am just having trouble finding the hook addresses. You said on that other forum that I would have to use the firebird debugger, and if that's the case, then I still have some learning to do. I am also a little confused on the difference between a hook, an interrupt, and a syscall. Could you please give me a rough idea of the difference between them? Or do you want me to make another topic for that question?

Thanks again for replying. :)
Dernière édition par MishaShapo le 07 Mai 2016, 16:41, édité 1 fois.
Avatar de l’utilisateur
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Prochain niv.: 68%
 
Messages: 17
Inscription: 06 Mai 2016, 04:58
Genre: Non spécifié
Calculatrice(s):
MyCalcs profile

Re: Ndless KeyListener

Message non lude Vogtinator » 07 Mai 2016, 10:21

You may be able to reuse the nClock hook. I don't know how often it is called though.

I am also a little confused on the difference between a hook, an interrupt, and a syscall. Could you please give me a rough idea of the difference between them?

A hook is a modification of running code at strategic places to make it call your code.
An interrupt (IRQ/FIQ) is a signal from the hardware which causes the CPU to jump to a specific address (0x18/0x1C on ARM).
A syscall is also called a software interrupt (SWI), as it is like a hardware interrupt, just caused by software (0x08 on ARM).
Ndless programs use SWIs to make calls to ndless and the OS.
Avatar de l’utilisateur
VogtinatorPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Prochain niv.: 1.6%
 
Messages: 217
Inscription: 29 Mar 2014, 15:55
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Ndless KeyListener

Message non lude MishaShapo » 07 Mai 2016, 16:45

Vogtinator, I tried to use the nClock hooks, but it did not fire regularly. How would I go about finding the OS's key interrupt handler as you said in the other forum post? I know it has to do with assembly and using the firebird debugger. But I am new to GDB and assembly in general. But if there are any resources that I should read/watch I will do that. Thanks for helping me with this. Its a project for a teacher of mine, and I really want to get it to her before the school year ends, so I appreciate you helping me with this. :)
Avatar de l’utilisateur
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Prochain niv.: 68%
 
Messages: 17
Inscription: 06 Mai 2016, 04:58
Genre: Non spécifié
Calculatrice(s):
MyCalcs profile

Re: Ndless KeyListener

Message non lude Vogtinator » 07 Mai 2016, 17:52

Finding that is quite easy, by printing the PC during reads of the keypad. Just tell me which OS and I'll find it.
Avatar de l’utilisateur
VogtinatorPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Prochain niv.: 1.6%
 
Messages: 217
Inscription: 29 Mar 2014, 15:55
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Ndless KeyListener

Message non lude MishaShapo » 07 Mai 2016, 18:21

I will be using TI-Nspire CX (both CAS and non-CAS) with Ndless 4.2. Also, what do you mean "PC"? Thank you so much!!
Avatar de l’utilisateur
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Prochain niv.: 68%
 
Messages: 17
Inscription: 06 Mai 2016, 04:58
Genre: Non spécifié
Calculatrice(s):
MyCalcs profile

Re: Ndless KeyListener

Message non lude Vogtinator » 07 Mai 2016, 18:36

PC is the program counter. The pointer to the current instruction.
You should be able to hook 0x10069ce0 on CX CAS and 0x1006A220 on CX.
Avatar de l’utilisateur
VogtinatorPremium
Niveau 9: IC (Compteur Infatigable)
Niveau 9: IC (Compteur Infatigable)
Prochain niv.: 1.6%
 
Messages: 217
Inscription: 29 Mar 2014, 15:55
Genre: Homme
Calculatrice(s):
MyCalcs profile

Re: Ndless KeyListener

Message non lude MishaShapo » 07 Mai 2016, 19:20

Hi, Vogtinator, the hooks work! But sadly not for the touchpad and it has crashed once with this error:

Code: Tout sélectionner
Warning (110ee3a0): Bad write_word: 90020018 00180018
Error (110ee3c4): LDRD/STRD with odd-numbered data register

Would it be possible to find the hook for the touchpad as well? If not, I can make this work. :)

EDIT: I've noticed the error occurs when the calculator wakes up from sleep.
Avatar de l’utilisateur
MishaShapo
Niveau 3: MH (Membre Habitué)
Niveau 3: MH (Membre Habitué)
Prochain niv.: 68%
 
Messages: 17
Inscription: 06 Mai 2016, 04:58
Genre: Non spécifié
Calculatrice(s):
MyCalcs profile

Suivante

Retourner vers Native: Ndless, Linux, ...

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 12 invités

-
Rechercher
-
Social TI-Planet
-
Sujets à la une
Comparaisons des meilleurs prix pour acheter sa calculatrice !
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
Phi NumWorks jailbreak
123
-
Faire un don / Premium
Pour plus de concours, de lots, de tests, nous aider à payer le serveur et les domaines...
Faire un don
Découvrez les avantages d'un compte donateur !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partenaires et pub
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
1040 utilisateurs:
>1020 invités
>16 membres
>4 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Autres sites intéressants
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)