IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

ESP32 > esp_console + argtable3 dans progamme C++ [Autre micro]


Sujet :

Embarqué

  1. #1
    Membre averti
    Homme Profil pro
    autre
    Inscrit en
    Juin 2014
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juin 2014
    Messages : 96
    Points : 344
    Points
    344
    Par défaut ESP32 > esp_console + argtable3 dans progamme C++
    Salut,

    je suis en train de faire une application en C++ sur un ESP32.
    J'utilise la bibliothèque esp_console pour fournir une console pour envoyer des ordres à l'ESP32 via liaison USB.
    Je veux utiliser la bibliothèque argtab3 pour aider à la saisie et faciliter la vérification des paramètres saisis.

    esp_console : https://docs.espressif.com/projects/...s/console.html
    argtable3 : https://www.argtable.org/

    Ces deux librairies sont en C et j'ai un petit soucis pour les intégrer dans mon projet C++.
    Pour initialiser argtable, on doit lui fournir des pointeurs de fonction. J'ai pas envie de créer des fonctions statiques vu que ça me ferait perdre tous les avantages de l'orienté objet. J'ai donc mis en place des fonctions de callback qui utilisent un pointeur sur mon objet pour pouvoir fournir à argtable des pointeurs sur des fonctions membres de ma classe. Je suis sûr et certain que cet objet ne sera instancié qu'une seule fois dans mon projet donc ça ne devrait pas poser de problème.

    Maintenant que j'ai introduit le contexte, venons-en au problème :
    Le problème, c'est que argtable ne me retourne pas les paramètres saisis par l'utilisateur.
    Les fonctions de test sur le nombre et le format des arguments passés à la commande fonctionnent bien mais quand je veux avoir accès aux paramètres qui viennent d'être vérifiés, je récupère des valeurs aléatoires.
    J'ai testé mon code en dehors de fonctions membres et il fonctionne bien. C'est le fait de l'intégrer à mon code orienté objet qui provoque le problème.

    Voilà le code en question, simplifié au maximum (code testé et reproduisant exactement le même problème que mon projet) :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    // Pointer for my callback functions
    MyClass * _callback;
     
    struct arg_int *argInt;
    struct arg_end *endPage;
     
    // My callback function (GLOBAL)
    int _setInt(int argc, char *argv[])
    {
    	return _callback->setInt(argc, argv);
    }
     
    // Tab of struct for argtable lib (GLOBAL)
    void *setInt_argtable[] =
    {
    	argInt = arg_int1(NULL, NULL, "<0-12>", "Integer argument"),
    	endInt = arg_end(10)
    };
     
    // Function I'm calling back
    int MyClass::setInt(int argc, char *argv[])
    {
    	int nerrors = arg_parse(argc,argv,setInt_argtable);
    	if (nerrors > 0)
    	{
    		arg_print_errors(stdout, endPage, "myprog");
    		return 0;
    	}
    	printf("argc = %d\n", argc); 				//  ### argc gives the correct number of args ###
    	printf("argv[0] = %s\n", argv[0]);			// ### argv[0] gives the correct command name ###
    	printf("argv[1] = %s\n", argv[1]);			// ### argv[1] gives the correct value ###
    	printf("argInt->ival[0] = %d\n", argInt->ival[0]);	// ### argInt->ival[0] gives random value ###
    	return 0;
    }
     
    void MyClass::main(void)
    {
    	// Callback pointer initialisation
    	_callback = this;
     
    	/* Initialize the console */
    	esp_console_config_t console_config
    	{
    		256,
    		8,
    		atoi(LOG_COLOR_CYAN),
    		0
    	};
    	ESP_ERROR_CHECK( esp_console_init(&console_config) );
     
    	/* Configure linenoise line completion library */
    	/* Enable multiline editing. If not set, long commands will scroll within
    	* single line.
    	*/
    	linenoiseSetMultiLine(1);
     
    	/* Tell linenoise where to get command completions and hints */
    	linenoiseSetCompletionCallback(&esp_console_get_completion);
    	linenoiseSetHintsCallback((linenoiseHintsCallback*) &esp_console_get_hint);
     
    	/* Set command history size */
    	linenoiseHistorySetMaxLen(100);
     
     
    	esp_console_register_help_command();
     
    	//
    	// Feeding my console with argtable parameters
    	//
     
    	esp_console_cmd_t consoleCmd;
    	consoleCmd.command  = "setInt";
    	consoleCmd.func     = &_setInt;   // ### Using the callback ###
    	consoleCmd.help     = "Trying to set a integer argument";
    	consoleCmd.argtable = setInt_argtable;
    	esp_console_cmd_register(&consoleCmd);  
     
    	/* Main loop */
    	while(true)
    	{
    		// Getting command from user
    	}
    }


    Le problème a l'air de se situer à cet endroit :
    Dans argatable3.c :
    A la fin de la fonction static int arg_int_scanfn(struct arg_int *parent, const char *argval), j'ai rajouté deux petits printf qui me permettent de voir le problème :

    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (errorcode == 0)
    {
    	parent->ival[parent->count++] = val;
    	printf("val = %ld\n", val);
    	printf("parent->ival[parent->count] = %d\n", parent->ival[parent->count]);
    }

    Le premier printf me renvoie bien la valeur saisie par l'utilisateur alors que le deuxième renvoi une valeur aléatoire.
    Le problème se situe donc au niveau de l'affectation à parent->ival[x].
    J'ai pas de quoi faire de débug donc je peux difficilement donner plus d'infos.

    Est-ce que mon approche de l'utilisation de fonctions de callback pour appeler des fonctions membres est bonne ?
    Des idées sur ce que je pourrais essayer de tester sur le pointeur de structure parent pour essayer de trouver la source du problème ?


    Merci d'avance pour vos réponses.

  2. #2
    Expert éminent
    Avatar de transgohan
    Homme Profil pro
    Développeur Temps réel Embarqué
    Inscrit en
    Janvier 2011
    Messages
    3 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur Temps réel Embarqué

    Informations forums :
    Inscription : Janvier 2011
    Messages : 3 146
    Points : 9 386
    Points
    9 386
    Par défaut
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (errorcode == 0)
    {
    	parent->ival[parent->count++] = val;
    	printf("val = %ld\n", val);
    	printf("parent->ival[parent->count] = %d\n", parent->ival[parent->count]);
    }
    Tu stockes à l'index count puis tu incrémentes count.
    Donc quand tu relis à l'index count tu te trouves à une différence de 1 par rapport à là où tu as stocké val.

    Ceci serait mieux :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (errorcode == 0)
    {
    	parent->ival[parent->count++] = val;
    	printf("val = %ld\n", val);
    	printf("parent->ival[parent->count] = %d\n", parent->ival[parent->count-1]);
    }

    Ou encore mieux :
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    if (errorcode == 0)
    {
    	parent->ival[parent->count] = val;
    	printf("val = %ld\n", val);
    	printf("parent->ival[parent->count] = %d\n", parent->ival[parent->count]);
            parent->count++;
    }

    « Toujours se souvenir que la majorité des ennuis viennent de l'espace occupé entre la chaise et l'écran de l'ordinateur. »
    « Le watchdog aboie, les tests passent »

  3. #3
    Membre averti
    Homme Profil pro
    autre
    Inscrit en
    Juin 2014
    Messages
    96
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juin 2014
    Messages : 96
    Points : 344
    Points
    344
    Par défaut
    Salut,

    merci pour la réponse.

    Désolé, j'ai oublié de revenir sur le forum ce matin, j'ai résolu mon pb.
    Je me suis rendu compte de la post incrémentation sur le printf un peu avoir posté mon message.

    Pour en revenir au problème de base, après avoir passé 2 jours à tester tout ce qui était possible et imaginable, j'ai fini par faire des copier/coller d'exemples simples trouvés sur internet.
    Et ça m'a permis de me rendre compte que ce qui faisait planter mon programme, c'était mes inclusions.

    J'incluais <argtable/argtable3.h> après "myclass.h"
    Le fait de changer l'ordre d'inclusion me redonne un fonctionnement normal de argtable.
    J'ai donc maintenant une belle classe avec toutes mes variables qui font partie de la classe et juste mon pointeur + mes fonctions de callback qui sont en global.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Invalid syntax dans mon progamme
    Par WipEout37 dans le forum Général Python
    Réponses: 2
    Dernier message: 14/05/2019, 22h42
  2. lancement d'un progamme console dans une console
    Par joreveur dans le forum Shell et commandes GNU
    Réponses: 1
    Dernier message: 09/02/2010, 14h07
  3. [SAX] progamme sui ne passe jamais dans endElement
    Par cocula dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 26/04/2005, 09h37
  4. gérer les jpg dans une fenetre directdraw???
    Par Anonymous dans le forum DirectX
    Réponses: 1
    Dernier message: 14/06/2002, 13h39
  5. Documentation DirectX dans C++Builder 3
    Par srvremi dans le forum DirectX
    Réponses: 1
    Dernier message: 26/04/2002, 09h59

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo