1. Должен быть ftp сервер с доступом, на который Вы можете закинуть прощивку. 2. Библиотеки: #include <FS.h> 3. Параметры соединения и данные прошивки: char* xhost = "адрес ftp сервера"; // ftp сервер char* xusername = "логин сервера"; // логин ftp char* xpassword = "пароль сервера"; // пароль ftp char* xfolder = "папка с прошивкой на ftp сервере"; // папка с прошивками на ftp char* xfilename = "esp_fw.bin"; // имя файла на сервере Ftp char* xfile = "fw.bin"; // имя файла в файловой системе (с ftp сперва будем копировать на esp во флеш (скачивать)) 4. Переменные и функции: short FTPresult; // пепременная для результатов ftp запросов short doFTP(char* , char* , char* , char*, char* , char* = ""); // функция скачивания файла с ftp на флеш esp8266 short eRcv(WiFiClient aclient, char outBuf[], int size); // обработка ftp запросов 5. Функция закачки файла на флеш с ftp: short doFTP(char* host, char* unam
1. Должен быть ftp сервер с доступом, на который Вы можете закинуть прощивку. 2. Библиотеки: #include <FS.h> 3. Параметры соединения и данные прошивки: char* xhost = "адрес ftp сервера"; // ftp сервер char* xusername = "логин сервера"; // логин ftp char* xpassword = "пароль сервера"; // пароль ftp char* xfolder = "папка с прошивкой на ftp сервере"; // папка с прошивками на ftp char* xfilename = "esp_fw.bin"; // имя файла на сервере Ftp char* xfile = "fw.bin"; // имя файла в файловой системе (с ftp сперва будем копировать на esp во флеш (скачивать)) 4. Переменные и функции: short FTPresult; // пепременная для результатов ftp запросов short doFTP(char* , char* , char* , char*, char* , char* = ""); // функция скачивания файла с ftp на флеш esp8266 short eRcv(WiFiClient aclient, char outBuf[], int size); // обработка ftp запросов 5. Функция закачки файла на флеш с ftp: short doFTP(char* host, char* unam
...Читать далее
1. Должен быть ftp сервер с доступом, на который Вы можете закинуть прощивку.
2. Библиотеки:
#include <FS.h>
3. Параметры соединения и данные прошивки:
char* xhost = "адрес ftp сервера"; // ftp сервер
char* xusername = "логин сервера"; // логин ftp
char* xpassword = "пароль сервера"; // пароль ftp
char* xfolder = "папка с прошивкой на ftp сервере"; // папка с прошивками на ftp
char* xfilename = "esp_fw.bin"; // имя файла на сервере Ftp
char* xfile = "fw.bin"; // имя файла в файловой системе (с ftp сперва будем копировать на esp во флеш (скачивать))
4. Переменные и функции:
short FTPresult; // пепременная для результатов ftp запросов
short doFTP(char* , char* , char* , char*, char* , char* = ""); // функция скачивания файла с ftp на флеш esp8266
short eRcv(WiFiClient aclient, char outBuf[], int size); // обработка ftp запросов
5. Функция закачки файла на флеш с ftp:
- соединение с сервером
short doFTP(char* host, char* uname, char* pwd, char* fileName, char* fNameMem, char* folder)
{
WiFiClient ftpclient;
WiFiClient ftpdclient;
const short FTPerrcode = 400; //error codes are > 400
const byte Bufsize = 128;
char outBuf[Bufsize];
short FTPretcode = 0;
const byte port = 21; //21 is the standard connection port
WiFiClient dataClient;
// попытка подключения к серверу
if (ftpclient.connect(host,port)) {
Serial.println(F("Connected to FTP server"));
}
else {
Serial.println(F("Failed to connect to FTP server"));
return 910;
}
FTPretcode = eRcv(ftpclient,outBuf,Bufsize);
if(FTPretcode >= 400) return FTPretcode;
// авторизация на сервере ftp
ftpclient.print("USER ");
ftpclient.println(uname);
FTPretcode = eRcv(ftpclient,outBuf,Bufsize);
if(FTPretcode >= 400) return FTPretcode;
/* PASS - Authentication password
* After sending the USER command, send this command to complete
* the login process. (Note, however, that an ACCT command may have to be
* used on some systems, not needed with synology diskstation)
*/
ftpclient.print("PASS ");
ftpclient.println(pwd);
FTPretcode = eRcv(ftpclient,outBuf,Bufsize);
if(FTPretcode >= 400) return FTPretcode;
//CWD - Change the working folder on the FTP server
// переход в заданную папку
if(!(folder == "")) {
ftpclient.print("CWD ");
ftpclient.println(folder);
FTPretcode = eRcv(ftpclient,outBuf,Bufsize);
if(FTPretcode >= 400) {return FTPretcode;}
}
// определение кодировки обмане данными
/* SYST - Returns a word identifying the system, the word "Type:",
* and the default transfer type (as would be set by the
* TYPE command). For example: UNIX Type: L8 - this is what
* the diskstation returns
*/
/*ftpclient.println("SYST");
FTPretcode = eRcv(ftpclient,outBuf,Bufsize);
if(FTPretcode >= 400) return FTPretcode;*/
// определение типа данных на ftp
/* TYPE - sets the transfer mode
* A - ASCII text
* E - EBCDIC text
* I - image (binary data)
* L - local format
* for A & E, second char is:
* N - Non-print (not destined for printing). This is the default if
* second-type-character is omitted
* Telnet format control (<CR>, <FF>, etc.)
* C - ASA Carriage Control
*/
ftpclient.println("Type I");
FTPretcode = eRcv(ftpclient,outBuf,Bufsize);
if(FTPretcode >= 400) return FTPretcode;
// пассивный режим обмена данными с ftp. В ответ получаем адрес/порт
ftpclient.println("PASV");
FTPretcode = eRcv(ftpclient,outBuf,Bufsize);
if(FTPretcode >= 400) return FTPretcode;
char *tStr = strtok(outBuf,"(,"); //chop the output buffer into tokens based on the delimiters
int array_pasv[6];
for ( int i = 0; i < 6; i++) { //there are 6 elements in the address to decode
tStr = strtok(NULL,"(,"); //1st time in loop 1st token, 2nd time 2nd token, etc.
array_pasv[i] = atoi(tStr); //convert to int, why atoi - because it ignores any non-numeric chars
//after the number
if(tStr == NULL) {Serial.println(F("Bad PASV Answer"));}
}
//extract data port number
unsigned int hiPort,loPort;
hiPort=array_pasv[4]<<8; //bit shift left by 8
loPort=array_pasv[5]&255;//bitwise AND
Serial.print(F("Data port: "));
hiPort = hiPort|loPort; //bitwise OR
Serial.println(hiPort);
//first instance of dftp
if(ftpdclient.connect(host, 21)){Serial.println(F("Data port connected"));}
else {
Serial.println(F("Data connection failed"));
ftpclient.stop();
// ftx.close();
}
// получение размера файла на ftp сервере
if (dataClient.connect(host,hiPort)) {
Serial.println("Data connection established");
ftpclient.println("SIZE " + String(fileName));
FTPretcode = eRcv(ftpclient,outBuf,Bufsize);
Serial.println(FTPretcode);
char *tStr = strtok(outBuf," ");
Serial.print("code:");Serial.println(tStr);
tStr = strtok(NULL," ");
Serial.print("sizelong:");Serial.println(atol(tStr));
long s_ = atol(tStr);
// чтение файла и перенос данных на esp
ftpclient.println("RETR " + String(fileName));
String response = ftpclient.readStringUntil('\n');
Serial.println("RETR Response: " + response);
Serial.println("File content:");
// открываем файл для записи и переносим в него данные с ftp
// данные переносятся по 100 байт, концовка по 1 байту
File fsUploadFile = SPIFFS.open(fNameMem, "w");
byte size_max_buffer = 100;
char buffer_[size_max_buffer];//[21];
char buffer_1[1];
long t = 0;
s_ = s_/size_max_buffer;
Serial.println(s_);
long percent = 0;
long percent_prev = 0;
while (dataClient.connected() || dataClient.available()) {
if (dataClient.available()) {
// запись в файл участков по 100 байт
if (t < s_)
{
size_t bytes_read = dataClient.readBytes(buffer_, size_max_buffer);
t++;
percent = t * 100/s_;
if (percent > percent_prev)
{
Serial.print(percent); Serial.println("%");
tft.fillRect(keyb_panel_left, 50, 480-keyb_panel_left - 1, 100, TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setCursor(keyb_panel_left + 3, 50 + 3, 2);
tft.print("download: ");
tft.print(percent);
tft.print("%");
}
percent_prev = percent;
fsUploadFile.write(buffer_, bytes_read);
}
else // запись в файл остатка по 1 байту
{
size_t bytes_read = dataClient.readBytes(buffer_1, 1);
//buffer_[bytes_read] = '\0';
t++;
fsUploadFile.write(buffer_1, bytes_read);
}
}
delay(1);
}
if(fsUploadFile) fsUploadFile.close();
dataClient.stop();
// выводим данные о файлах на флеш и их размере (справочно можно убрать)
String str = "";
Dir dir = SPIFFS.openDir("");
while (dir.next()) {
str += dir.fileName();
str += " / ";
str += dir.fileSize();
str += "\r\n";}
Serial.print(str);
Serial.println("--------------------------------");
Serial.println("\nData connection closed");
} else {
Serial.println("Data connection failed");
}
//разрыв соединения, завершение сессии
ftpclient.println("QUIT");
ftpclient.stop();
Serial.println(F("Disconnected from FTP server"));
Serial.println(F("File closed"));
return FTPretcode;
} // end function doFTP
Далее создаем ффункцию обновления прошивки esp, в начале которой вызывается функция загрузки файла с ftp на flash память esp
void update_esp()
{
// загрузка прошивки с ftp на esp
FTPresult = doFTP(xhost,xusername,xpassword,xfilename, xfile, xfolder);
Serial.print("Return code = ");
Serial.println(FTPresult);
if (FTPresult == 213)
{
// Обновление прошивки
File file = SPIFFS.open(xfile, "r");
uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
if (!Update.begin(maxSketchSpace, U_FLASH)) { //start with max available size
Update.printError(Serial);
Serial.println("ERROR");
}
else
{
Serial.println("start");
}
if (file.available())
{
Serial.println("file ok");
long size_ = file.size();
long size_wr = 0;
long percent, percent_prev = 0;
while (file.available()) {
size_wr += 128;
percent = size_wr * 100 / size_;
if (percent > percent_prev)
{ Serial.print(percent); Serial.println("%");
tft.fillRect(keyb_panel_left, 70, 480-keyb_panel_left - 1, 100, TFT_WHITE);
tft.setTextColor(TFT_BLACK, TFT_WHITE);
tft.setCursor(keyb_panel_left + 3, 70 + 3, 2);
tft.print("update: ");
tft.print(percent);
tft.print("%");
}
percent_prev = percent;
uint8_t ibuffer[128];
file.read((uint8_t *)ibuffer, 128);
Update.write(ibuffer, sizeof(ibuffer));
}
file.close();
Serial.print(Update.end(true));
delay(1);
ESP.restart(); // перезагрузка esp после обновления прошивки
}
}
}
Вот и всё. Данный код позволит обеспечить обновление прошивки с ftp сервера...