Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Problème d'affichage avec fonction de recopie RAM en ROM
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » mar. 7 févr. 2017 07:35

Bonjour à tous,

J'utilise la fonction de Paul pour mettre du texte directement en RAM !

Code : Tout sélectionner

//------------------------------------------------------------------------------
// --- Copie le texte depuis ROM vers RAM
void strConstRamCpy(char *dest, const char *source){
  while(*source)
       *(dest++) = *(source++) ;
  *dest = 0 ;    // terminateur 
}


D’après ce que je comprend de cette fonction, elle récupère le texte envoyé en argument ( qui doit se terminer par un NULL pour arrêter le transfert) , et le copie dans la destination qui est un tableau préalablement déclaré en local char T_message[150]; . une fois le texte source lu ( jusqu'au terminateur), on arrête la recopie et on rajoute un nouveau terminateur à la fin de notre tableau.

Je rencontre des bugs d'affichages du genre texte coupé, caractères à la fin non voulus etc ... il me semble quand je dépasse un certains nombres de caractères, mais je n'en suis pas sûr. j'avoue que el comportement est plutôt aléatoire parfois!

Je vous raccourci ma fonction pour aller directement la ou ça bug .

Par exemple avec ceci , je n'ai aucun probléme , ça fonctionne parfaitement !

20170207_072911.jpg


Code : Tout sélectionner

//------------------------------------------------------------------------------
// Param. d'entrée : Le numéro correspondant au message à envoyer
void envoi_et_composition_SMS(char numero_message){
  // Les INT UART doivent etre desactivée

  char Compteur=0, Compteur2=0; // compteur pour time-out et re-envoie

  char T_message[150];      // Stockage du SMS à envoyer pendant la composition
  char temp[30];                // tableau temporaire pour les calculs

  F_envoi_ok = 0;               // RAZ de la variable, que indique que l'envoie c'est bien passé

  T_message[0] = 0;             // On se positionne au début du tableau
  temp[0] = 0;

  //--------------------    séléction et Création du message      -------------------
  switch (numero_message){

         case 1:{
               }
 ........
 ........
                }
         case 8:{
                  strConstRamCpy(T_message, "Etat du module:\r\nDate : ../../20..\r\nHeure : ..:..:..\r\nRéseau : ..%\r\nBatterie : ..%\r\nChrono lancé : ");

                  // rajoute le signal
                  T_message[63] = T_Signal[1];
                  T_message[64] = T_Signal[2];

                  // rajoute la tension
                  T_message[79] = T_Tension[1];
                  T_message[80] = T_Tension[2];


                  if (Chrono_lance==0){     // Si le Chrono est en cours
                     
                       
}
                 break;
               }


maintenant si je rajoute cette ligne strConstRamCpy(T_message+99, "Oui\r\nChrono :\r\n..h ..m ..s"); quand le chrono est lancé l'affichage est mauvais

Code : Tout sélectionner

                  if (Chrono_lance==0){     // Si le Chrono est en cours
                     strConstRamCpy(T_message+99, "Oui\r\nChrono :\r\n..h ..m ..s");
                   

20170207_072917.jpg

J'obtiens des erreurs !
et je ne cmprends pas d'ou cela peut provenir ! le texte continue a s'afficher malgrés la fin de chaine !

On voit que le "%" à disparu écrasé par je ne sais quoi, toput comme le texte "Chrono lancé" ???
On voit le texte "Chrono :" qui est affiché , mais pas le "OUI" ? si il y avait un probléme de placement dans le tableau le OUI serait aussi affiché mais au mauvais endroit ! Le comportement n'a rien de logique :furieux:

Merci !
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Problème d'affichage avec fonction de recopie RAM en ROM
brunog
Membre
Membre
Messages : 20
Enregistré en : janvier 2017

#2 Message par brunog » mar. 7 févr. 2017 11:53

Hello,
il faut vérifier :
* que le PIC utilisé dispose d'un bloc en RAM d'au moins 150 octets contigus et d'un autre de 30
* si ces 180 octets sont disponibles pour être créés sur la stack au moment de l'appel de la fonction (T_message est une variable locale). il est préférable d'utiliser un buffer global pour cela, ne serait-ce que pour avoir une information fiable du compilateur concernant la RAM disponible
* si il est garanti que T_message+99 représente l'adresse de la fin de la chaîne. il est préférable d'utiliser une fonction de concaténation plutôt que de copie pour éviter ce problème
* si il est garanti que l'application ne provoque pas d'autres débordements (on ne voit pas tout le code)
* si il n'y a pas un problème de ré-entrance
en général, plutôt que de manipuler et transmettre un seul grand buffer, il est préférable de découper la transmission avec plusieurs émissions d'un plus petit buffer. cela peut demander de modifier la stratégie de composition et d'envoi du message.
A+,
BrunoG
---
Quelques pico-idées en vrac : http:://www.micro-examples.com

Problème d'affichage avec fonction de recopie RAM en ROM
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » mar. 7 févr. 2017 12:03

Bonjour Brunog ,

merci de ton intérêt ! On voit la tout de suite le PRO ! me gourge ?

Je t'avoue ne pas avoir tout compris à tes solutions ! :oops: je suis d'un bien maigre niveau !

Pour la concaténation, j'ai essayé avec la fonction strcat mais le résultat n'est pas bon non plus , mais différent !
Pour l’envoi en plusieurs petit buffer, j'ai fais tout le contraire, car je pensais qu'il était préférable de préparer son SMS et ensuite d'envoyer un gros paquet !


Sinon je crois que le probléme est résolu en mettant char T_message[150]; en global et non en local ! je continue mes tests mais c'est sur la bonne voie !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Problème d'affichage avec fonction de recopie RAM en ROM
brunog
Membre
Membre
Messages : 20
Enregistré en : janvier 2017

#4 Message par brunog » mar. 7 févr. 2017 15:11

Jérémy a écrit :Bonjour Brunog ,

merci de ton intérêt ! On voit la tout de suite le PRO ! me gourge ?

Je t'avoue ne pas avoir tout compris à tes solutions ! :oops: je suis d'un bien maigre niveau !

Pour la concaténation, j'ai essayé avec la fonction strcat mais le résultat n'est pas bon non plus , mais différent !
Pour l’envoi en plusieurs petit buffer, j'ai fais tout le contraire, car je pensais qu'il était préférable de préparer son SMS et ensuite d'envoyer un gros paquet !


Sinon je crois que le probléme est résolu en mettant char T_message[150]; en global et non en local ! je continue mes tests mais c'est sur la bonne voie !

oui je connais bien le langage C, disons que c'est ma seconde langue maternelle...
pour la concaténation, il faut te construire une fonction strConstRamCat un peu comme tu l'as fait pour strConstRamCpy, car sinon en utilisant strcpy, l'argument littéral sera placé en RAM puis copié, cela multiplie donc par deux l'espace RAM utilisé...
mais le plus direct c'est effectivement d'utiliser un buffer global.
A+,
BrunoG
---
Quelques pico-idées en vrac : http:://www.micro-examples.com

Problème d'affichage avec fonction de recopie RAM en ROM
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#5 Message par Jérémy » mar. 7 févr. 2017 18:25

mais le plus direct c'est effectivement d'utiliser un buffer global.

+1

J'avais essayé de bien faire les choses avec mes variables globales, mais au final je me rends compte, que j'ai perdu bien plus de temps !

Je pense sincèrement que l'optimisation est fait pour les personnes ayant déjà un assez haut niveau ! je sais qu'il faut prendre les bonnes habitudes, les bonnes bases , mais si cela devient contre productif , le jeu n'en vaut pas la chandelle .

Surtout que maintenant nos chers µC ont des mémoires conséquentes. Je préfère perdre un peu en mémoire et ne pas à avoir à m'occuper de savoir si la variables est local ou non ! j’espère un jour avoir à m'en soucier , cela voudra dire que j'optimise à fond !

En tout cas merci pour tes précisions, je n'ai plus rencontré de bug !

Merci !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Problème d'affichage avec fonction de recopie RAM en ROM
brunog
Membre
Membre
Messages : 20
Enregistré en : janvier 2017

#6 Message par brunog » mer. 8 févr. 2017 10:06

content que ton problème soit résolu !
la principale difficulté d'implémentation d'un langage de haut niveau sur ces toutes petites machines c'est justement la gestion de la mémoire, car le langage permet de faire des choses qui peuvent rapidement dépasser la capacité de la machine, et qui ne seront pas signalées à la compilation tant que le code source respecte le standard C.
sur des machines plus complexes ou disposant d'un système d'exploitation, les problèmes de mémoire sont identifiés à l'exécution, ce qui permet au programmeur d'en être informé et de prévoir leur traitement.
ce n'est pas le cas sur un petit PIC et ça se traduit par un bug. mais l'inconvénient des très petits systèmes est également un avantage : un système clos dont les limites arrivent rapidement est également plus facilement débugable, car il est humainement possible de connaître l'état complet de la machine.
pour éviter les ennuis sur ces petites machines et faciliter la tâche du compilateur, il est préférable de réserver l'espace de stockage des buffers, structures et variables dans l'espace global, comme cela aurait été fait en assembleur, de ne se servir de variables locales que pour des objets de petite taille, et de surveiller de près la réentrance et le niveau de profondeur de la pile de retour d'appels. ceci concerne tout particulièrement les PIC12 et PIC16, dont la gestion de leur RAM non linéaire (organisée en banques) est acrobatique.
A+,
BrunoG
---
Quelques pico-idées en vrac : http:://www.micro-examples.com


Retourner vers « Langage C »

Qui est en ligne

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