Go Down

Topic: Need to declare some variable as volatile for DUE but not for MEGA (Read 605 times) previous topic - next topic

Pierre83

Using DUE + Ethernet shield, my FTP code is running for a long time on MEGA, I tried with the DUE and I have been obliged to declare some variables as volatile to avoid errors when running on DUE.

Did someone having advices or information about this ?
Moreover, is it normal ?

Pierre

pert

It would probably be helpful if you posted a minimal complete sketch that demonstrates the issue as well as the full error output.

Pierre83

Hello, here after the part of the problematic code:

Explanation:
"FTP_start_time" has been declared as volatile because it's value was lost when the return is done, the same for "FTP_port"


Code: [Select]
// ===========================================   F T P   ===========================================

volatile int FTP_port = 0;  // Port Freebox data en retour de la demande de connexion de l'Arduino


// ****************************************************************
boolean FTP_appel(byte FTP_file_number, char *enregistrement)
{
  static unsigned long int FTP_temps_total = 0;
  volatile unsigned long int FTP_start_time = millis();
  unsigned long int FTP_temps_operation = 0;
  if ( socket_check_status() > 2 ) {  // pas assez de sockets libres
    FTP_erreurs++;
    return 0;
  }
  int retour = FTP_action(FTP_file_number, enregistrement);
  if ( retour != 255 ) FTP_cloture();  // sur le  ftp_command.connect(FREEBOX, 21)
  FTP_temps_operation = millis() - FTP_start_time;
  socket_check_status();
  if (bitRead(debug_status, DEBUG_FTP)) {
    SerialUSB.print(F("Temps FTP: "));
    affiche_temps_mesure(FTP_temps_operation, 1);
  }
  if (retour) {
    FTP_erreur(retour);
    FTP_erreurs++;
    return 0;
  }
  FTP_count++;
  if ( FTP_temps_operation < 10000 ) { // cas ou le temps est trop long
    FTP_temps_total += FTP_temps_operation; // Memorisation maxi-mini
    FTP_temps_moyen = FTP_temps_total / FTP_count;
    if (FTP_temps_maxi < FTP_temps_operation) FTP_temps_maxi = FTP_temps_operation;
    if (FTP_temps_mini > FTP_temps_operation) FTP_temps_mini = FTP_temps_operation;
  } else {
    //SerialUSB.print(F("Temps FTP anormal"));
  }
  return 1;
}

// ****************************************************************
int FTP_action(byte FTP_file_number, char *FTP_record)
{
  char FTP_file_name[50];
  int statut;
  strcpy (FTP_file_name, "APPE /Disque dur/Pierre/meteolog.");
  //strcat (FTP_file_name, FTP_REPOS);
  strcat (FTP_file_name, FTP_FILES_NAMES[FTP_file_number]);
  ftp_command.connect(FREEBOX, 21);
  statut = FTP_reception();
  if (statut != 220 ) return statut;
  ftp_command.println(F("USER freebox"));
  statut = FTP_reception();
  if (statut != 331 ) return (statut + 1000);
  ftp_command.println(F("PASS 1234"));
  statut = FTP_reception();
  if (statut != 230 ) return (statut + 2000);
  ftp_command.println(F("PASV"));
  statut = FTP_reception();
  if (statut != 227 ) return (statut + 3000);
  statut = ftp_data.connect(FREEBOX, FTP_port);
  if ( statut != 1 ) return ( statut + 4000 );  //  SUCCESS 1, TIMED_OUT -1, INVALID_SERVER -2, TRUNCATED -3, INVALID_RESPONSE -4
  if ( bitRead(debug_status, DEBUG_FTP )) SerialUSB.println(FTP_file_name);
  ftp_command.println(FTP_file_name);
  statut = FTP_reception();
  if (statut != 150 ) {
    //ftp_data.stop();  // cloture du canal data sans vérification en cas de problème sur ouverture fichier
    return (statut + 5000);
  }
  statut = ftp_data.println(FTP_record);  // Returns the number of bytes written
  int temporaire = strlen(FTP_record) + 2 ;   // +2 = CR + LF
  if ( statut != temporaire) return ( 6000 );
  return 0;
}

