Bonjour,
Un truc qui m'échappe, après lecture de ma mémoire pour la première utilisation, j'ai donc du FF partout, je fais en sorte que ce soit le cas, ceci avant le chargement des paramètres.
Dans ce cas là pour charger mes paramètres , réseau notamment je fais un simple teste pour prendre des valeurs par défautCode:nvm_read_data_spi ((char *)&appDataTCPIP_WIFI, sizeof(appDataTCPIP_WIFI)); if (appDataTCPIP_WIFI.pre_utilisation!=0xAA) { sector_erase (); nvm_read_data_spi ((char *)&appDataTCPIP_WIFI, sizeof(appDataTCPIP_WIFI)); }
Par exemple mon SSIDcomme pour tout les autres
En mode débug, j'ai donc bien vérifié si les valeurs 0xFF étaient bien chargé et a priori c'est le cas et je ne comprend pas pourquoi, dans ma condition ne vient par charger la bonne valeur et ne prend pas en compte le 0xFF, fait donc le "else" pour ainsi me charger la valeurCode:if (appDataTCPIP_WIFI.new_SSID[0]==0xFF) strcpy(parametre_wifi.new_SSID,WDRV_DEFAULT_SSID_NAME); else strcpy(parametre_wifi.new_SSID,appDataTCPIP_WIFI.new_SSID);
de parametre_wifi.new_SSID[32]=0xFF;
là comprend pas
Honnêtement, je comprend rien j'ai bien 0xFF et ma condition , simple if fonctionne pas :
pour vérifier la valeur avant comparaison, j'ai créé une variable qui va prendre la valeur à comparer
et j'ai bien verif_val=0xff;Code:verif_val=appDataTCPIP_WIFI.new_SSID[0]; if(appDataTCPIP_WIFI.new_SSID[0]==0xff) { strcpy(parametre_wifi.new_SSID,appDataTCPIP_WIFI.new_SSID); } else { strcpy(parametre_wifi.new_SSID,WDRV_DEFAULT_SSID_NAME); }
mais passe directement au else ????
Problème réglé, c'était le type de variable
Enfin, je sors de 2 mois de galère, mai ma flash fonctionne.
Maintenant je ne vais pas en changer, mais garder celle-ci (:
Bonjour, je reviens sur une question pas très compliqué en soit d'ailleurs, je crois avoir une réponse mais suis pas certains.
Après avoir réussi tant bien que mal à coder l'utilisation de ma flash, celle-ci à des données de ma structure de stocké, seulement je souhaite changer la taille d'un élément de ma structure et j'ai peur que ça désorganise tout lors de la prochaine lecture de ma flash.
Est ce qui risque d'arriver, n'est ce pas ?
Saut, je suis en train de faire la même chose, tout un tas de paramètres stockés en flash.
Pour éviter des désagréments lors du développement :
- une valeur témoin stockée en dernier, pour détecter des changements de taille de la structure.
- une vérification systématique des paramètres après chaque lecture de l'eeprom, et si au moins un n'est pas bon, reset de la structure avec des valeurs par défaut.
Bonjour Satinas, he oui je reviens sur ma flash car ayant donc réussi avec ton aide de sauvegarder ma structure d'environ 340 octet je souhaiterai là mémoriser plusieurs tableau de constante représentatif des codes de sortie IR d'une télécommande.
Jusqu'à là je mémorisais 9 tableaux(9boutons) de 67 caractères de 2 octet dans mon micro, j'aimerai mémoriser d'autre tableau mais je ne passe plus, donc j'aimerai savoir comment mémoriser à un emplacement (derrière mes autres données) mes tableaux en flash externe pour les lire au moment de la commande.
La méthode est différente de l'écriture que je fait habituellement ?
Merci
Bonsoir,
Si ta structure dépasse 256 octets, il faut écrire plusieurs pages.
Pour la lecture, pas de problème car on peut lire toute la flash en une seule commande.
Et si tu as d'autres structures ou tableaux à écrire, tu peux les écrire dans d'autres pages, il y en a 30000 de pages.Code:Struct s; uint32_t adr; // écrire s à l'adresse adr uint8_t* b = (uint8_t*)&s; int nb_to_write = sizeof(s); do { int n = nb_to_write < 256 ? nb_to_write : 256; WriteFlash(adr, b, n); adr += n; b += n; nb_to_write -= n; } while (nb_to_write);
Ma fonction d'écriture de ma structure :
nvm_write_data_spi ((char *)&appDataTCPIP_WIFI, sizeof(appDataTCPIP_WIFI));
et de lecture de ma structure :
nvm_read_data_spi ((char *)&appDataTCPIP_WIFI, sizeof(appDataTCPIP_WIFI));
Alors en fait, je sauvegarde ma structure avec cette fonction :
et je l'a lis avec celle-ci :Code:void nvm_write_data_spi (char *buf, int size) { unsigned long i,j,k; //int status; check1a=0; check2a=0; check3a=0; page_bad=0; page_good=0; i=0; break_l=0; status=1; //1 means memory/code works and 0 means fault has occured. check=0; //keeps track of code progress. tempcheck=1; SPI_WREN(); block_protection_18[0]=0x00; block_protection_18[1]=0x00; block_protection_18[2]=0x00; block_protection_18[3]=0x00; block_protection_18[4]=0x00; block_protection_18[5]=0x00; block_protection_18[6]=0x00; block_protection_18[7]=0x00; block_protection_18[8]=0x00; block_protection_18[9]=0x00; block_protection_18[10]=0x00; block_protection_18[11]=0x00; block_protection_18[12]=0x00; block_protection_18[13]=0x00; block_protection_18[14]=0x00; block_protection_18[15]=0x00; block_protection_18[16]=0x00; block_protection_18[17]=0x00; SPI_WriteBlockProtection(); SPI_Wait_Busy(); SPI_WREN(); SPI_Sector_Erase(0); //Do Sector Erase SPI_Wait_Busy(); i=0; SPI_WREN(); k=0; while(i<size) { for(j=0;j<=255;j++) { data_256[j]=buf[k]; k++; } SPI_WREN(); SPI_Page_Program(i); SPI_Wait_Busy(); i=i+256; break_l=1; } }
Code:void nvm_read_data_spi (char *buf, int size) { unsigned long i,j,k; //int status; check1a=0; check2a=0; check3a=0; page_bad=0; page_good=0; j=0; break_l=0; status=1; //1 means memory/code works and 0 means fault has occured. check=0; //keeps track of code progress. tempcheck=1; SPI_WREN(); j=0; i=0; while (j<size) { SPI_HighSpeed_Read_Cont(j,256); for (k=0;k<=255;k++) { buf[i]=data_256[k]; i++; } j=j+256; break_l=2; } }
Je commence donc à sauvegarder du début de la flash jusqu'à la fin de ma structure donc 346 octet.
J'aimerai donc placer mes autres tableaux IR de ce format à un autre endroit de ma flash que j'appellerai dès le besoin :
Code:uint16_t nov_plus[67]={8960,4520,524,580,548,1710,532,580,548,580,600,528, 532,568,560,572,600,528,532,1710,600,532,528,1700, 612,1630,552,1710,532,1710,600,1630,552,1700,532,1710, 600,528,532,580,540,1710,532,580,548,580,580,552,528, 580,552,580,568,1660,556,1700,532,580,552,1710,532, 1700,580,1660,552,1710,532};
Ma question est dans ma fonction d'écriture, je modifie la totalité de la flash en faisant un erase, il faudrait donc que j'efface seulement les secteurs sur lesquels j'écris pour pas toucher à d'autres secteurs qui seront utiliser.
Je me demandait comment puis-je sauvegarder mes tableaux dans ma flash et à quel moment du programme car comme ça ils sont sauvegarder dans ma mémoire interne du micro (9 tableaux) et sachant que j'en ai 14 à mémoriser ça ferai un peu moins de 2Mo.
Je pourrai commencer la sauvegarde a partir d'un page ?
Si je ne trompe pas avec cette fonction :
Code:SPI_Page_Program(i); void SPI_Page_Program(unsigned long Dst) { unsigned int i; i=0; CE_Low(); /* enable device */ Send_Byte(0x02); /* send Byte Program command */ Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */ Send_Byte(((Dst & 0xFFFF) >> 8)); Send_Byte(Dst & 0xFF); for (i=0;i<256;i++) { Send_Byte(data_256[i]); /* send byte to be programmed */ } CE_High(); /* disable device */ }
Ca serait super si tu fournissais du code présenté et indenté correctement ...
la fonction de lecture peut être simplifiée pour charger les données directement dans la structure ou le tableau, sans passer par un tableau intermédiaire.
la fonction d'écriture de page permet d'écrire un tableau
14 fois 67 octets ça fait donc 2MO, depuis quand ?
Est-ce que tu écris tout en une seule fois, où y-a-t'il des infos écrites à des moment différents ?
soit tu écris tout en une seule fois, sur un seul secteur :
pages 0 et 1 -> structure
pages 2 à 15 -> tableaux
soit tu écris à 2 moments différents, sur 2 secteurs :
pages 0 et 1 -> structure
pages 16 à 29 -> tableaux
Plus simple, un seul tableau :
uint16_t codes[14][67] = { { 8940,4520, ... }, ..., { ... } };
et tu écris ce tableau avec nvm_write_data_spi(), en page 2 ou 16 (voir plus haut)
ok merci je vois ça, je préfère le faire a des moments différent secteurs différent, mais c'est bien cette fonction
SPI_Page_Program(i); qui permet de placer les pages à programmer
comment choisis tu la page 16 ce cas là , ce serait 16*256=4096 donc je me place à
SPI_Page_Program(4096); c'est ça
Quand je dis 2Mo de données : je fais 14 (nbr de tableau)*67 (nbr de données par tableau)*2 (16bits) me trompe-je ? ça fait 1876 octet donc arrondi à 2Mo non ?
Par contre mon soucie du départ, raison pour laquelle je souhaite mettre mes codes en flash c'est que d'autres codes risque de s'ajouter et évidemment mon micro en interne me dis stop.
Je m'explique :
à l'initial je déclarai mes tableaux normalement, comme montré plus haut (donc en mémoire flash interne) et un moment donnée en rajoutant d'autres tableaux , à la compilation on me disait qu'il n'y avait plus de place pour faire fonctionner ma stack TCPIP si j'ai bien compris :
donc je me dis qu'il faudrait donc les mettre en mémoire, et donc charger seulement le tableau (donc le code) appeller par ma commande et non charger la totalité à l'ouverture sinon sauf erreur je me retrouverai avec le même problème qu'a l'initial non ? plus assez de place pour le reste non ?Code:c:\program files (x86)\microchip\xc32\v1.40\bin\bin\gcc\pic32mx\4.8.3\..\..\..\..\bin/xc32-ld.exe Error: Not enough memory for stack (2064 bytes needed, 1944 bytes available) collect2.exe: error: ld returned 255 exit status make[2]: *** [dist/pic32mx_eth_sk+ioexp+11n+freertos/production/pic32_eth_wifi_web_server.X.production.hex] Error 255 make[1]: *** [.build-conf] Error 2 make: *** [.build-impl] Error 2
En fait, je ne perçois pas comment mettre directement mes tableaux en mémoire, a quel moment les charger à la programmation ? ou à chaque initialisation, suis-je claire ? (:
Tu modifies void nvm_write_data_spi (char *buf, int size) en void nvm_write_data_spi (uint32_t adr, uint8_t*buf, int size)
Il faut enlever ce char* pas beau du tout, on stocke des octets pas des caractères.
nvm_write_data_spi (0x0000, (uint8_t*)ma_structure, sizeof(ma_structure));
nvm_write_data_spi (0x1000, (uint8_t*)nov_plus, 67);
ou nvm_write_data_spi (0x1000, (uint8_t*)codes, 14*67);
Si tu as des problèmes de place ram, tu stockes tes codes uniquement en flash. La lecture de la flash est suffisamment rapide pour comparer ton code IR reçu au contenu de la flash.
Si cela doit être évolutif, il faut aussi stocker dans la flash le nombre et la taille des codes IR.
Les évolutions tu les insères comment, c'est à toi de le dire, par le bootloader, par http, par une console série, usb ?
Ou alors tu stockes les codes IR en dur dans le code, je sais plus si sur le pic32, le fait de rajouter const devant une variable suffit pour la mettre dans le code, il faut essayer.
Dans ce cas le stockage des codes IR en flash ne sert plus à rien.
ok apparemment ça fonctionne en mettant le code "const" , qu'est ce que ça veut dire quand on fait comme ça ?
Le compilateur empêchera que l'on modifie toute variable déclarée const.
Avec un peu de chance, le linker placera ces variables const dans la flash du pic.
d'accord satinas, mais pourquoi ça passe maintenant alors que j'avais des erreurs d'espace ?
Il y a la flash et la ram.
La flash stocke en dur le code et les données constantes comme tes pages http.
La ram stocke les variables globales, la pile pour les appels de fonctions et leurs variables locales, et le tas pour les allocations de mémoire dynamiques.
Ton erreur d'espace concernait la ram, et en passant certaines variables globales de la ram vers la flash (cela reste à vérifier), ça soulage la ram.
ok , en tout cas merci encore une fois (:
il me reste à me remettre à continuer sur mon bootloader que je peine à faire, je sais ça traine mais j'ai été pas mal interrompu notamment pour envoyer la matos en certification UL.
Bon allé courage !! (:
Tu modifies void nvm_write_data_spi (char *buf, int size) en void nvm_write_data_spi (uint32_t adr, uint8_t*buf, int size)
Il faut enlever ce char* pas beau du tout, on stocke des octets pas des caractères.
nvm_write_data_spi (0x0000, (uint8_t*)ma_structure, sizeof(ma_structure));
nvm_write_data_spi (0x1000, (uint8_t*)nov_plus, 67);
ou nvm_write_data_spi (0x1000, (uint8_t*)codes, 14*67);
Si tu as des problèmes de place ram, tu stockes tes codes uniquement en flash. La lecture de la flash est suffisamment rapide pour comparer ton code IR reçu au contenu de la flash.
Si cela doit être évolutif, il faut aussi stocker dans la flash le nombre et la taille des codes IR.
Les évolutions tu les insères comment, c'est à toi de le dire, par le bootloader, par http, par une console série, usb ?
Bonjour satinas,
Je souhaite cibler qu'un secteur ( ou seulement les secteurs nécessaires ) en écriture et donc Erase également afin de séparer les données à sauvegarder et donc ne pas effacer toutes la mémoire lors de la sauvegarde.
Ma fonction d'écriture actuel est :
avec ma fonction erase :void nvm_write_data_spi (char *buf, int size)
{
unsigned long i,j,k;
//int status;
check1a=0;
check2a=0;
check3a=0;
page_bad=0;
page_good=0;
i=0;
break_l=0;
status=1; //1 means memory/code works and 0 means fault has occured.
check=0; //keeps track of code progress.
tempcheck=1;
SPI_WREN();
block_protection_18[0]=0x00;
block_protection_18[1]=0x00;
block_protection_18[2]=0x00;
block_protection_18[3]=0x00;
block_protection_18[4]=0x00;
block_protection_18[5]=0x00;
block_protection_18[6]=0x00;
block_protection_18[7]=0x00;
block_protection_18[8]=0x00;
block_protection_18[9]=0x00;
block_protection_18[10]=0x00;
block_protection_18[11]=0x00;
block_protection_18[12]=0x00;
block_protection_18[13]=0x00;
block_protection_18[14]=0x00;
block_protection_18[15]=0x00;
block_protection_18[16]=0x00;
block_protection_18[17]=0x00;
SPI_WriteBlockProtection();
SPI_Wait_Busy();
SPI_WREN();
SPI_Sector_Erase(0); //Do Sector Erase
SPI_Wait_Busy();
i=0;
SPI_WREN();
k=0;
while(i<size)
{
for(j=0;j<=255;j++)
{
data_256[j]=buf[k];
//if (buf[k]==0x0){ goto exit ;}
k++;
}
//exit :
SPI_WREN();
SPI_Page_Program(i);
SPI_Wait_Busy();
i=i+256;
break_l=1;
}
}
Ou bien utiliser :void SPI_Sector_Erase(unsigned long Dst)
{
CE_Low(); /* enable device */
Send_Byte(0x20); /* send Sector Erase command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
CE_High(); /* disable device */
}
Merci de votre éclairagevoid SPI_Block_Erase(unsigned long Dst)
{
CE_Low(); /* enable device */
Send_Byte(0xD8); /* send Block Erase command */
Send_Byte(((Dst & 0xFFFFFF) >> 16)); /* send 3 address bytes */
Send_Byte(((Dst & 0xFFFF) >> 8));
Send_Byte(Dst & 0xFF);
CE_High(); /* disable device */
}
En fait, à quel niveau je met l'adresse de départ et de fin d'effacement et d'écriture ?