// ****************************************************************
int FTP_reception()
{
  const int  FTP_TIMEOUT = 2500;
  char buffer_Ethernet[128], code[4];
  uint8_t inCount = 0;
  uint8_t port_data[6];
  memset (buffer_Ethernet, 0, 128);
  unsigned long int FTP_temps_reception, start_waiting_at = millis();
  while (!ftp_command.available()) {
    if ((millis() - FTP_TIMEOUT) > start_waiting_at) break;
  }
  if ( (millis() - FTP_TIMEOUT) < start_waiting_at ) {
    while (ftp_command.available()) {
      buffer_Ethernet[inCount] = ftp_command.read();
      inCount++;
    }
    if (bitRead(debug_status, DEBUG_FTP)) {
      FTP_temps_reception = millis() - start_waiting_at;
      SerialUSB.print(F("Serveur FTP: "));
      affiche_temps_mesure( FTP_temps_reception , 1 );  // Temps de réponse du serveur
      SerialUSB.println(buffer_Ethernet);
    }
    memcpy (code, buffer_Ethernet, 3);
    code[3] = 0;
    int code_retour = atoi(code);
    if ( code_retour == 227 ) {
      char *tStr = strtok(buffer_Ethernet, "(,");// cherche xxx et yyy dans "227 PASV OK (192,168,0,254,xxx,yyy)"
      for ( uint8_t i = 0; i < 6; i++) {
        tStr = strtok(NULL, "(,");
        port_data[i] = atoi(tStr);
      }
      FTP_port = word( port_data[4], port_data[5] );
    }
    return code_retour;
  } else {
    if (bitRead(debug_status, DEBUG_FTP)) SerialUSB.println(F("FTP Timeout"));
    return 255;
  }
}

// ****************************************************************
void FTP_cloture()
{
  char buffer_Ethernet[128];
  int statut, count = 0;;
  unsigned long int FTP_temps_reception = millis(), start = millis();
  if (ftp_data.connected()) {
    ftp_data.stop();  // Freebox = environ 195ms pour clore canal data
    FTP_temps_reception = millis();
    if ( !bitRead(flags_fonctionnement, FTP_FAST ) ) {
      statut = FTP_reception();
      FTP_temps_reception = millis() ;
      if ( statut != 226 ) {
        FTP_erreur(statut + 7000);
        FTP_erreurs++;
      }
    }
    if (bitRead(debug_status, DEBUG_FTP)) SerialUSB.println(F("FTP D clot"));
  }
  if (bitRead(debug_status, DEBUG_FTP)) {
    SerialUSB.print(F("Temps: "));
    affiche_temps_mesure( (FTP_temps_reception - start) , 1 );
    start = millis();
  }
  ftp_command.println(F("QUIT"));
  while (ftp_command.available()) {
    buffer_Ethernet[count++] = ftp_command.read();
    if ( count < 127 ) count++;
  }
  FTP_temps_reception = millis() ;
  if (bitRead(debug_status, DEBUG_FTP)) {
    SerialUSB.print(F("Rcv: "));
    SerialUSB.println(buffer_Ethernet);
    SerialUSB.println(F("FTP C clot"));
    SerialUSB.print(F("Temps: "));
    affiche_temps_mesure( (FTP_temps_reception - start) , 1 );
  }
  ftp_command.stop();  // on ne vérifie pas si connecté car pas fiable à 100%
}

MorganS

FTP_start_time is local to FTP_appel(). If you were expecting to use this variable outside of that function then the compiler should be showing you an error or you have a second definition of it in another scope.

FTP_port gets set once, when you receive a 227 status. It gets used 2 lines later. I don't see any problem that indicates this would not work without the volatile storage class.

Perhaps the problem is in the code you didn't post?
"The problem is in the code you didn't post."

Pierre83

@MorganS

Thanks for your answer.


Yes, FTP_start_time is local to FTP_appel(). It's not used outside and don't need to be declared as volatile except for the DUE ( the MEGA did'nt). Don't ask me why.

For FTP_port, i discovered that the DUE is not able to catch some answers from the Freebox, particularly on the connect command and the port answer, so I modified the code to avoid this strange behavior...

Now with volatile variable and using the test of the connect command ( test if = 1 and not testing that Freebox' answer is 220...)  the DUE works a little more better, but some events related to the anemometer are still missed, a lot more than the Mega.

Pierre

Go Up