mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-04-06 00:59:26 +03:00
@@ -1,47 +1,44 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/*
|
/*
|
||||||
* Здесь хранятся все настройки прошивки
|
* Main consts
|
||||||
*/
|
*/
|
||||||
#define firmware_version "2.3.4"
|
#define FIRMWARE_VERSION "2.3.4"
|
||||||
#define NUM_BUTTONS 6
|
#define NUM_BUTTONS 6
|
||||||
#define mb_4_of_memory 1
|
#define LED_PIN 2
|
||||||
#define wifi_mqtt_reconnecting 20000
|
#define FLASH_4MB true
|
||||||
#define blink_pin 2
|
#define MQTT_RECONNECT_INTERVAL 20000
|
||||||
#define tank_level_times_to_send 10 //после скольки выстрелов делать отправку данных
|
// 1000 * 60 * 60 * 2
|
||||||
#define statistics_update 1000 * 60 * 60 * 2
|
#define TELEMETRY_UPDATE_INTERVAL 0
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Optional
|
* Optional
|
||||||
*/
|
*/
|
||||||
//#define OTA_enable
|
//#define OTA_UPDATES_ENABLED
|
||||||
//#define MDNS_enable
|
//#define MDNS_ENABLED
|
||||||
//#define WS_enable
|
//#define WEBSOCKET_ENABLED
|
||||||
//#define layout_in_ram
|
//#define LAYOUT_IN_RAM
|
||||||
#define UDP_enable
|
#define UDP_ENABLED
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sensor
|
* Sensor
|
||||||
*/
|
*/
|
||||||
#define level_enable
|
#define TANK_LEVEL_SAMPLES 10
|
||||||
#define analog_enable
|
#define LEVEL_ENABLED
|
||||||
#define dallas_enable
|
#define ANALOG_ENABLED
|
||||||
#define dht_enable
|
#define DALLAS_ENABLED
|
||||||
#define bmp_enable
|
#define DHT_ENABLED
|
||||||
#define bme_enable
|
#define BMP_ENABLED
|
||||||
|
#define BME_ENABLED
|
||||||
/*
|
|
||||||
* Logging
|
|
||||||
*/
|
|
||||||
#define logging_enable
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Gears
|
* Gears
|
||||||
*/
|
*/
|
||||||
#define stepper_enable
|
#define STEPPER_ENABLED
|
||||||
#define servo_enable
|
#define SERVO_ENABLED
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Other
|
* Other
|
||||||
*/
|
*/
|
||||||
#define serial_enable
|
#define LOGGING_ENABLED
|
||||||
#define push_enable
|
#define SERIAL_ENABLED
|
||||||
|
#define PUSH_ENABLED
|
||||||
|
|||||||
@@ -1,18 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
#include <AsyncTCP.h>
|
// don't change order
|
||||||
|
#include "WiFi.h"
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "ESPAsyncWebServer.h"
|
||||||
|
#include "SPIFFSEditor.h"
|
||||||
|
// don't change order
|
||||||
#include <AsyncUDP.h>
|
#include <AsyncUDP.h>
|
||||||
#include <ESP32Servo.h>
|
#include <ESP32Servo.h>
|
||||||
#include <HTTPClient.h>
|
#include <HTTPClient.h>
|
||||||
#include <HTTPUpdate.h>
|
#include <HTTPUpdate.h>
|
||||||
#include <LittleFS.h>
|
|
||||||
|
//
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#include <analogWrite.h>
|
#include <analogWrite.h>
|
||||||
|
|
||||||
#ifdef MDNS_enable
|
#ifdef MDNS_ENABLED
|
||||||
#include <ESPmDNS.h>
|
#include <ESPmDNS.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern AsyncUDP udp;
|
extern AsyncUDP udp;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1,13 +1,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
|
|
||||||
#include <ESP8266HTTPClient.h>
|
#include <ESP8266HTTPClient.h>
|
||||||
#include <ESP8266HTTPUpdateServer.h>
|
#include <ESP8266HTTPUpdateServer.h>
|
||||||
#include <ESP8266httpUpdate.h>
|
#include <ESP8266httpUpdate.h>
|
||||||
|
#include <ESPAsyncWebServer.h>
|
||||||
|
#include <LittleFS.h>
|
||||||
|
#include <SPIFFSEditor.h>
|
||||||
#include <Servo.h>
|
#include <Servo.h>
|
||||||
#include <WiFiUdp.h>
|
#include <WiFiUdp.h>
|
||||||
|
#ifdef MDNS_ENABLED
|
||||||
#ifdef MDNS_enable
|
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -3,17 +3,13 @@
|
|||||||
/*
|
/*
|
||||||
* Libraries
|
* Libraries
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <ESP8266HTTPUpdateServer.h>
|
|
||||||
#include <ESPAsyncWebServer.h>
|
|
||||||
#include <LittleFS.h>
|
|
||||||
#include <SPIFFSEditor.h>
|
|
||||||
|
|
||||||
|
#include "ESP32.h"
|
||||||
|
#include "ESP8266.h"
|
||||||
|
//
|
||||||
#include "Consts.h"
|
#include "Consts.h"
|
||||||
#include "ESP32_Spec.h"
|
|
||||||
#include "ESP8266_Spec.h"
|
|
||||||
#include "Errors.h"
|
#include "Errors.h"
|
||||||
#include "GyverFilters.h"
|
#include "GyverFilters.h"
|
||||||
#include "UptimeInterval.h"
|
#include "UptimeInterval.h"
|
||||||
@@ -34,7 +30,7 @@
|
|||||||
#include <TickerScheduler.h>
|
#include <TickerScheduler.h>
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifdef OTA_enable
|
#ifdef OTA_UPDATES_ENABLED
|
||||||
#include <ArduinoOTA.h>
|
#include <ArduinoOTA.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -42,7 +38,7 @@
|
|||||||
* Objects.h(без данных)
|
* Objects.h(без данных)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef WS_enable
|
#ifdef WEBSOCKET_ENABLED
|
||||||
extern AsyncWebSocket ws;
|
extern AsyncWebSocket ws;
|
||||||
//extern AsyncEventSource events;
|
//extern AsyncEventSource events;
|
||||||
#endif
|
#endif
|
||||||
@@ -164,9 +160,6 @@ extern void Scenario_init();
|
|||||||
extern void txtExecution(String file);
|
extern void txtExecution(String file);
|
||||||
extern void stringExecution(String str);
|
extern void stringExecution(String str);
|
||||||
|
|
||||||
// FileSystem
|
|
||||||
extern void File_system_init();
|
|
||||||
|
|
||||||
// i2c_bu
|
// i2c_bu
|
||||||
extern void do_i2c_scanning();
|
extern void do_i2c_scanning();
|
||||||
extern String i2c_scan();
|
extern String i2c_scan();
|
||||||
@@ -187,7 +180,7 @@ extern void choose_log_date_and_send();
|
|||||||
|
|
||||||
// Main
|
// Main
|
||||||
extern void setChipId();
|
extern void setChipId();
|
||||||
extern void getMemoryLoad(String text);
|
extern void printMemoryStatus(String text);
|
||||||
extern void saveConfig();
|
extern void saveConfig();
|
||||||
extern String getURL(const String &urls);
|
extern String getURL(const String &urls);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,30 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <FS.h>
|
|
||||||
|
#include "FS.h"
|
||||||
|
|
||||||
|
#ifdef ESP32
|
||||||
|
#include "LITTLEFS.h"
|
||||||
|
#define LittleFS LITTLEFS
|
||||||
|
#endif
|
||||||
|
#ifdef ESP8266
|
||||||
|
#include <LittleFS.h>
|
||||||
|
#endif
|
||||||
|
/*
|
||||||
|
* Инициализация ФС
|
||||||
|
*/
|
||||||
|
bool fileSystemInit();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Удалить файл
|
||||||
|
*/
|
||||||
|
void removeFile(const String filename);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Открыть файл на позиции
|
||||||
|
*/
|
||||||
|
File seekFile(const String filename, size_t position = 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Чтение строки из файла
|
* Чтение строки из файла
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#ifdef ESP8266
|
||||||
#include <TZ.h>
|
#include <TZ.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
void Time_Init();
|
void Time_Init();
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ class AsyncResponseStream;
|
|||||||
#ifdef ESP8266WEBSERVER_H
|
#ifdef ESP8266WEBSERVER_H
|
||||||
#define HTTP_ENUM
|
#define HTTP_ENUM
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HTTP_ENUM
|
#ifndef HTTP_ENUM
|
||||||
typedef enum { HTTP_GET = 0b00000001,
|
typedef enum { HTTP_GET = 0b00000001,
|
||||||
HTTP_POST = 0b00000010,
|
HTTP_POST = 0b00000010,
|
||||||
@@ -75,7 +77,6 @@ typedef enum { HTTP_GET = 0b00000001,
|
|||||||
HTTP_ANY = 0b01111111,
|
HTTP_ANY = 0b01111111,
|
||||||
} WebRequestMethod;
|
} WebRequestMethod;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
//if this value is returned when asked for data, packet will not be sent and you will be asked for data again
|
//if this value is returned when asked for data, packet will not be sent and you will be asked for data again
|
||||||
#define RESPONSE_TRY_AGAIN 0xFFFFFFFF
|
#define RESPONSE_TRY_AGAIN 0xFFFFFFFF
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
#ifndef SPIFFSEditor_H_
|
#ifndef SPIFFSEditor_H_
|
||||||
#define SPIFFSEditor_H_
|
#define SPIFFSEditor_H_
|
||||||
#include <ESPAsyncWebServer.h>
|
#include <ESPAsyncWebServer.h>
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
#include <LittleFS.h>
|
#include <LittleFS.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
class SPIFFSEditor : public AsyncWebHandler {
|
class SPIFFSEditor : public AsyncWebHandler {
|
||||||
private:
|
private:
|
||||||
|
|||||||
339
lib/LITTLEFS/LICENSE
Normal file
339
lib/LITTLEFS/LICENSE
Normal file
@@ -0,0 +1,339 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
||||||
59
lib/LITTLEFS/README.md
Normal file
59
lib/LITTLEFS/README.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# LITTLEFS
|
||||||
|
## LittleFS library for arduino-esp32
|
||||||
|
|
||||||
|
#### Warning: Tested only with git arduino-esp32 #b92c58d core, which is for ESP-IDF 3.3! </br> With other versions/releases of the core including release 1.0.4, especially against different IDF this will NOT not work.
|
||||||
|
|
||||||
|
- A LittleFS wrapper for Arduino ESP32 of [Mbed LittleFS](https://github.com/ARMmbed/littlefs)
|
||||||
|
- Based on [ESP-IDF port of joltwallet/esp_littlefs](https://github.com/joltwallet/esp_littlefs) , thank you Brian!
|
||||||
|
- Functionality is the same and SPIFFS partition scheme and data folder meaning are kept
|
||||||
|
- You can use either LITTLEFS or SPIFFS but not both simultaneously on given Arduino project
|
||||||
|
- A PR to embed it to esp32 core is made too. See the [PR status here](https://github.com/espressif/arduino-esp32/pull/4096)
|
||||||
|
|
||||||
|
### Installation
|
||||||
|
|
||||||
|
- Copy <b>LITTLEFS</b> folder to Arduino IDE embedded libraries place
|
||||||
|
- For Win, the default place of arduino-esp32 core libraries is somewhere like:
|
||||||
|
```C:\Users\<username>\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.4\libraries ```
|
||||||
|
- Alternatively, you can put it to your usual libraries place
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
- In your existing code, replace SPIFFS like this
|
||||||
|
```
|
||||||
|
#define USE_LittleFS
|
||||||
|
|
||||||
|
#include <FS.h>
|
||||||
|
#ifdef USE_LittleFS
|
||||||
|
#define SPIFFS LITTLEFS
|
||||||
|
#include <LITTLEFS.h>
|
||||||
|
#else
|
||||||
|
#include <SPIFFS.h>
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
### Differences with SPIFFS (and in this implementation)
|
||||||
|
|
||||||
|
- LittleFS has folders, you my need to tweak your code to iterate files in folders
|
||||||
|
- Root: /someting = something, so attention to /
|
||||||
|
- Lower level littlefs library cannot mount on NULL as partition_label name, while SPIFFS can
|
||||||
|
- Lower level littlefs library does not need maxOpenFiles parameter
|
||||||
|
- Speed (LITTLEFS_Test.ino) 1048576 bytes written in 16238 ms / 1048576 bytes read in 918 ms
|
||||||
|
- Speed (SPIFFS_Test.ino) 1048576 bytes written in 65971 ms / 1048576 bytes read in 680 ms
|
||||||
|
|
||||||
|
|
||||||
|
### Arduino ESP32 LittleFS filesystem upload tool
|
||||||
|
|
||||||
|
- Download the tool archive from [here](https://github.com/lorol/arduino-esp32littlefs-plugin/raw/master/src/bin/esp32littlefs.jar)
|
||||||
|
- In your Arduino sketchbook directory, create tools directory if it doesn't exist yet.
|
||||||
|
- Unpack the tool into tools directory (the path will look like ```<home_dir>/Arduino/tools/ESP32LittleFS/tool/esp32littlefs.jar```).
|
||||||
|
- You need the [mklittlefs tool](https://github.com/earlephilhower/mklittlefs) Download the [release](https://github.com/earlephilhower/mklittlefs/releases) and copy it to
|
||||||
|
packages\esp32\tools\mkspiffs\<mklittlefs rev. x.x.x>\ or on checkout (dev) environment to: packages\esp32\hardware\esp32\<release>\tools\mklittlefs\
|
||||||
|
- Restart Arduino IDE.
|
||||||
|
|
||||||
|
## Credits and license
|
||||||
|
|
||||||
|
- This work is based on [Mbed LittleFS](https://github.com/ARMmbed/littlefs) , [ESP-IDF port of joltwallet/esp_littlefs](https://github.com/joltwallet/esp_littlefs) , [Espressif Arduino core for the ESP32, the ESP-IDF - SPIFFS Library](https://github.com/espressif/arduino-esp32/tree/master/libraries/SPIFFS)
|
||||||
|
- Licensed under GPL v2 ([text](LICENSE))
|
||||||
|
|
||||||
|
## To Do
|
||||||
|
|
||||||
|
- Supporting different IDF versions
|
||||||
182
lib/LITTLEFS/examples/LittleFS_test/LittleFS_test.ino
Normal file
182
lib/LITTLEFS/examples/LittleFS_test/LittleFS_test.ino
Normal file
@@ -0,0 +1,182 @@
|
|||||||
|
#include <Arduino.h>
|
||||||
|
#include "FS.h"
|
||||||
|
#include <LITTLEFS.h>
|
||||||
|
|
||||||
|
/* You only need to format SPIFFS the first time you run a
|
||||||
|
test or else use the LITTLEFS plugin to create a partition
|
||||||
|
https://github.com/me-no-dev/arduino-esp32fs-plugin */
|
||||||
|
#define FORMAT_LITTLEFS_IF_FAILED true
|
||||||
|
|
||||||
|
void listDir(fs::FS &fs, const char * dirname, uint8_t levels){
|
||||||
|
Serial.printf("Listing directory: %s\r\n", dirname);
|
||||||
|
|
||||||
|
File root = fs.open(dirname);
|
||||||
|
if(!root){
|
||||||
|
Serial.println("- failed to open directory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(!root.isDirectory()){
|
||||||
|
Serial.println(" - not a directory");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
File file = root.openNextFile();
|
||||||
|
while(file){
|
||||||
|
if(file.isDirectory()){
|
||||||
|
Serial.print(" DIR : ");
|
||||||
|
Serial.println(file.name());
|
||||||
|
if(levels){
|
||||||
|
listDir(fs, file.name(), levels -1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Serial.print(" FILE: ");
|
||||||
|
Serial.print(file.name());
|
||||||
|
Serial.print("\tSIZE: ");
|
||||||
|
Serial.println(file.size());
|
||||||
|
}
|
||||||
|
file = root.openNextFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void readFile(fs::FS &fs, const char * path){
|
||||||
|
Serial.printf("Reading file: %s\r\n", path);
|
||||||
|
|
||||||
|
File file = fs.open(path);
|
||||||
|
if(!file || file.isDirectory()){
|
||||||
|
Serial.println("- failed to open file for reading");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.println("- read from file:");
|
||||||
|
while(file.available()){
|
||||||
|
Serial.write(file.read());
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeFile(fs::FS &fs, const char * path, const char * message){
|
||||||
|
Serial.printf("Writing file: %s\r\n", path);
|
||||||
|
|
||||||
|
File file = fs.open(path, FILE_WRITE);
|
||||||
|
if(!file){
|
||||||
|
Serial.println("- failed to open file for writing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(file.print(message)){
|
||||||
|
Serial.println("- file written");
|
||||||
|
} else {
|
||||||
|
Serial.println("- write failed");
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void appendFile(fs::FS &fs, const char * path, const char * message){
|
||||||
|
Serial.printf("Appending to file: %s\r\n", path);
|
||||||
|
|
||||||
|
File file = fs.open(path, FILE_APPEND);
|
||||||
|
if(!file){
|
||||||
|
Serial.println("- failed to open file for appending");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(file.print(message)){
|
||||||
|
Serial.println("- message appended");
|
||||||
|
} else {
|
||||||
|
Serial.println("- append failed");
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void renameFile(fs::FS &fs, const char * path1, const char * path2){
|
||||||
|
Serial.printf("Renaming file %s to %s\r\n", path1, path2);
|
||||||
|
if (fs.rename(path1, path2)) {
|
||||||
|
Serial.println("- file renamed");
|
||||||
|
} else {
|
||||||
|
Serial.println("- rename failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void deleteFile(fs::FS &fs, const char * path){
|
||||||
|
Serial.printf("Deleting file: %s\r\n", path);
|
||||||
|
if(fs.remove(path)){
|
||||||
|
Serial.println("- file deleted");
|
||||||
|
} else {
|
||||||
|
Serial.println("- delete failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFileIO(fs::FS &fs, const char * path){
|
||||||
|
Serial.printf("Testing file I/O with %s\r\n", path);
|
||||||
|
|
||||||
|
static uint8_t buf[512];
|
||||||
|
size_t len = 0;
|
||||||
|
File file = fs.open(path, FILE_WRITE);
|
||||||
|
if(!file){
|
||||||
|
Serial.println("- failed to open file for writing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t i;
|
||||||
|
Serial.print("- writing" );
|
||||||
|
uint32_t start = millis();
|
||||||
|
for(i=0; i<2048; i++){
|
||||||
|
if ((i & 0x001F) == 0x001F){
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
file.write(buf, 512);
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
uint32_t end = millis() - start;
|
||||||
|
Serial.printf(" - %u bytes written in %u ms\r\n", 2048 * 512, end);
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
file = fs.open(path);
|
||||||
|
start = millis();
|
||||||
|
end = start;
|
||||||
|
i = 0;
|
||||||
|
if(file && !file.isDirectory()){
|
||||||
|
len = file.size();
|
||||||
|
size_t flen = len;
|
||||||
|
start = millis();
|
||||||
|
Serial.print("- reading" );
|
||||||
|
while(len){
|
||||||
|
size_t toRead = len;
|
||||||
|
if(toRead > 512){
|
||||||
|
toRead = 512;
|
||||||
|
}
|
||||||
|
file.read(buf, toRead);
|
||||||
|
if ((i++ & 0x001F) == 0x001F){
|
||||||
|
Serial.print(".");
|
||||||
|
}
|
||||||
|
len -= toRead;
|
||||||
|
}
|
||||||
|
Serial.println("");
|
||||||
|
end = millis() - start;
|
||||||
|
Serial.printf("- %u bytes read in %u ms\r\n", flen, end);
|
||||||
|
file.close();
|
||||||
|
} else {
|
||||||
|
Serial.println("- failed to open file for reading");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setup(){
|
||||||
|
Serial.begin(115200);
|
||||||
|
if(!LITTLEFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
|
||||||
|
Serial.println("LITTLEFS Mount Failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
listDir(LITTLEFS, "/", 0);
|
||||||
|
writeFile(LITTLEFS, "/hello.txt", "Hello ");
|
||||||
|
appendFile(LITTLEFS, "/hello.txt", "World!\r\n");
|
||||||
|
readFile(LITTLEFS, "/hello.txt");
|
||||||
|
renameFile(LITTLEFS, "/hello.txt", "/foo.txt");
|
||||||
|
readFile(LITTLEFS, "/foo.txt");
|
||||||
|
deleteFile(LITTLEFS, "/foo.txt");
|
||||||
|
testFileIO(LITTLEFS, "/test.txt");
|
||||||
|
deleteFile(LITTLEFS, "/test.txt");
|
||||||
|
Serial.println( "Test complete" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop(){
|
||||||
|
|
||||||
|
}
|
||||||
22
lib/LITTLEFS/library.json
Normal file
22
lib/LITTLEFS/library.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name":"LITTLEFS",
|
||||||
|
"description":"LITTLEFS File System Library for ESP32",
|
||||||
|
"keywords":"littlefs, spiffs",
|
||||||
|
"authors":
|
||||||
|
{
|
||||||
|
"name": "LL",
|
||||||
|
"maintainer": true
|
||||||
|
},
|
||||||
|
"repository":
|
||||||
|
{
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/lorol/LITTLEFS.git"
|
||||||
|
},
|
||||||
|
"version": "1.0",
|
||||||
|
"license": "LGPL-2.0",
|
||||||
|
"frameworks": "arduino",
|
||||||
|
"platforms": "espressif32",
|
||||||
|
"build": {
|
||||||
|
"libCompatMode": 2
|
||||||
|
}
|
||||||
|
}
|
||||||
9
lib/LITTLEFS/library.properties
Normal file
9
lib/LITTLEFS/library.properties
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
name=LITTLEFS
|
||||||
|
version=1.0
|
||||||
|
author=LL
|
||||||
|
maintainer=LL
|
||||||
|
sentence=ESP32 LITTLEFS File System
|
||||||
|
paragraph=
|
||||||
|
category=Data Storage
|
||||||
|
url=
|
||||||
|
architectures=esp32
|
||||||
106
lib/LITTLEFS/src/LITTLEFS.cpp
Normal file
106
lib/LITTLEFS/src/LITTLEFS.cpp
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
static constexpr const char LFS_NAME[] = "spiffs";
|
||||||
|
|
||||||
|
#include "vfs_api.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
#include <sys/unistd.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include "esp_littlefs.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "LITTLEFS.h"
|
||||||
|
|
||||||
|
using namespace fs;
|
||||||
|
|
||||||
|
LITTLEFSFS::LITTLEFSFS() : FS(FSImplPtr(new VFSImpl()))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LITTLEFSFS::begin(bool formatOnFail, const char * basePath, uint8_t maxOpenFiles)
|
||||||
|
{
|
||||||
|
if(esp_littlefs_mounted(LFS_NAME)){
|
||||||
|
log_w("LITTLEFS Already Mounted!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
esp_vfs_littlefs_conf_t conf = {
|
||||||
|
.base_path = basePath,
|
||||||
|
.partition_label = LFS_NAME,
|
||||||
|
//.max_files = maxOpenFiles,
|
||||||
|
.format_if_mount_failed = false
|
||||||
|
};
|
||||||
|
|
||||||
|
esp_err_t err = esp_vfs_littlefs_register(&conf);
|
||||||
|
if(err == ESP_FAIL && formatOnFail){
|
||||||
|
if(format()){
|
||||||
|
err = esp_vfs_littlefs_register(&conf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(err != ESP_OK){
|
||||||
|
log_e("Mounting LITTLEFS failed! Error: %d", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
_impl->mountpoint(basePath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LITTLEFSFS::end()
|
||||||
|
{
|
||||||
|
if(esp_littlefs_mounted(LFS_NAME)){
|
||||||
|
esp_err_t err = esp_vfs_littlefs_unregister(LFS_NAME);
|
||||||
|
if(err){
|
||||||
|
log_e("Unmounting LITTLEFS failed! Error: %d", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_impl->mountpoint(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LITTLEFSFS::format()
|
||||||
|
{
|
||||||
|
disableCore0WDT();
|
||||||
|
esp_err_t err = esp_littlefs_format(LFS_NAME);
|
||||||
|
enableCore0WDT();
|
||||||
|
if(err){
|
||||||
|
log_e("Formatting LITTLEFS failed! Error: %d", err);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t LITTLEFSFS::totalBytes()
|
||||||
|
{
|
||||||
|
size_t total,used;
|
||||||
|
if(esp_littlefs_info(LFS_NAME, &total, &used)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t LITTLEFSFS::usedBytes()
|
||||||
|
{
|
||||||
|
size_t total,used;
|
||||||
|
if(esp_littlefs_info(LFS_NAME, &total, &used)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
|
||||||
|
LITTLEFSFS LITTLEFS;
|
||||||
|
|
||||||
38
lib/LITTLEFS/src/LITTLEFS.h
Normal file
38
lib/LITTLEFS/src/LITTLEFS.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
#ifndef _LITTLEFS_H_
|
||||||
|
#define _LITTLEFS_H_
|
||||||
|
|
||||||
|
#include "FS.h"
|
||||||
|
|
||||||
|
namespace fs
|
||||||
|
{
|
||||||
|
|
||||||
|
class LITTLEFSFS : public FS
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
LITTLEFSFS();
|
||||||
|
bool begin(bool formatOnFail=false, const char * basePath="/littlefs", uint8_t maxOpenFiles=5);
|
||||||
|
bool format();
|
||||||
|
size_t totalBytes();
|
||||||
|
size_t usedBytes();
|
||||||
|
void end();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extern fs::LITTLEFSFS LITTLEFS;
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
1481
lib/LITTLEFS/src/esp_littlefs.c
Normal file
1481
lib/LITTLEFS/src/esp_littlefs.c
Normal file
File diff suppressed because it is too large
Load Diff
114
lib/LITTLEFS/src/esp_littlefs.h
Normal file
114
lib/LITTLEFS/src/esp_littlefs.h
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
#ifndef ESP_LITTLEFS_H__
|
||||||
|
#define ESP_LITTLEFS_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <utime.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "esp_err.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/reent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/termios.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include "lfs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
LITTLEFS_ATTR_MTIME, /**< Last Modified - time (seconds) */
|
||||||
|
LITTLEFS_ATTR_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Configuration structure for esp_vfs_littlefs_register.
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
const char *base_path; /**< Mounting point. */
|
||||||
|
const char *partition_label; /**< Label of partition to use. */
|
||||||
|
uint8_t format_if_mount_failed:1; /**< Format the file system if it fails to mount. */
|
||||||
|
uint8_t dont_mount:1; /**< Don't attempt to mount or format. Overrides format_if_mount_failed */
|
||||||
|
} esp_vfs_littlefs_conf_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register and mount littlefs to VFS with given path prefix.
|
||||||
|
*
|
||||||
|
* @param conf Pointer to esp_vfs_littlefs_conf_t configuration structure
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK if success
|
||||||
|
* - ESP_ERR_NO_MEM if objects could not be allocated
|
||||||
|
* - ESP_ERR_INVALID_STATE if already mounted or partition is encrypted
|
||||||
|
* - ESP_ERR_NOT_FOUND if partition for littlefs was not found
|
||||||
|
* - ESP_FAIL if mount or format fails
|
||||||
|
*/
|
||||||
|
esp_err_t esp_vfs_littlefs_register(const esp_vfs_littlefs_conf_t * conf);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregister and unmount littlefs from VFS
|
||||||
|
*
|
||||||
|
* @param partition_label Label of the partition to unregister.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK if successful
|
||||||
|
* - ESP_ERR_INVALID_STATE already unregistered
|
||||||
|
*/
|
||||||
|
esp_err_t esp_vfs_littlefs_unregister(const char* partition_label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if littlefs is mounted
|
||||||
|
*
|
||||||
|
* @param partition_label Label of the partition to check.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - true if mounted
|
||||||
|
* - false if not mounted
|
||||||
|
*/
|
||||||
|
bool esp_littlefs_mounted(const char* partition_label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Format the littlefs partition
|
||||||
|
*
|
||||||
|
* @param partition_label Label of the partition to format.
|
||||||
|
* @return
|
||||||
|
* - ESP_OK if successful
|
||||||
|
* - ESP_FAIL on error
|
||||||
|
*/
|
||||||
|
esp_err_t esp_littlefs_format(const char* partition_label);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get information for littlefs
|
||||||
|
*
|
||||||
|
* @param partition_label Optional, label of the partition to get info for.
|
||||||
|
* @param[out] total_bytes Size of the file system
|
||||||
|
* @param[out] used_bytes Current used bytes in the file system
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK if success
|
||||||
|
* - ESP_ERR_INVALID_STATE if not mounted
|
||||||
|
*/
|
||||||
|
esp_err_t esp_littlefs_info(const char* partition_label, size_t *total_bytes, size_t *used_bytes);
|
||||||
|
|
||||||
|
#if CONFIG_LITTLEFS_HUMAN_READABLE
|
||||||
|
/**
|
||||||
|
* @brief converts an enumerated lfs error into a string.
|
||||||
|
* @param lfs_errno The enumerated littlefs error.
|
||||||
|
*/
|
||||||
|
const char * esp_littlefs_errno(enum lfs_error lfs_errno);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
4913
lib/LITTLEFS/src/lfs.c
Normal file
4913
lib/LITTLEFS/src/lfs.c
Normal file
File diff suppressed because it is too large
Load Diff
655
lib/LITTLEFS/src/lfs.h
Normal file
655
lib/LITTLEFS/src/lfs.h
Normal file
@@ -0,0 +1,655 @@
|
|||||||
|
/*
|
||||||
|
* The little filesystem
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#ifndef LFS_H
|
||||||
|
#define LFS_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/// Version info ///
|
||||||
|
|
||||||
|
// Software library version
|
||||||
|
// Major (top-nibble), incremented on backwards incompatible changes
|
||||||
|
// Minor (bottom-nibble), incremented on feature additions
|
||||||
|
#define LFS_VERSION 0x00020002
|
||||||
|
#define LFS_VERSION_MAJOR (0xffff & (LFS_VERSION >> 16))
|
||||||
|
#define LFS_VERSION_MINOR (0xffff & (LFS_VERSION >> 0))
|
||||||
|
|
||||||
|
// Version of On-disk data structures
|
||||||
|
// Major (top-nibble), incremented on backwards incompatible changes
|
||||||
|
// Minor (bottom-nibble), incremented on feature additions
|
||||||
|
#define LFS_DISK_VERSION 0x00020000
|
||||||
|
#define LFS_DISK_VERSION_MAJOR (0xffff & (LFS_DISK_VERSION >> 16))
|
||||||
|
#define LFS_DISK_VERSION_MINOR (0xffff & (LFS_DISK_VERSION >> 0))
|
||||||
|
|
||||||
|
|
||||||
|
/// Definitions ///
|
||||||
|
|
||||||
|
// Type definitions
|
||||||
|
typedef uint32_t lfs_size_t;
|
||||||
|
typedef uint32_t lfs_off_t;
|
||||||
|
|
||||||
|
typedef int32_t lfs_ssize_t;
|
||||||
|
typedef int32_t lfs_soff_t;
|
||||||
|
|
||||||
|
typedef uint32_t lfs_block_t;
|
||||||
|
|
||||||
|
// Maximum name size in bytes, may be redefined to reduce the size of the
|
||||||
|
// info struct. Limited to <= 1022. Stored in superblock and must be
|
||||||
|
// respected by other littlefs drivers.
|
||||||
|
#ifndef LFS_NAME_MAX
|
||||||
|
#define LFS_NAME_MAX 255
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Maximum size of a file in bytes, may be redefined to limit to support other
|
||||||
|
// drivers. Limited on disk to <= 4294967296. However, above 2147483647 the
|
||||||
|
// functions lfs_file_seek, lfs_file_size, and lfs_file_tell will return
|
||||||
|
// incorrect values due to using signed integers. Stored in superblock and
|
||||||
|
// must be respected by other littlefs drivers.
|
||||||
|
#ifndef LFS_FILE_MAX
|
||||||
|
#define LFS_FILE_MAX 2147483647
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Maximum size of custom attributes in bytes, may be redefined, but there is
|
||||||
|
// no real benefit to using a smaller LFS_ATTR_MAX. Limited to <= 1022.
|
||||||
|
#ifndef LFS_ATTR_MAX
|
||||||
|
#define LFS_ATTR_MAX 1022
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Possible error codes, these are negative to allow
|
||||||
|
// valid positive return values
|
||||||
|
enum lfs_error {
|
||||||
|
LFS_ERR_OK = 0, // No error
|
||||||
|
LFS_ERR_IO = -5, // Error during device operation
|
||||||
|
LFS_ERR_CORRUPT = -84, // Corrupted
|
||||||
|
LFS_ERR_NOENT = -2, // No directory entry
|
||||||
|
LFS_ERR_EXIST = -17, // Entry already exists
|
||||||
|
LFS_ERR_NOTDIR = -20, // Entry is not a dir
|
||||||
|
LFS_ERR_ISDIR = -21, // Entry is a dir
|
||||||
|
LFS_ERR_NOTEMPTY = -39, // Dir is not empty
|
||||||
|
LFS_ERR_BADF = -9, // Bad file number
|
||||||
|
LFS_ERR_FBIG = -27, // File too large
|
||||||
|
LFS_ERR_INVAL = -22, // Invalid parameter
|
||||||
|
LFS_ERR_NOSPC = -28, // No space left on device
|
||||||
|
LFS_ERR_NOMEM = -12, // No more memory available
|
||||||
|
LFS_ERR_NOATTR = -61, // No data/attr available
|
||||||
|
LFS_ERR_NAMETOOLONG = -36, // File name too long
|
||||||
|
};
|
||||||
|
|
||||||
|
// File types
|
||||||
|
enum lfs_type {
|
||||||
|
// file types
|
||||||
|
LFS_TYPE_REG = 0x001,
|
||||||
|
LFS_TYPE_DIR = 0x002,
|
||||||
|
|
||||||
|
// internally used types
|
||||||
|
LFS_TYPE_SPLICE = 0x400,
|
||||||
|
LFS_TYPE_NAME = 0x000,
|
||||||
|
LFS_TYPE_STRUCT = 0x200,
|
||||||
|
LFS_TYPE_USERATTR = 0x300,
|
||||||
|
LFS_TYPE_FROM = 0x100,
|
||||||
|
LFS_TYPE_TAIL = 0x600,
|
||||||
|
LFS_TYPE_GLOBALS = 0x700,
|
||||||
|
LFS_TYPE_CRC = 0x500,
|
||||||
|
|
||||||
|
// internally used type specializations
|
||||||
|
LFS_TYPE_CREATE = 0x401,
|
||||||
|
LFS_TYPE_DELETE = 0x4ff,
|
||||||
|
LFS_TYPE_SUPERBLOCK = 0x0ff,
|
||||||
|
LFS_TYPE_DIRSTRUCT = 0x200,
|
||||||
|
LFS_TYPE_CTZSTRUCT = 0x202,
|
||||||
|
LFS_TYPE_INLINESTRUCT = 0x201,
|
||||||
|
LFS_TYPE_SOFTTAIL = 0x600,
|
||||||
|
LFS_TYPE_HARDTAIL = 0x601,
|
||||||
|
LFS_TYPE_MOVESTATE = 0x7ff,
|
||||||
|
|
||||||
|
// internal chip sources
|
||||||
|
LFS_FROM_NOOP = 0x000,
|
||||||
|
LFS_FROM_MOVE = 0x101,
|
||||||
|
LFS_FROM_USERATTRS = 0x102,
|
||||||
|
};
|
||||||
|
|
||||||
|
// File open flags
|
||||||
|
enum lfs_open_flags {
|
||||||
|
// open flags
|
||||||
|
LFS_O_RDONLY = 1, // Open a file as read only
|
||||||
|
LFS_O_WRONLY = 2, // Open a file as write only
|
||||||
|
LFS_O_RDWR = 3, // Open a file as read and write
|
||||||
|
LFS_O_CREAT = 0x0100, // Create a file if it does not exist
|
||||||
|
LFS_O_EXCL = 0x0200, // Fail if a file already exists
|
||||||
|
LFS_O_TRUNC = 0x0400, // Truncate the existing file to zero size
|
||||||
|
LFS_O_APPEND = 0x0800, // Move to end of file on every write
|
||||||
|
|
||||||
|
// internally used flags
|
||||||
|
LFS_F_DIRTY = 0x010000, // File does not match storage
|
||||||
|
LFS_F_WRITING = 0x020000, // File has been written since last flush
|
||||||
|
LFS_F_READING = 0x040000, // File has been read since last flush
|
||||||
|
LFS_F_ERRED = 0x080000, // An error occured during write
|
||||||
|
LFS_F_INLINE = 0x100000, // Currently inlined in directory entry
|
||||||
|
LFS_F_OPENED = 0x200000, // File has been opened
|
||||||
|
};
|
||||||
|
|
||||||
|
// File seek flags
|
||||||
|
enum lfs_whence_flags {
|
||||||
|
LFS_SEEK_SET = 0, // Seek relative to an absolute position
|
||||||
|
LFS_SEEK_CUR = 1, // Seek relative to the current file position
|
||||||
|
LFS_SEEK_END = 2, // Seek relative to the end of the file
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Configuration provided during initialization of the littlefs
|
||||||
|
struct lfs_config {
|
||||||
|
// Opaque user provided context that can be used to pass
|
||||||
|
// information to the block device operations
|
||||||
|
void *context;
|
||||||
|
|
||||||
|
// Read a region in a block. Negative error codes are propogated
|
||||||
|
// to the user.
|
||||||
|
int (*read)(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
// Program a region in a block. The block must have previously
|
||||||
|
// been erased. Negative error codes are propogated to the user.
|
||||||
|
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||||
|
int (*prog)(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, const void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
// Erase a block. A block must be erased before being programmed.
|
||||||
|
// The state of an erased block is undefined. Negative error codes
|
||||||
|
// are propogated to the user.
|
||||||
|
// May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||||
|
int (*erase)(const struct lfs_config *c, lfs_block_t block);
|
||||||
|
|
||||||
|
// Sync the state of the underlying block device. Negative error codes
|
||||||
|
// are propogated to the user.
|
||||||
|
int (*sync)(const struct lfs_config *c);
|
||||||
|
|
||||||
|
// Minimum size of a block read. All read operations will be a
|
||||||
|
// multiple of this value.
|
||||||
|
lfs_size_t read_size;
|
||||||
|
|
||||||
|
// Minimum size of a block program. All program operations will be a
|
||||||
|
// multiple of this value.
|
||||||
|
lfs_size_t prog_size;
|
||||||
|
|
||||||
|
// Size of an erasable block. This does not impact ram consumption and
|
||||||
|
// may be larger than the physical erase size. However, non-inlined files
|
||||||
|
// take up at minimum one block. Must be a multiple of the read
|
||||||
|
// and program sizes.
|
||||||
|
lfs_size_t block_size;
|
||||||
|
|
||||||
|
// Number of erasable blocks on the device.
|
||||||
|
lfs_size_t block_count;
|
||||||
|
|
||||||
|
// Number of erase cycles before littlefs evicts metadata logs and moves
|
||||||
|
// the metadata to another block. Suggested values are in the
|
||||||
|
// range 100-1000, with large values having better performance at the cost
|
||||||
|
// of less consistent wear distribution.
|
||||||
|
//
|
||||||
|
// Set to -1 to disable block-level wear-leveling.
|
||||||
|
int32_t block_cycles;
|
||||||
|
|
||||||
|
// Size of block caches. Each cache buffers a portion of a block in RAM.
|
||||||
|
// The littlefs needs a read cache, a program cache, and one additional
|
||||||
|
// cache per file. Larger caches can improve performance by storing more
|
||||||
|
// data and reducing the number of disk accesses. Must be a multiple of
|
||||||
|
// the read and program sizes, and a factor of the block size.
|
||||||
|
lfs_size_t cache_size;
|
||||||
|
|
||||||
|
// Size of the lookahead buffer in bytes. A larger lookahead buffer
|
||||||
|
// increases the number of blocks found during an allocation pass. The
|
||||||
|
// lookahead buffer is stored as a compact bitmap, so each byte of RAM
|
||||||
|
// can track 8 blocks. Must be a multiple of 8.
|
||||||
|
lfs_size_t lookahead_size;
|
||||||
|
|
||||||
|
// Optional statically allocated read buffer. Must be cache_size.
|
||||||
|
// By default lfs_malloc is used to allocate this buffer.
|
||||||
|
void *read_buffer;
|
||||||
|
|
||||||
|
// Optional statically allocated program buffer. Must be cache_size.
|
||||||
|
// By default lfs_malloc is used to allocate this buffer.
|
||||||
|
void *prog_buffer;
|
||||||
|
|
||||||
|
// Optional statically allocated lookahead buffer. Must be lookahead_size
|
||||||
|
// and aligned to a 32-bit boundary. By default lfs_malloc is used to
|
||||||
|
// allocate this buffer.
|
||||||
|
void *lookahead_buffer;
|
||||||
|
|
||||||
|
// Optional upper limit on length of file names in bytes. No downside for
|
||||||
|
// larger names except the size of the info struct which is controlled by
|
||||||
|
// the LFS_NAME_MAX define. Defaults to LFS_NAME_MAX when zero. Stored in
|
||||||
|
// superblock and must be respected by other littlefs drivers.
|
||||||
|
lfs_size_t name_max;
|
||||||
|
|
||||||
|
// Optional upper limit on files in bytes. No downside for larger files
|
||||||
|
// but must be <= LFS_FILE_MAX. Defaults to LFS_FILE_MAX when zero. Stored
|
||||||
|
// in superblock and must be respected by other littlefs drivers.
|
||||||
|
lfs_size_t file_max;
|
||||||
|
|
||||||
|
// Optional upper limit on custom attributes in bytes. No downside for
|
||||||
|
// larger attributes size but must be <= LFS_ATTR_MAX. Defaults to
|
||||||
|
// LFS_ATTR_MAX when zero.
|
||||||
|
lfs_size_t attr_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
// File info structure
|
||||||
|
struct lfs_info {
|
||||||
|
// Type of the file, either LFS_TYPE_REG or LFS_TYPE_DIR
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
// Size of the file, only valid for REG files. Limited to 32-bits.
|
||||||
|
lfs_size_t size;
|
||||||
|
|
||||||
|
// Name of the file stored as a null-terminated string. Limited to
|
||||||
|
// LFS_NAME_MAX+1, which can be changed by redefining LFS_NAME_MAX to
|
||||||
|
// reduce RAM. LFS_NAME_MAX is stored in superblock and must be
|
||||||
|
// respected by other littlefs drivers.
|
||||||
|
char name[LFS_NAME_MAX+1];
|
||||||
|
};
|
||||||
|
|
||||||
|
// Custom attribute structure, used to describe custom attributes
|
||||||
|
// committed atomically during file writes.
|
||||||
|
struct lfs_attr {
|
||||||
|
// 8-bit type of attribute, provided by user and used to
|
||||||
|
// identify the attribute
|
||||||
|
uint8_t type;
|
||||||
|
|
||||||
|
// Pointer to buffer containing the attribute
|
||||||
|
void *buffer;
|
||||||
|
|
||||||
|
// Size of attribute in bytes, limited to LFS_ATTR_MAX
|
||||||
|
lfs_size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Optional configuration provided during lfs_file_opencfg
|
||||||
|
struct lfs_file_config {
|
||||||
|
// Optional statically allocated file buffer. Must be cache_size.
|
||||||
|
// By default lfs_malloc is used to allocate this buffer.
|
||||||
|
void *buffer;
|
||||||
|
|
||||||
|
// Optional list of custom attributes related to the file. If the file
|
||||||
|
// is opened with read access, these attributes will be read from disk
|
||||||
|
// during the open call. If the file is opened with write access, the
|
||||||
|
// attributes will be written to disk every file sync or close. This
|
||||||
|
// write occurs atomically with update to the file's contents.
|
||||||
|
//
|
||||||
|
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||||
|
// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller
|
||||||
|
// than the buffer, it will be padded with zeros. If the stored attribute
|
||||||
|
// is larger, then it will be silently truncated. If the attribute is not
|
||||||
|
// found, it will be created implicitly.
|
||||||
|
struct lfs_attr *attrs;
|
||||||
|
|
||||||
|
// Number of custom attributes in the list
|
||||||
|
lfs_size_t attr_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// internal littlefs data structures ///
|
||||||
|
typedef struct lfs_cache {
|
||||||
|
lfs_block_t block;
|
||||||
|
lfs_off_t off;
|
||||||
|
lfs_size_t size;
|
||||||
|
uint8_t *buffer;
|
||||||
|
} lfs_cache_t;
|
||||||
|
|
||||||
|
typedef struct lfs_mdir {
|
||||||
|
lfs_block_t pair[2];
|
||||||
|
uint32_t rev;
|
||||||
|
lfs_off_t off;
|
||||||
|
uint32_t etag;
|
||||||
|
uint16_t count;
|
||||||
|
bool erased;
|
||||||
|
bool split;
|
||||||
|
lfs_block_t tail[2];
|
||||||
|
} lfs_mdir_t;
|
||||||
|
|
||||||
|
// littlefs directory type
|
||||||
|
typedef struct lfs_dir {
|
||||||
|
struct lfs_dir *next;
|
||||||
|
uint16_t id;
|
||||||
|
uint8_t type;
|
||||||
|
lfs_mdir_t m;
|
||||||
|
|
||||||
|
lfs_off_t pos;
|
||||||
|
lfs_block_t head[2];
|
||||||
|
} lfs_dir_t;
|
||||||
|
|
||||||
|
// littlefs file type
|
||||||
|
typedef struct lfs_file {
|
||||||
|
struct lfs_file *next;
|
||||||
|
uint16_t id;
|
||||||
|
uint8_t type;
|
||||||
|
lfs_mdir_t m;
|
||||||
|
|
||||||
|
struct lfs_ctz {
|
||||||
|
lfs_block_t head;
|
||||||
|
lfs_size_t size;
|
||||||
|
} ctz;
|
||||||
|
|
||||||
|
uint32_t flags;
|
||||||
|
lfs_off_t pos;
|
||||||
|
lfs_block_t block;
|
||||||
|
lfs_off_t off;
|
||||||
|
lfs_cache_t cache;
|
||||||
|
|
||||||
|
const struct lfs_file_config *cfg;
|
||||||
|
} lfs_file_t;
|
||||||
|
|
||||||
|
typedef struct lfs_superblock {
|
||||||
|
uint32_t version;
|
||||||
|
lfs_size_t block_size;
|
||||||
|
lfs_size_t block_count;
|
||||||
|
lfs_size_t name_max;
|
||||||
|
lfs_size_t file_max;
|
||||||
|
lfs_size_t attr_max;
|
||||||
|
} lfs_superblock_t;
|
||||||
|
|
||||||
|
typedef struct lfs_gstate {
|
||||||
|
uint32_t tag;
|
||||||
|
lfs_block_t pair[2];
|
||||||
|
} lfs_gstate_t;
|
||||||
|
|
||||||
|
// The littlefs filesystem type
|
||||||
|
typedef struct lfs {
|
||||||
|
lfs_cache_t rcache;
|
||||||
|
lfs_cache_t pcache;
|
||||||
|
|
||||||
|
lfs_block_t root[2];
|
||||||
|
struct lfs_mlist {
|
||||||
|
struct lfs_mlist *next;
|
||||||
|
uint16_t id;
|
||||||
|
uint8_t type;
|
||||||
|
lfs_mdir_t m;
|
||||||
|
} *mlist;
|
||||||
|
uint32_t seed;
|
||||||
|
|
||||||
|
lfs_gstate_t gstate;
|
||||||
|
lfs_gstate_t gdisk;
|
||||||
|
lfs_gstate_t gdelta;
|
||||||
|
|
||||||
|
struct lfs_free {
|
||||||
|
lfs_block_t off;
|
||||||
|
lfs_block_t size;
|
||||||
|
lfs_block_t i;
|
||||||
|
lfs_block_t ack;
|
||||||
|
uint32_t *buffer;
|
||||||
|
} free;
|
||||||
|
|
||||||
|
const struct lfs_config *cfg;
|
||||||
|
lfs_size_t name_max;
|
||||||
|
lfs_size_t file_max;
|
||||||
|
lfs_size_t attr_max;
|
||||||
|
|
||||||
|
#ifdef LFS_MIGRATE
|
||||||
|
struct lfs1 *lfs1;
|
||||||
|
#endif
|
||||||
|
} lfs_t;
|
||||||
|
|
||||||
|
|
||||||
|
/// Filesystem functions ///
|
||||||
|
|
||||||
|
// Format a block device with the littlefs
|
||||||
|
//
|
||||||
|
// Requires a littlefs object and config struct. This clobbers the littlefs
|
||||||
|
// object, and does not leave the filesystem mounted. The config struct must
|
||||||
|
// be zeroed for defaults and backwards compatibility.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_format(lfs_t *lfs, const struct lfs_config *config);
|
||||||
|
|
||||||
|
// Mounts a littlefs
|
||||||
|
//
|
||||||
|
// Requires a littlefs object and config struct. Multiple filesystems
|
||||||
|
// may be mounted simultaneously with multiple littlefs objects. Both
|
||||||
|
// lfs and config must be allocated while mounted. The config struct must
|
||||||
|
// be zeroed for defaults and backwards compatibility.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_mount(lfs_t *lfs, const struct lfs_config *config);
|
||||||
|
|
||||||
|
// Unmounts a littlefs
|
||||||
|
//
|
||||||
|
// Does nothing besides releasing any allocated resources.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_unmount(lfs_t *lfs);
|
||||||
|
|
||||||
|
/// General operations ///
|
||||||
|
|
||||||
|
// Removes a file or directory
|
||||||
|
//
|
||||||
|
// If removing a directory, the directory must be empty.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_remove(lfs_t *lfs, const char *path);
|
||||||
|
|
||||||
|
// Rename or move a file or directory
|
||||||
|
//
|
||||||
|
// If the destination exists, it must match the source in type.
|
||||||
|
// If the destination is a directory, the directory must be empty.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_rename(lfs_t *lfs, const char *oldpath, const char *newpath);
|
||||||
|
|
||||||
|
// Find info about a file or directory
|
||||||
|
//
|
||||||
|
// Fills out the info structure, based on the specified file or directory.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_stat(lfs_t *lfs, const char *path, struct lfs_info *info);
|
||||||
|
|
||||||
|
// Get a custom attribute
|
||||||
|
//
|
||||||
|
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||||
|
// to LFS_ATTR_MAX bytes. When read, if the stored attribute is smaller than
|
||||||
|
// the buffer, it will be padded with zeros. If the stored attribute is larger,
|
||||||
|
// then it will be silently truncated. If no attribute is found, the error
|
||||||
|
// LFS_ERR_NOATTR is returned and the buffer is filled with zeros.
|
||||||
|
//
|
||||||
|
// Returns the size of the attribute, or a negative error code on failure.
|
||||||
|
// Note, the returned size is the size of the attribute on disk, irrespective
|
||||||
|
// of the size of the buffer. This can be used to dynamically allocate a buffer
|
||||||
|
// or check for existance.
|
||||||
|
lfs_ssize_t lfs_getattr(lfs_t *lfs, const char *path,
|
||||||
|
uint8_t type, void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
// Set custom attributes
|
||||||
|
//
|
||||||
|
// Custom attributes are uniquely identified by an 8-bit type and limited
|
||||||
|
// to LFS_ATTR_MAX bytes. If an attribute is not found, it will be
|
||||||
|
// implicitly created.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_setattr(lfs_t *lfs, const char *path,
|
||||||
|
uint8_t type, const void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
// Removes a custom attribute
|
||||||
|
//
|
||||||
|
// If an attribute is not found, nothing happens.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_removeattr(lfs_t *lfs, const char *path, uint8_t type);
|
||||||
|
|
||||||
|
|
||||||
|
/// File operations ///
|
||||||
|
|
||||||
|
// Open a file
|
||||||
|
//
|
||||||
|
// The mode that the file is opened in is determined by the flags, which
|
||||||
|
// are values from the enum lfs_open_flags that are bitwise-ored together.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_open(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
const char *path, int flags);
|
||||||
|
|
||||||
|
// Open a file with extra configuration
|
||||||
|
//
|
||||||
|
// The mode that the file is opened in is determined by the flags, which
|
||||||
|
// are values from the enum lfs_open_flags that are bitwise-ored together.
|
||||||
|
//
|
||||||
|
// The config struct provides additional config options per file as described
|
||||||
|
// above. The config struct must be allocated while the file is open, and the
|
||||||
|
// config struct must be zeroed for defaults and backwards compatibility.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_opencfg(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
const char *path, int flags,
|
||||||
|
const struct lfs_file_config *config);
|
||||||
|
|
||||||
|
// Close a file
|
||||||
|
//
|
||||||
|
// Any pending writes are written out to storage as though
|
||||||
|
// sync had been called and releases any allocated resources.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_close(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
// Synchronize a file on storage
|
||||||
|
//
|
||||||
|
// Any pending writes are written out to storage.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_sync(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
// Read data from file
|
||||||
|
//
|
||||||
|
// Takes a buffer and size indicating where to store the read data.
|
||||||
|
// Returns the number of bytes read, or a negative error code on failure.
|
||||||
|
lfs_ssize_t lfs_file_read(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
// Write data to file
|
||||||
|
//
|
||||||
|
// Takes a buffer and size indicating the data to write. The file will not
|
||||||
|
// actually be updated on the storage until either sync or close is called.
|
||||||
|
//
|
||||||
|
// Returns the number of bytes written, or a negative error code on failure.
|
||||||
|
lfs_ssize_t lfs_file_write(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
const void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
// Change the position of the file
|
||||||
|
//
|
||||||
|
// The change in position is determined by the offset and whence flag.
|
||||||
|
// Returns the new position of the file, or a negative error code on failure.
|
||||||
|
lfs_soff_t lfs_file_seek(lfs_t *lfs, lfs_file_t *file,
|
||||||
|
lfs_soff_t off, int whence);
|
||||||
|
|
||||||
|
// Truncates the size of the file to the specified size
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_truncate(lfs_t *lfs, lfs_file_t *file, lfs_off_t size);
|
||||||
|
|
||||||
|
// Return the position of the file
|
||||||
|
//
|
||||||
|
// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_CUR)
|
||||||
|
// Returns the position of the file, or a negative error code on failure.
|
||||||
|
lfs_soff_t lfs_file_tell(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
// Change the position of the file to the beginning of the file
|
||||||
|
//
|
||||||
|
// Equivalent to lfs_file_seek(lfs, file, 0, LFS_SEEK_SET)
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_file_rewind(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
// Return the size of the file
|
||||||
|
//
|
||||||
|
// Similar to lfs_file_seek(lfs, file, 0, LFS_SEEK_END)
|
||||||
|
// Returns the size of the file, or a negative error code on failure.
|
||||||
|
lfs_soff_t lfs_file_size(lfs_t *lfs, lfs_file_t *file);
|
||||||
|
|
||||||
|
|
||||||
|
/// Directory operations ///
|
||||||
|
|
||||||
|
// Create a directory
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_mkdir(lfs_t *lfs, const char *path);
|
||||||
|
|
||||||
|
// Open a directory
|
||||||
|
//
|
||||||
|
// Once open a directory can be used with read to iterate over files.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_dir_open(lfs_t *lfs, lfs_dir_t *dir, const char *path);
|
||||||
|
|
||||||
|
// Close a directory
|
||||||
|
//
|
||||||
|
// Releases any allocated resources.
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_dir_close(lfs_t *lfs, lfs_dir_t *dir);
|
||||||
|
|
||||||
|
// Read an entry in the directory
|
||||||
|
//
|
||||||
|
// Fills out the info structure, based on the specified file or directory.
|
||||||
|
// Returns a positive value on success, 0 at the end of directory,
|
||||||
|
// or a negative error code on failure.
|
||||||
|
int lfs_dir_read(lfs_t *lfs, lfs_dir_t *dir, struct lfs_info *info);
|
||||||
|
|
||||||
|
// Change the position of the directory
|
||||||
|
//
|
||||||
|
// The new off must be a value previous returned from tell and specifies
|
||||||
|
// an absolute offset in the directory seek.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_dir_seek(lfs_t *lfs, lfs_dir_t *dir, lfs_off_t off);
|
||||||
|
|
||||||
|
// Return the position of the directory
|
||||||
|
//
|
||||||
|
// The returned offset is only meant to be consumed by seek and may not make
|
||||||
|
// sense, but does indicate the current position in the directory iteration.
|
||||||
|
//
|
||||||
|
// Returns the position of the directory, or a negative error code on failure.
|
||||||
|
lfs_soff_t lfs_dir_tell(lfs_t *lfs, lfs_dir_t *dir);
|
||||||
|
|
||||||
|
// Change the position of the directory to the beginning of the directory
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_dir_rewind(lfs_t *lfs, lfs_dir_t *dir);
|
||||||
|
|
||||||
|
|
||||||
|
/// Filesystem-level filesystem operations
|
||||||
|
|
||||||
|
// Finds the current size of the filesystem
|
||||||
|
//
|
||||||
|
// Note: Result is best effort. If files share COW structures, the returned
|
||||||
|
// size may be larger than the filesystem actually is.
|
||||||
|
//
|
||||||
|
// Returns the number of allocated blocks, or a negative error code on failure.
|
||||||
|
lfs_ssize_t lfs_fs_size(lfs_t *lfs);
|
||||||
|
|
||||||
|
// Traverse through all blocks in use by the filesystem
|
||||||
|
//
|
||||||
|
// The provided callback will be called with each block address that is
|
||||||
|
// currently in use by the filesystem. This can be used to determine which
|
||||||
|
// blocks are in use or how much of the storage is available.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_fs_traverse(lfs_t *lfs, int (*cb)(void*, lfs_block_t), void *data);
|
||||||
|
|
||||||
|
#ifdef LFS_MIGRATE
|
||||||
|
// Attempts to migrate a previous version of littlefs
|
||||||
|
//
|
||||||
|
// Behaves similarly to the lfs_format function. Attempts to mount
|
||||||
|
// the previous version of littlefs and update the filesystem so it can be
|
||||||
|
// mounted with the current version of littlefs.
|
||||||
|
//
|
||||||
|
// Requires a littlefs object and config struct. This clobbers the littlefs
|
||||||
|
// object, and does not leave the filesystem mounted. The config struct must
|
||||||
|
// be zeroed for defaults and backwards compatibility.
|
||||||
|
//
|
||||||
|
// Returns a negative error code on failure.
|
||||||
|
int lfs_migrate(lfs_t *lfs, const struct lfs_config *cfg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
33
lib/LITTLEFS/src/lfs_util.c
Normal file
33
lib/LITTLEFS/src/lfs_util.c
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* lfs util functions
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#include "lfs_util.h"
|
||||||
|
|
||||||
|
// Only compile if user does not provide custom config
|
||||||
|
#ifndef LFS_CONFIG
|
||||||
|
|
||||||
|
|
||||||
|
// Software CRC implementation with small lookup table
|
||||||
|
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size) {
|
||||||
|
static const uint32_t rtable[16] = {
|
||||||
|
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
||||||
|
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||||
|
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
||||||
|
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c,
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint8_t *data = buffer;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 0)) & 0xf];
|
||||||
|
crc = (crc >> 4) ^ rtable[(crc ^ (data[i] >> 4)) & 0xf];
|
||||||
|
}
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
234
lib/LITTLEFS/src/lfs_util.h
Normal file
234
lib/LITTLEFS/src/lfs_util.h
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
/*
|
||||||
|
* lfs utility functions
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017, Arm Limited. All rights reserved.
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
#ifndef LFS_UTIL_H
|
||||||
|
#define LFS_UTIL_H
|
||||||
|
|
||||||
|
// Users can override lfs_util.h with their own configuration by defining
|
||||||
|
// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h).
|
||||||
|
//
|
||||||
|
// If LFS_CONFIG is used, none of the default utils will be emitted and must be
|
||||||
|
// provided by the config file. To start, I would suggest copying lfs_util.h
|
||||||
|
// and modifying as needed.
|
||||||
|
#ifdef LFS_CONFIG
|
||||||
|
#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x)
|
||||||
|
#define LFS_STRINGIZE2(x) #x
|
||||||
|
#include LFS_STRINGIZE(LFS_CONFIG)
|
||||||
|
#else
|
||||||
|
|
||||||
|
// System includes
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#ifndef LFS_NO_MALLOC
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
#ifndef LFS_NO_ASSERT
|
||||||
|
#include <assert.h>
|
||||||
|
#endif
|
||||||
|
#if !defined(LFS_NO_DEBUG) || \
|
||||||
|
!defined(LFS_NO_WARN) || \
|
||||||
|
!defined(LFS_NO_ERROR) || \
|
||||||
|
defined(LFS_YES_TRACE)
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Macros, may be replaced by system specific wrappers. Arguments to these
|
||||||
|
// macros must not have side-effects as the macros can be removed for a smaller
|
||||||
|
// code footprint
|
||||||
|
|
||||||
|
// Logging functions
|
||||||
|
#ifdef LFS_YES_TRACE
|
||||||
|
#define LFS_TRACE_(fmt, ...) \
|
||||||
|
printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define LFS_TRACE(...) LFS_TRACE_(__VA_ARGS__, "")
|
||||||
|
#else
|
||||||
|
#define LFS_TRACE(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_NO_DEBUG
|
||||||
|
#define LFS_DEBUG_(fmt, ...) \
|
||||||
|
printf("%s:%d:debug: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define LFS_DEBUG(...) LFS_DEBUG_(__VA_ARGS__, "")
|
||||||
|
#else
|
||||||
|
#define LFS_DEBUG(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_NO_WARN
|
||||||
|
#define LFS_WARN_(fmt, ...) \
|
||||||
|
printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define LFS_WARN(...) LFS_WARN_(__VA_ARGS__, "")
|
||||||
|
#else
|
||||||
|
#define LFS_WARN(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LFS_NO_ERROR
|
||||||
|
#define LFS_ERROR_(fmt, ...) \
|
||||||
|
printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
#define LFS_ERROR(...) LFS_ERROR_(__VA_ARGS__, "")
|
||||||
|
#else
|
||||||
|
#define LFS_ERROR(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Runtime assertions
|
||||||
|
#ifndef LFS_NO_ASSERT
|
||||||
|
#define LFS_ASSERT(test) assert(test)
|
||||||
|
#else
|
||||||
|
#define LFS_ASSERT(test)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Builtin functions, these may be replaced by more efficient
|
||||||
|
// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more
|
||||||
|
// expensive basic C implementation for debugging purposes
|
||||||
|
|
||||||
|
// Min/max functions for unsigned 32-bit numbers
|
||||||
|
static inline uint32_t lfs_max(uint32_t a, uint32_t b) {
|
||||||
|
return (a > b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lfs_min(uint32_t a, uint32_t b) {
|
||||||
|
return (a < b) ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Align to nearest multiple of a size
|
||||||
|
static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) {
|
||||||
|
return a - (a % alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) {
|
||||||
|
return lfs_aligndown(a + alignment-1, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the smallest power of 2 greater than or equal to a
|
||||||
|
static inline uint32_t lfs_npw2(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||||
|
return 32 - __builtin_clz(a-1);
|
||||||
|
#else
|
||||||
|
uint32_t r = 0;
|
||||||
|
uint32_t s;
|
||||||
|
a -= 1;
|
||||||
|
s = (a > 0xffff) << 4; a >>= s; r |= s;
|
||||||
|
s = (a > 0xff ) << 3; a >>= s; r |= s;
|
||||||
|
s = (a > 0xf ) << 2; a >>= s; r |= s;
|
||||||
|
s = (a > 0x3 ) << 1; a >>= s; r |= s;
|
||||||
|
return (r | (a >> 1)) + 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of trailing binary zeros in a
|
||||||
|
// lfs_ctz(0) may be undefined
|
||||||
|
static inline uint32_t lfs_ctz(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__)
|
||||||
|
return __builtin_ctz(a);
|
||||||
|
#else
|
||||||
|
return lfs_npw2((a & -a) + 1) - 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count the number of binary ones in a
|
||||||
|
static inline uint32_t lfs_popc(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM))
|
||||||
|
return __builtin_popcount(a);
|
||||||
|
#else
|
||||||
|
a = a - ((a >> 1) & 0x55555555);
|
||||||
|
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
|
||||||
|
return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the sequence comparison of a and b, this is the distance
|
||||||
|
// between a and b ignoring overflow
|
||||||
|
static inline int lfs_scmp(uint32_t a, uint32_t b) {
|
||||||
|
return (int)(unsigned)(a - b);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert between 32-bit little-endian and native order
|
||||||
|
static inline uint32_t lfs_fromle32(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && ( \
|
||||||
|
(defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \
|
||||||
|
(defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \
|
||||||
|
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||||
|
return a;
|
||||||
|
#elif !defined(LFS_NO_INTRINSICS) && ( \
|
||||||
|
(defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \
|
||||||
|
(defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \
|
||||||
|
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||||
|
return __builtin_bswap32(a);
|
||||||
|
#else
|
||||||
|
return (((uint8_t*)&a)[0] << 0) |
|
||||||
|
(((uint8_t*)&a)[1] << 8) |
|
||||||
|
(((uint8_t*)&a)[2] << 16) |
|
||||||
|
(((uint8_t*)&a)[3] << 24);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lfs_tole32(uint32_t a) {
|
||||||
|
return lfs_fromle32(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert between 32-bit big-endian and native order
|
||||||
|
static inline uint32_t lfs_frombe32(uint32_t a) {
|
||||||
|
#if !defined(LFS_NO_INTRINSICS) && ( \
|
||||||
|
(defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \
|
||||||
|
(defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \
|
||||||
|
(defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
|
||||||
|
return __builtin_bswap32(a);
|
||||||
|
#elif !defined(LFS_NO_INTRINSICS) && ( \
|
||||||
|
(defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \
|
||||||
|
(defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \
|
||||||
|
(defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||||
|
return a;
|
||||||
|
#else
|
||||||
|
return (((uint8_t*)&a)[0] << 24) |
|
||||||
|
(((uint8_t*)&a)[1] << 16) |
|
||||||
|
(((uint8_t*)&a)[2] << 8) |
|
||||||
|
(((uint8_t*)&a)[3] << 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t lfs_tobe32(uint32_t a) {
|
||||||
|
return lfs_frombe32(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate CRC-32 with polynomial = 0x04c11db7
|
||||||
|
uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size);
|
||||||
|
|
||||||
|
// Allocate memory, only used if buffers are not provided to littlefs
|
||||||
|
// Note, memory must be 64-bit aligned
|
||||||
|
static inline void *lfs_malloc(size_t size) {
|
||||||
|
#ifndef LFS_NO_MALLOC
|
||||||
|
return malloc(size);
|
||||||
|
#else
|
||||||
|
(void)size;
|
||||||
|
return NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deallocate memory, only used if buffers are not provided to littlefs
|
||||||
|
static inline void lfs_free(void *p) {
|
||||||
|
#ifndef LFS_NO_MALLOC
|
||||||
|
free(p);
|
||||||
|
#else
|
||||||
|
(void)p;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} /* extern "C" */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
58
lib/LITTLEFS/src/littlefs_api.c
Normal file
58
lib/LITTLEFS/src/littlefs_api.c
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
/**
|
||||||
|
* @file littlefs_api.c
|
||||||
|
* @brief Maps the HAL of esp_partition <-> littlefs
|
||||||
|
* @author Brian Pugh
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ESP_LOCAL_LOG_LEVEL ESP_LOG_INFO
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_partition.h"
|
||||||
|
#include "esp_vfs.h"
|
||||||
|
#include "lfs.h"
|
||||||
|
#include "esp_littlefs.h"
|
||||||
|
#include "littlefs_api.h"
|
||||||
|
|
||||||
|
static const char TAG[] = "esp_littlefs_api";
|
||||||
|
|
||||||
|
int littlefs_api_read(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, void *buffer, lfs_size_t size) {
|
||||||
|
esp_littlefs_t * efs = c->context;
|
||||||
|
size_t part_off = (block * c->block_size) + off;
|
||||||
|
esp_err_t err = esp_partition_read(efs->partition, part_off, buffer, size);
|
||||||
|
if (err) {
|
||||||
|
ESP_LOGE(TAG, "failed to read addr %08x, size %08x, err %d", part_off, size, err);
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int littlefs_api_prog(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, const void *buffer, lfs_size_t size) {
|
||||||
|
esp_littlefs_t * efs = c->context;
|
||||||
|
size_t part_off = (block * c->block_size) + off;
|
||||||
|
esp_err_t err = esp_partition_write(efs->partition, part_off, buffer, size);
|
||||||
|
if (err) {
|
||||||
|
ESP_LOGE(TAG, "failed to write addr %08x, size %08x, err %d", part_off, size, err);
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int littlefs_api_erase(const struct lfs_config *c, lfs_block_t block) {
|
||||||
|
esp_littlefs_t * efs = c->context;
|
||||||
|
size_t part_off = block * c->block_size;
|
||||||
|
esp_err_t err = esp_partition_erase_range(efs->partition, part_off, c->block_size);
|
||||||
|
if (err) {
|
||||||
|
ESP_LOGE(TAG, "failed to erase addr %08x, size %08x, err %d", part_off, c->block_size, err);
|
||||||
|
return LFS_ERR_IO;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int littlefs_api_sync(const struct lfs_config *c) {
|
||||||
|
/* Unnecessary for esp-idf */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
106
lib/LITTLEFS/src/littlefs_api.h
Normal file
106
lib/LITTLEFS/src/littlefs_api.h
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
#ifndef ESP_LITTLEFS_API_H__
|
||||||
|
#define ESP_LITTLEFS_API_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "esp_vfs.h"
|
||||||
|
#include "esp_partition.h"
|
||||||
|
#include "lfs.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief a file descriptor
|
||||||
|
* That's also a singly linked list used for keeping tracks of all opened file descriptor
|
||||||
|
*
|
||||||
|
* Shortcomings/potential issues of 32-bit hash (when CONFIG_LITTLEFS_USE_ONLY_HASH) listed here:
|
||||||
|
* * unlink - If a different file is open that generates a hash collision, it will report an
|
||||||
|
* error that it cannot unlink an open file.
|
||||||
|
* * rename - If a different file is open that generates a hash collision with
|
||||||
|
* src or dst, it will report an error that it cannot rename an open file.
|
||||||
|
* Potential consequences:
|
||||||
|
* 1. A file cannot be deleted while a collision-geneating file is open.
|
||||||
|
* Worst-case, if the other file is always open during the lifecycle
|
||||||
|
* of your app, it's collision file cannot be deleted, which in the
|
||||||
|
* worst-case could cause storage-capacity issues.
|
||||||
|
* 2. Same as (1), but for renames
|
||||||
|
*/
|
||||||
|
typedef struct _vfs_littlefs_file_t {
|
||||||
|
lfs_file_t file;
|
||||||
|
uint32_t hash;
|
||||||
|
struct _vfs_littlefs_file_t * next; /*!< Pointer to next file in Singly Linked List */
|
||||||
|
#ifndef CONFIG_LITTLEFS_USE_ONLY_HASH
|
||||||
|
char * path;
|
||||||
|
#endif
|
||||||
|
} vfs_littlefs_file_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief littlefs definition structure
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
lfs_t *fs; /*!< Handle to the underlying littlefs */
|
||||||
|
SemaphoreHandle_t lock; /*!< FS lock */
|
||||||
|
const esp_partition_t* partition; /*!< The partition on which littlefs is located */
|
||||||
|
char base_path[ESP_VFS_PATH_MAX+1]; /*!< Mount point */
|
||||||
|
|
||||||
|
struct lfs_config cfg; /*!< littlefs Mount configuration */
|
||||||
|
|
||||||
|
vfs_littlefs_file_t *file; /*!< Singly Linked List of files */
|
||||||
|
|
||||||
|
vfs_littlefs_file_t **cache; /*!< A cache of pointers to the opened files */
|
||||||
|
uint16_t cache_size; /*!< The cache allocated size (in pointers) */
|
||||||
|
uint16_t fd_count; /*!< The count of opened file descriptor used to speed up computation */
|
||||||
|
} esp_littlefs_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a region in a block.
|
||||||
|
*
|
||||||
|
* Negative error codes are propogated to the user.
|
||||||
|
*
|
||||||
|
* @return errorcode. 0 on success.
|
||||||
|
*/
|
||||||
|
int littlefs_api_read(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Program a region in a block.
|
||||||
|
*
|
||||||
|
* The block must have previously been erased.
|
||||||
|
* Negative error codes are propogated to the user.
|
||||||
|
* May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||||
|
*
|
||||||
|
* @return errorcode. 0 on success.
|
||||||
|
*/
|
||||||
|
int littlefs_api_prog(const struct lfs_config *c, lfs_block_t block,
|
||||||
|
lfs_off_t off, const void *buffer, lfs_size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Erase a block.
|
||||||
|
*
|
||||||
|
* A block must be erased before being programmed.
|
||||||
|
* The state of an erased block is undefined.
|
||||||
|
* Negative error codes are propogated to the user.
|
||||||
|
* May return LFS_ERR_CORRUPT if the block should be considered bad.
|
||||||
|
* @return errorcode. 0 on success.
|
||||||
|
*/
|
||||||
|
int littlefs_api_erase(const struct lfs_config *c, lfs_block_t block);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sync the state of the underlying block device.
|
||||||
|
*
|
||||||
|
* Negative error codes are propogated to the user.
|
||||||
|
*
|
||||||
|
* @return errorcode. 0 on success.
|
||||||
|
*/
|
||||||
|
int littlefs_api_sync(const struct lfs_config *c);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -15,7 +15,8 @@ default_envs = esp8266
|
|||||||
framework = arduino
|
framework = arduino
|
||||||
|
|
||||||
[env:esp32]
|
[env:esp32]
|
||||||
platform = espressif32
|
platform = https://github.com/platformio/platform-espressif32.git
|
||||||
|
build_flags = ${env.build_flags} -D=${PIOENV}
|
||||||
board = esp32dev
|
board = esp32dev
|
||||||
board_build.partitions = partitions_custom.csv
|
board_build.partitions = partitions_custom.csv
|
||||||
monitor_filters = esp32_exception_decoder
|
monitor_filters = esp32_exception_decoder
|
||||||
@@ -23,7 +24,6 @@ monitor_speed = 115200
|
|||||||
lib_deps =
|
lib_deps =
|
||||||
ModuleInterface@3.5.1
|
ModuleInterface@3.5.1
|
||||||
ArduinoJson@5.*
|
ArduinoJson@5.*
|
||||||
AsyncTCP
|
|
||||||
ESP32Servo
|
ESP32Servo
|
||||||
Bounce2
|
Bounce2
|
||||||
PubSubClient
|
PubSubClient
|
||||||
@@ -34,8 +34,8 @@ lib_deps =
|
|||||||
Adafruit BME280 Library
|
Adafruit BME280 Library
|
||||||
|
|
||||||
[env:esp8266]
|
[env:esp8266]
|
||||||
build_flags =-Wno-deprecated
|
|
||||||
platform = https://github.com/platformio/platform-espressif8266.git
|
platform = https://github.com/platformio/platform-espressif8266.git
|
||||||
|
build_flags = ${env.build_flags} -D=${PIOENV}
|
||||||
board = nodemcuv2
|
board = nodemcuv2
|
||||||
monitor_filters = esp8266_exception_decoder
|
monitor_filters = esp8266_exception_decoder
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|||||||
30
src/Cmd.cpp
30
src/Cmd.cpp
@@ -19,17 +19,17 @@ void CMD_init() {
|
|||||||
|
|
||||||
sCmd.addCommand("switch", switch_);
|
sCmd.addCommand("switch", switch_);
|
||||||
|
|
||||||
#ifdef analog_enable
|
#ifdef ANALOG_ENABLED
|
||||||
sCmd.addCommand("analog", analog);
|
sCmd.addCommand("analog", analog);
|
||||||
#endif
|
#endif
|
||||||
#ifdef level_enable
|
#ifdef LEVEL_ENABLED
|
||||||
sCmd.addCommand("levelPr", levelPr);
|
sCmd.addCommand("levelPr", levelPr);
|
||||||
sCmd.addCommand("ultrasonicCm", ultrasonicCm);
|
sCmd.addCommand("ultrasonicCm", ultrasonicCm);
|
||||||
#endif
|
#endif
|
||||||
#ifdef dallas_enable
|
#ifdef DALLAS_ENABLED
|
||||||
sCmd.addCommand("dallas", dallas);
|
sCmd.addCommand("dallas", dallas);
|
||||||
#endif
|
#endif
|
||||||
#ifdef dht_enable
|
#ifdef DHT_ENABLED
|
||||||
sCmd.addCommand("dhtT", dhtT);
|
sCmd.addCommand("dhtT", dhtT);
|
||||||
sCmd.addCommand("dhtH", dhtH);
|
sCmd.addCommand("dhtH", dhtH);
|
||||||
sCmd.addCommand("dhtPerception", dhtP);
|
sCmd.addCommand("dhtPerception", dhtP);
|
||||||
@@ -37,34 +37,34 @@ void CMD_init() {
|
|||||||
sCmd.addCommand("dhtDewpoint", dhtD);
|
sCmd.addCommand("dhtDewpoint", dhtD);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef bmp_enable
|
#ifdef BMP_ENABLED
|
||||||
sCmd.addCommand("bmp280T", bmp280T);
|
sCmd.addCommand("bmp280T", bmp280T);
|
||||||
sCmd.addCommand("bmp280P", bmp280P);
|
sCmd.addCommand("bmp280P", bmp280P);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef bme_enable
|
#ifdef BME_ENABLED
|
||||||
sCmd.addCommand("bme280T", bme280T);
|
sCmd.addCommand("bme280T", bme280T);
|
||||||
sCmd.addCommand("bme280P", bme280P);
|
sCmd.addCommand("bme280P", bme280P);
|
||||||
sCmd.addCommand("bme280H", bme280H);
|
sCmd.addCommand("bme280H", bme280H);
|
||||||
sCmd.addCommand("bme280A", bme280A);
|
sCmd.addCommand("bme280A", bme280A);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef stepper_enable
|
#ifdef STEPPER_ENABLED
|
||||||
sCmd.addCommand("stepper", stepper);
|
sCmd.addCommand("stepper", stepper);
|
||||||
sCmd.addCommand("stepperSet", stepperSet);
|
sCmd.addCommand("stepperSet", stepperSet);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef servo_enable
|
#ifdef SERVO_ENABLED
|
||||||
sCmd.addCommand("servo", servo_);
|
sCmd.addCommand("servo", servo_);
|
||||||
sCmd.addCommand("servoSet", servoSet);
|
sCmd.addCommand("servoSet", servoSet);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef serial_enable
|
#ifdef SERIAL_ENABLED
|
||||||
sCmd.addCommand("serialBegin", serialBegin);
|
sCmd.addCommand("serialBegin", serialBegin);
|
||||||
sCmd.addCommand("serialWrite", serialWrite);
|
sCmd.addCommand("serialWrite", serialWrite);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef logging_enable
|
#ifdef LOGGING_ENABLED
|
||||||
sCmd.addCommand("logging", logging);
|
sCmd.addCommand("logging", logging);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -83,7 +83,7 @@ void CMD_init() {
|
|||||||
sCmd.addCommand("mqtt", mqttOrderSend);
|
sCmd.addCommand("mqtt", mqttOrderSend);
|
||||||
sCmd.addCommand("http", httpOrderSend);
|
sCmd.addCommand("http", httpOrderSend);
|
||||||
|
|
||||||
#ifdef push_enable
|
#ifdef PUSH_ENABLED
|
||||||
sCmd.addCommand("push", pushControl);
|
sCmd.addCommand("push", pushControl);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -345,7 +345,7 @@ void textSet() {
|
|||||||
}
|
}
|
||||||
//=====================================================================================================================================
|
//=====================================================================================================================================
|
||||||
//=========================================Модуль шагового мотора======================================================================
|
//=========================================Модуль шагового мотора======================================================================
|
||||||
#ifdef stepper_enable
|
#ifdef STEPPER_ENABLED
|
||||||
//stepper 1 12 13
|
//stepper 1 12 13
|
||||||
void stepper() {
|
void stepper() {
|
||||||
String stepper_number = sCmd.next();
|
String stepper_number = sCmd.next();
|
||||||
@@ -407,7 +407,7 @@ void stepperSet() {
|
|||||||
#endif
|
#endif
|
||||||
//====================================================================================================================================================
|
//====================================================================================================================================================
|
||||||
//=================================================================Сервоприводы=======================================================================
|
//=================================================================Сервоприводы=======================================================================
|
||||||
#ifdef servo_enable
|
#ifdef SERVO_ENABLED
|
||||||
//servo 1 13 50 Мой#сервопривод Сервоприводы 0 100 0 180 2
|
//servo 1 13 50 Мой#сервопривод Сервоприводы 0 100 0 180 2
|
||||||
void servo_() {
|
void servo_() {
|
||||||
String servo_number = sCmd.next();
|
String servo_number = sCmd.next();
|
||||||
@@ -501,7 +501,7 @@ void servoSet() {
|
|||||||
#endif
|
#endif
|
||||||
//====================================================================================================================================================
|
//====================================================================================================================================================
|
||||||
//===================================================================================serial===========================================================
|
//===================================================================================serial===========================================================
|
||||||
#ifdef serial_enable
|
#ifdef SERIAL_ENABLED
|
||||||
void serialBegin() {
|
void serialBegin() {
|
||||||
//String s_speed = sCmd.next();
|
//String s_speed = sCmd.next();
|
||||||
//String rxPin = sCmd.next();
|
//String rxPin = sCmd.next();
|
||||||
@@ -545,7 +545,7 @@ void firmwareVersion() {
|
|||||||
String widget_name = sCmd.next();
|
String widget_name = sCmd.next();
|
||||||
String page_name = sCmd.next();
|
String page_name = sCmd.next();
|
||||||
String page_number = sCmd.next();
|
String page_number = sCmd.next();
|
||||||
jsonWriteStr(configLiveJson, "firmver", firmware_version);
|
jsonWriteStr(configLiveJson, "firmver", FIRMWARE_VERSION);
|
||||||
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "firmver");
|
choose_widget_and_create(widget_name, page_name, page_number, "any-data", "firmver");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
34
src/Init.cpp
34
src/Init.cpp
@@ -7,18 +7,15 @@ UptimeInterval myUptime(10);
|
|||||||
void handle_uptime();
|
void handle_uptime();
|
||||||
void handle_statistics();
|
void handle_statistics();
|
||||||
|
|
||||||
void File_system_init() {
|
void loadConfig() {
|
||||||
if (!LittleFS.begin()) {
|
if (fileSystemInit()) {
|
||||||
Serial.println("[E] LittleFS");
|
configSetupJson = readFile("config.json", 4096);
|
||||||
return;
|
configSetupJson.replace(" ", "");
|
||||||
|
configSetupJson.replace("\r\n", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
configSetupJson = readFile("config.json", 4096);
|
|
||||||
configSetupJson.replace(" ", "");
|
|
||||||
configSetupJson.replace("\r\n", "");
|
|
||||||
|
|
||||||
jsonWriteStr(configSetupJson, "chipID", chipId);
|
jsonWriteStr(configSetupJson, "chipID", chipId);
|
||||||
jsonWriteStr(configSetupJson, "firmware_version", firmware_version);
|
jsonWriteStr(configSetupJson, "firmware_version", FIRMWARE_VERSION);
|
||||||
|
|
||||||
prex = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + chipId;
|
prex = jsonReadStr(configSetupJson, "mqttPrefix") + "/" + chipId;
|
||||||
|
|
||||||
@@ -62,10 +59,10 @@ void Device_init() {
|
|||||||
ts.remove(i);
|
ts.remove(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef layout_in_ram
|
#ifdef LAYOUT_IN_RAM
|
||||||
all_widgets = "";
|
all_widgets = "";
|
||||||
#else
|
#else
|
||||||
LittleFS.remove("/layout.txt");
|
removeFile("/layout.txt");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
txtExecution("firmware.c.txt");
|
txtExecution("firmware.c.txt");
|
||||||
@@ -85,11 +82,14 @@ void uptime_init() {
|
|||||||
handle_uptime();
|
handle_uptime();
|
||||||
},
|
},
|
||||||
nullptr, true);
|
nullptr, true);
|
||||||
ts.add(
|
|
||||||
STATISTICS, statistics_update, [&](void*) {
|
if (TELEMETRY_UPDATE_INTERVAL) {
|
||||||
handle_statistics();
|
ts.add(
|
||||||
},
|
STATISTICS, TELEMETRY_UPDATE_INTERVAL, [&](void*) {
|
||||||
nullptr, true);
|
handle_statistics();
|
||||||
|
},
|
||||||
|
nullptr, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_uptime() {
|
void handle_uptime() {
|
||||||
@@ -123,7 +123,7 @@ void handle_statistics() {
|
|||||||
urls += "&";
|
urls += "&";
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
urls += "ver: ";
|
urls += "ver: ";
|
||||||
urls += String(firmware_version);
|
urls += String(FIRMWARE_VERSION);
|
||||||
//-----------------------------------------------------------------
|
//-----------------------------------------------------------------
|
||||||
String stat = getURL(urls);
|
String stat = getURL(urls);
|
||||||
//Serial.println(stat);
|
//Serial.println(stat);
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
#include <LITTLEFS.h>
|
||||||
|
|
||||||
void sendLogData(String file, String topic);
|
void sendLogData(String file, String topic);
|
||||||
|
|
||||||
#ifdef logging_enable
|
#ifdef LOGGING_ENABLED
|
||||||
//===============================================Логирование============================================================
|
//===============================================Логирование============================================================
|
||||||
//logging temp1 1 10 Температура Датчики 2
|
//logging temp1 1 10 Температура Датчики 2
|
||||||
void logging() {
|
void logging() {
|
||||||
@@ -22,7 +25,7 @@ void logging() {
|
|||||||
LOG1, period_min.toInt() * 1000 * 60, [&](void*) {
|
LOG1, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||||
String tmp_buf_1 = selectFromMarkerToMarker(logging_value_names_list, ",", 0);
|
String tmp_buf_1 = selectFromMarkerToMarker(logging_value_names_list, ",", 0);
|
||||||
deleteOldDate("log." + tmp_buf_1 + ".txt", jsonReadInt(configOptionJson, tmp_buf_1 + "_c"), jsonReadStr(configLiveJson, tmp_buf_1));
|
deleteOldDate("log." + tmp_buf_1 + ".txt", jsonReadInt(configOptionJson, tmp_buf_1 + "_c"), jsonReadStr(configLiveJson, tmp_buf_1));
|
||||||
Serial.println("[I] LOGGING for sensor '" + tmp_buf_1 + "' done");
|
Serial.println("[I] LOGGING for sensor '" + tmp_buf_1 + "' done");
|
||||||
},
|
},
|
||||||
nullptr, false);
|
nullptr, false);
|
||||||
}
|
}
|
||||||
@@ -31,7 +34,7 @@ void logging() {
|
|||||||
LOG2, period_min.toInt() * 1000 * 60, [&](void*) {
|
LOG2, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||||
String tmp_buf_2 = selectFromMarkerToMarker(logging_value_names_list, ",", 1);
|
String tmp_buf_2 = selectFromMarkerToMarker(logging_value_names_list, ",", 1);
|
||||||
deleteOldDate("log." + tmp_buf_2 + ".txt", jsonReadInt(configOptionJson, tmp_buf_2 + "_c"), jsonReadStr(configLiveJson, tmp_buf_2));
|
deleteOldDate("log." + tmp_buf_2 + ".txt", jsonReadInt(configOptionJson, tmp_buf_2 + "_c"), jsonReadStr(configLiveJson, tmp_buf_2));
|
||||||
Serial.println("[I] LOGGING for sensor '" + tmp_buf_2 + "' done");
|
Serial.println("[I] LOGGING for sensor '" + tmp_buf_2 + "' done");
|
||||||
},
|
},
|
||||||
nullptr, false);
|
nullptr, false);
|
||||||
}
|
}
|
||||||
@@ -40,7 +43,7 @@ void logging() {
|
|||||||
LOG3, period_min.toInt() * 1000 * 60, [&](void*) {
|
LOG3, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||||
String tmp_buf_3 = selectFromMarkerToMarker(logging_value_names_list, ",", 2);
|
String tmp_buf_3 = selectFromMarkerToMarker(logging_value_names_list, ",", 2);
|
||||||
deleteOldDate("log." + tmp_buf_3 + ".txt", jsonReadInt(configOptionJson, tmp_buf_3 + "_c"), jsonReadStr(configLiveJson, tmp_buf_3));
|
deleteOldDate("log." + tmp_buf_3 + ".txt", jsonReadInt(configOptionJson, tmp_buf_3 + "_c"), jsonReadStr(configLiveJson, tmp_buf_3));
|
||||||
Serial.println("[I] LOGGING for sensor '" + tmp_buf_3 + "' done");
|
Serial.println("[I] LOGGING for sensor '" + tmp_buf_3 + "' done");
|
||||||
},
|
},
|
||||||
nullptr, false);
|
nullptr, false);
|
||||||
}
|
}
|
||||||
@@ -49,7 +52,7 @@ void logging() {
|
|||||||
LOG4, period_min.toInt() * 1000 * 60, [&](void*) {
|
LOG4, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||||
String tmp_buf_4 = selectFromMarkerToMarker(logging_value_names_list, ",", 3);
|
String tmp_buf_4 = selectFromMarkerToMarker(logging_value_names_list, ",", 3);
|
||||||
deleteOldDate("log." + tmp_buf_4 + ".txt", jsonReadInt(configOptionJson, tmp_buf_4 + "_c"), jsonReadStr(configLiveJson, tmp_buf_4));
|
deleteOldDate("log." + tmp_buf_4 + ".txt", jsonReadInt(configOptionJson, tmp_buf_4 + "_c"), jsonReadStr(configLiveJson, tmp_buf_4));
|
||||||
Serial.println("[I] LOGGING for sensor '" + tmp_buf_4 + "' done");
|
Serial.println("[I] LOGGING for sensor '" + tmp_buf_4 + "' done");
|
||||||
},
|
},
|
||||||
nullptr, false);
|
nullptr, false);
|
||||||
}
|
}
|
||||||
@@ -58,35 +61,33 @@ void logging() {
|
|||||||
LOG5, period_min.toInt() * 1000 * 60, [&](void*) {
|
LOG5, period_min.toInt() * 1000 * 60, [&](void*) {
|
||||||
String tmp_buf_5 = selectFromMarkerToMarker(logging_value_names_list, ",", 4);
|
String tmp_buf_5 = selectFromMarkerToMarker(logging_value_names_list, ",", 4);
|
||||||
deleteOldDate("log." + tmp_buf_5 + ".txt", jsonReadInt(configOptionJson, tmp_buf_5 + "_c"), jsonReadStr(configLiveJson, tmp_buf_5));
|
deleteOldDate("log." + tmp_buf_5 + ".txt", jsonReadInt(configOptionJson, tmp_buf_5 + "_c"), jsonReadStr(configLiveJson, tmp_buf_5));
|
||||||
Serial.println("[I] LOGGING for sensor '" + tmp_buf_5 + "' done");
|
Serial.println("[I] LOGGING for sensor '" + tmp_buf_5 + "' done");
|
||||||
},
|
},
|
||||||
nullptr, false);
|
nullptr, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=========================================Удаление стрых данных и запись новых==================================================================
|
//=========================================Удаление стрых данных и запись новых==================================================================
|
||||||
void deleteOldDate(String file, int seted_number_of_lines, String date_to_add) {
|
void deleteOldDate(const String filename, int max_lines_cnt, String date_to_add) {
|
||||||
String log_date = readFile(file, 5000);
|
String log_date = readFile(filename, 5120);
|
||||||
int current_number_of_lines = itemsCount(log_date, "\r\n");
|
size_t lines_cnt = itemsCount(log_date, "\r\n");
|
||||||
Serial.println("=====> [i] in log file " + file + " " + current_number_of_lines + " lines");
|
|
||||||
|
|
||||||
if (current_number_of_lines > seted_number_of_lines + 1) {
|
Serial.printf("[I] log %s of %d lines\n", filename.c_str(), lines_cnt);
|
||||||
LittleFS.remove("/" + file);
|
|
||||||
current_number_of_lines = 0;
|
if ((lines_cnt > max_lines_cnt + 1) || !lines_cnt) {
|
||||||
|
removeFile("/" + filename);
|
||||||
|
lines_cnt = 0;
|
||||||
}
|
}
|
||||||
if (current_number_of_lines == 0) {
|
|
||||||
LittleFS.remove("/" + file);
|
if (lines_cnt > max_lines_cnt) {
|
||||||
current_number_of_lines = 0;
|
|
||||||
}
|
|
||||||
if (current_number_of_lines > seted_number_of_lines) {
|
|
||||||
log_date = deleteBeforeDelimiter(log_date, "\r\n");
|
log_date = deleteBeforeDelimiter(log_date, "\r\n");
|
||||||
if (getTimeUnix() != "failed") {
|
if (getTimeUnix() != "failed") {
|
||||||
log_date += getTimeUnix() + " " + date_to_add + "\r\n";
|
log_date += getTimeUnix() + " " + date_to_add + "\r\n";
|
||||||
writeFile(file, log_date);
|
writeFile(filename, log_date);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (getTimeUnix() != "failed") {
|
if (getTimeUnix() != "failed") {
|
||||||
addFile(file, getTimeUnix() + " " + date_to_add);
|
addFile(filename, getTimeUnix() + " " + date_to_add);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log_date = "";
|
log_date = "";
|
||||||
@@ -133,7 +134,7 @@ void sendLogData(String file, String topic) {
|
|||||||
Serial.println(json_array);
|
Serial.println(json_array);
|
||||||
sendCHART(topic, json_array);
|
sendCHART(topic, json_array);
|
||||||
json_array = "";
|
json_array = "";
|
||||||
getMemoryLoad("[I] after send log date");
|
printMemoryStatus("[I] send log date");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,12 +155,13 @@ void sendLogData(String file, String topic) {
|
|||||||
}
|
}
|
||||||
getMemoryLoad("[I] after send log date");
|
getMemoryLoad("[I] after send log date");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//=========================================Очистка данных===================================================================================
|
//=========================================Очистка данных===================================================================================
|
||||||
void clean_log_date() {
|
void clean_log_date() {
|
||||||
String all_line = logging_value_names_list;
|
String all_line = logging_value_names_list;
|
||||||
while (all_line.length() != 0) {
|
while (all_line.length() != 0) {
|
||||||
String tmp = selectToMarker(all_line, ",");
|
String tmp = selectToMarker(all_line, ",");
|
||||||
LittleFS.remove("/log." + tmp + ".txt");
|
removeFile("/log." + tmp + ".txt");
|
||||||
all_line = deleteBeforeDelimiter(all_line, ",");
|
all_line = deleteBeforeDelimiter(all_line, ",");
|
||||||
}
|
}
|
||||||
all_line = "";
|
all_line = "";
|
||||||
|
|||||||
27
src/Mqtt.cpp
27
src/Mqtt.cpp
@@ -1,5 +1,8 @@
|
|||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
#include <LittleFS.h>
|
||||||
|
|
||||||
// Errors
|
// Errors
|
||||||
int wifi_lost_error = 0;
|
int wifi_lost_error = 0;
|
||||||
int mqtt_lost_error = 0;
|
int mqtt_lost_error = 0;
|
||||||
@@ -14,7 +17,7 @@ void outcoming_date();
|
|||||||
//===============================================ИНИЦИАЛИЗАЦИЯ================================================
|
//===============================================ИНИЦИАЛИЗАЦИЯ================================================
|
||||||
void MQTT_init() {
|
void MQTT_init() {
|
||||||
ts.add(
|
ts.add(
|
||||||
WIFI_MQTT_CONNECTION_CHECK, wifi_mqtt_reconnecting, [&](void*) {
|
WIFI_MQTT_CONNECTION_CHECK, MQTT_RECONNECT_INTERVAL, [&](void*) {
|
||||||
if (WiFi.status() == WL_CONNECTED) {
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
Serial.println("[VV] WiFi-ok");
|
Serial.println("[VV] WiFi-ok");
|
||||||
if (client_mqtt.connected()) {
|
if (client_mqtt.connected()) {
|
||||||
@@ -73,7 +76,7 @@ boolean MQTT_Connecting() {
|
|||||||
Serial.println("[V] Callback set, subscribe done");
|
Serial.println("[V] Callback set, subscribe done");
|
||||||
res = true;
|
res = true;
|
||||||
} else {
|
} else {
|
||||||
Serial.println("[E] try again in " + String(wifi_mqtt_reconnecting / 1000) + " sec");
|
Serial.println("[E] try again in " + String(MQTT_RECONNECT_INTERVAL / 1000) + " sec");
|
||||||
led_blink("fast");
|
led_blink("fast");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +136,7 @@ void outcoming_date() {
|
|||||||
sendAllWigets();
|
sendAllWigets();
|
||||||
sendAllData();
|
sendAllData();
|
||||||
|
|
||||||
#ifdef logging_enable
|
#ifdef LOGGING_ENABLED
|
||||||
choose_log_date_and_send();
|
choose_log_date_and_send();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -179,7 +182,7 @@ void sendCONTROL(String id, String topik, String state) {
|
|||||||
|
|
||||||
//=====================================================ОТПРАВЛЯЕМ ВИДЖЕТЫ========================================================
|
//=====================================================ОТПРАВЛЯЕМ ВИДЖЕТЫ========================================================
|
||||||
|
|
||||||
#ifdef layout_in_ram
|
#ifdef LAYOUT_IN_RAM
|
||||||
void sendAllWigets() {
|
void sendAllWigets() {
|
||||||
if (all_widgets != "") {
|
if (all_widgets != "") {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
@@ -203,26 +206,26 @@ void sendAllWigets() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef layout_in_ram
|
#ifndef LAYOUT_IN_RAM
|
||||||
void sendAllWigets() {
|
void sendAllWigets() {
|
||||||
auto file = LittleFS.open("/layout.txt", "r");
|
auto file = seekFile("/layout.txt");
|
||||||
if (!file) {
|
if (!file) {
|
||||||
Serial.println("[e] on open layout.txt");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
file.seek(0, SeekSet); //поставим курсор в начало файла
|
|
||||||
while (file.position() != file.size()) {
|
while (file.position() != file.size()) {
|
||||||
String widget_to_send = file.readStringUntil('\n');
|
String payload = file.readStringUntil('\n');
|
||||||
Serial.println("[V] " + widget_to_send);
|
Serial.println("[V] " + payload);
|
||||||
sendMQTT("config", widget_to_send);
|
sendMQTT("config", payload);
|
||||||
}
|
}
|
||||||
|
file.close();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//=====================================================ОТПРАВЛЯЕМ ДАННЫЕ В ВИДЖЕТЫ ПРИ ОБНОВЛЕНИИ СТРАНИЦЫ========================================================
|
//=====================================================ОТПРАВЛЯЕМ ДАННЫЕ В ВИДЖЕТЫ ПРИ ОБНОВЛЕНИИ СТРАНИЦЫ========================================================
|
||||||
void sendAllData() { //берет строку json и ключи превращает в топики а значения колючей в них посылает
|
void sendAllData() { //берет строку json и ключи превращает в топики а значения колючей в них посылает
|
||||||
|
|
||||||
String current_config = configLiveJson; //{"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"}
|
String current_config = configLiveJson; //{"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"}
|
||||||
getMemoryLoad("[I] after send all date");
|
printMemoryStatus("[I] after send all date");
|
||||||
current_config.replace("{", "");
|
current_config.replace("{", "");
|
||||||
current_config.replace("}", ""); //"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"
|
current_config.replace("}", ""); //"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1"
|
||||||
current_config += ","; //"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1",
|
current_config += ","; //"name":"MODULES","lang":"","ip":"192.168.43.60","DS":"34.00","rel1":"1","rel2":"1",
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void sensors_init() {
|
|||||||
static int counter;
|
static int counter;
|
||||||
counter++;
|
counter++;
|
||||||
|
|
||||||
#ifdef level_enable
|
#ifdef LEVEL_ENABLED
|
||||||
if (sensors_reading_map[0] == 1)
|
if (sensors_reading_map[0] == 1)
|
||||||
ultrasonic_reading();
|
ultrasonic_reading();
|
||||||
#endif
|
#endif
|
||||||
@@ -31,19 +31,19 @@ void sensors_init() {
|
|||||||
if (counter > 10) {
|
if (counter > 10) {
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
#ifdef analog_enable
|
#ifdef ANALOG_ENABLED
|
||||||
if (sensors_reading_map[1] == 1)
|
if (sensors_reading_map[1] == 1)
|
||||||
analog_reading1();
|
analog_reading1();
|
||||||
if (sensors_reading_map[2] == 1)
|
if (sensors_reading_map[2] == 1)
|
||||||
analog_reading2();
|
analog_reading2();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef dallas_enable
|
#ifdef DALLAS_ENABLED
|
||||||
if (sensors_reading_map[3] == 1)
|
if (sensors_reading_map[3] == 1)
|
||||||
dallas_reading();
|
dallas_reading();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef dht_enable
|
#ifdef DHT_ENABLED
|
||||||
if (sensors_reading_map[4] == 1)
|
if (sensors_reading_map[4] == 1)
|
||||||
dhtT_reading();
|
dhtT_reading();
|
||||||
if (sensors_reading_map[5] == 1)
|
if (sensors_reading_map[5] == 1)
|
||||||
@@ -56,14 +56,14 @@ void sensors_init() {
|
|||||||
dhtD_reading();
|
dhtD_reading();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef bmp_enable
|
#ifdef BMP_ENABLED
|
||||||
if (sensors_reading_map[9] == 1)
|
if (sensors_reading_map[9] == 1)
|
||||||
bmp280T_reading();
|
bmp280T_reading();
|
||||||
if (sensors_reading_map[10] == 1)
|
if (sensors_reading_map[10] == 1)
|
||||||
bmp280P_reading();
|
bmp280P_reading();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef bme_enable
|
#ifdef BME_ENABLED
|
||||||
if (sensors_reading_map[11] == 1)
|
if (sensors_reading_map[11] == 1)
|
||||||
bme280T_reading();
|
bme280T_reading();
|
||||||
if (sensors_reading_map[12] == 1)
|
if (sensors_reading_map[12] == 1)
|
||||||
@@ -80,7 +80,7 @@ void sensors_init() {
|
|||||||
|
|
||||||
//=========================================================================================================================================
|
//=========================================================================================================================================
|
||||||
//=========================================Модуль измерения уровня в баке==================================================================
|
//=========================================Модуль измерения уровня в баке==================================================================
|
||||||
#ifdef level_enable
|
#ifdef LEVEL_ENABLED
|
||||||
//levelPr p 14 12 Вода#в#баке,#% Датчики fill-gauge 125 20 1
|
//levelPr p 14 12 Вода#в#баке,#% Датчики fill-gauge 125 20 1
|
||||||
void levelPr() {
|
void levelPr() {
|
||||||
String value_name = sCmd.next();
|
String value_name = sCmd.next();
|
||||||
@@ -138,7 +138,7 @@ void ultrasonic_reading() {
|
|||||||
distance_cm = duration_ / 29 / 2;
|
distance_cm = duration_ / 29 / 2;
|
||||||
distance_cm = medianFilter.filtered(distance_cm); //отсечение промахов медианным фильтром
|
distance_cm = medianFilter.filtered(distance_cm); //отсечение промахов медианным фильтром
|
||||||
counter++;
|
counter++;
|
||||||
if (counter > tank_level_times_to_send) {
|
if (counter > TANK_LEVEL_SAMPLES) {
|
||||||
counter = 0;
|
counter = 0;
|
||||||
level = map(distance_cm,
|
level = map(distance_cm,
|
||||||
jsonReadInt(configOptionJson, "e_lev"),
|
jsonReadInt(configOptionJson, "e_lev"),
|
||||||
@@ -158,7 +158,7 @@ void ultrasonic_reading() {
|
|||||||
#endif
|
#endif
|
||||||
//=========================================================================================================================================
|
//=========================================================================================================================================
|
||||||
//=========================================Модуль аналогового сенсора======================================================================
|
//=========================================Модуль аналогового сенсора======================================================================
|
||||||
#ifdef analog_enable
|
#ifdef ANALOG_ENABLED
|
||||||
//analog adc 0 Аналоговый#вход,#% Датчики any-data 1 1023 1 100 1
|
//analog adc 0 Аналоговый#вход,#% Датчики any-data 1 1023 1 100 1
|
||||||
void analog() {
|
void analog() {
|
||||||
String value_name = sCmd.next();
|
String value_name = sCmd.next();
|
||||||
@@ -226,7 +226,7 @@ void analog_reading2() {
|
|||||||
#endif
|
#endif
|
||||||
//=========================================================================================================================================
|
//=========================================================================================================================================
|
||||||
//=========================================Модуль температурного сенсора ds18b20===========================================================
|
//=========================================Модуль температурного сенсора ds18b20===========================================================
|
||||||
#ifdef dallas_enable
|
#ifdef DALLAS_ENABLED
|
||||||
void dallas() {
|
void dallas() {
|
||||||
//String value_name = sCmd.next();
|
//String value_name = sCmd.next();
|
||||||
String pin = sCmd.next();
|
String pin = sCmd.next();
|
||||||
@@ -255,7 +255,7 @@ void dallas_reading() {
|
|||||||
#endif
|
#endif
|
||||||
//=========================================================================================================================================
|
//=========================================================================================================================================
|
||||||
//=========================================Модуль сенсоров DHT=============================================================================
|
//=========================================Модуль сенсоров DHT=============================================================================
|
||||||
#ifdef dht_enable
|
#ifdef DHT_ENABLED
|
||||||
//dhtT t 2 dht11 Температура#DHT,#t°C Датчики any-data 1
|
//dhtT t 2 dht11 Температура#DHT,#t°C Датчики any-data 1
|
||||||
void dhtT() {
|
void dhtT() {
|
||||||
String value_name = sCmd.next();
|
String value_name = sCmd.next();
|
||||||
|
|||||||
@@ -68,10 +68,10 @@ void upgrade_firmware() {
|
|||||||
Serial.println("Restart...");
|
Serial.println("Restart...");
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
} else {
|
} else {
|
||||||
Serial.println("[e] on build");
|
Serial.println("[E] on build");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Serial.println("[e] on upgrade");
|
Serial.println("[E] on upgrade");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,29 @@
|
|||||||
#include "Utils/FileUtils.h"
|
#include "Utils/FileUtils.h"
|
||||||
|
|
||||||
#include <LittleFS.h>
|
|
||||||
|
bool fileSystemInit() {
|
||||||
|
if (!LittleFS.begin()) {
|
||||||
|
Serial.println("[E] LittleFS");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeFile(const String filename) {
|
||||||
|
if (!LittleFS.remove(filename)) {
|
||||||
|
Serial.printf("[E] on remove %s", filename.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
File seekFile(const String filename, size_t position) {
|
||||||
|
auto file = LittleFS.open(filename, "r");
|
||||||
|
if (!file) {
|
||||||
|
Serial.printf("[E] on open %s", filename.c_str());
|
||||||
|
}
|
||||||
|
// поставим курсор в начало файла
|
||||||
|
file.seek(position, SeekSet);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
String readFileString(const String filename, const String to_find) {
|
String readFileString(const String filename, const String to_find) {
|
||||||
String res = "Failed";
|
String res = "Failed";
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ void reconfigTime() {
|
|||||||
if (WiFi.status() == WL_CONNECTED) {
|
if (WiFi.status() == WL_CONNECTED) {
|
||||||
String ntp = jsonReadStr(configSetupJson, "ntp");
|
String ntp = jsonReadStr(configSetupJson, "ntp");
|
||||||
configTime(0, 0, ntp.c_str());
|
configTime(0, 0, ntp.c_str());
|
||||||
int i = 0;
|
Serial.println("[I] Time sync");
|
||||||
Serial.println("[I] Start time sync");
|
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
|
uint8_t i = 0;
|
||||||
struct tm timeinfo;
|
struct tm timeinfo;
|
||||||
while (!getLocalTime(&timeinfo) && i <= 4) {
|
while (!getLocalTime(&timeinfo) && i <= 4) {
|
||||||
Serial.print(".");
|
Serial.print(".");
|
||||||
@@ -33,6 +33,7 @@ void reconfigTime() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
|
//uint8_t i = 0;
|
||||||
//while (!time(nullptr) && i < 4) {
|
//while (!time(nullptr) && i < 4) {
|
||||||
// Serial.print(".");
|
// Serial.print(".");
|
||||||
// i++;
|
// i++;
|
||||||
|
|||||||
12
src/Web.cpp
12
src/Web.cpp
@@ -124,7 +124,7 @@ void web_init() {
|
|||||||
request->send(200, "text/text", "OK");
|
request->send(200, "text/text", "OK");
|
||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
#ifdef logging_enable
|
#ifdef LOGGING_ENABLED
|
||||||
if (request->hasArg("cleanlog")) {
|
if (request->hasArg("cleanlog")) {
|
||||||
clean_log_date();
|
clean_log_date();
|
||||||
request->send(200, "text/text", "OK");
|
request->send(200, "text/text", "OK");
|
||||||
@@ -147,7 +147,7 @@ void web_init() {
|
|||||||
}
|
}
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
if (request->hasArg("updatelist")) {
|
if (request->hasArg("updatelist")) {
|
||||||
LittleFS.remove("/dev.csv");
|
removeFile("/dev.csv");
|
||||||
addFile("dev.csv", "device id;device name;ip address");
|
addFile("dev.csv", "device id;device name;ip address");
|
||||||
request->redirect("/?set.udp");
|
request->redirect("/?set.udp");
|
||||||
}
|
}
|
||||||
@@ -270,7 +270,7 @@ void web_init() {
|
|||||||
request->send(200, "text/text", tmp);
|
request->send(200, "text/text", tmp);
|
||||||
}
|
}
|
||||||
//==============================push settings=============================================
|
//==============================push settings=============================================
|
||||||
#ifdef push_enable
|
#ifdef PUSH_ENABLED
|
||||||
if (request->hasArg("pushingboxid")) {
|
if (request->hasArg("pushingboxid")) {
|
||||||
jsonWriteStr(configSetupJson, "pushingboxid", request->getParam("pushingboxid")->value());
|
jsonWriteStr(configSetupJson, "pushingboxid", request->getParam("pushingboxid")->value());
|
||||||
saveConfig();
|
saveConfig();
|
||||||
@@ -292,10 +292,10 @@ void web_init() {
|
|||||||
int case_of_update;
|
int case_of_update;
|
||||||
|
|
||||||
if (WiFi.status() != WL_CONNECTED) last_version = "nowifi";
|
if (WiFi.status() != WL_CONNECTED) last_version = "nowifi";
|
||||||
if (!mb_4_of_memory) last_version = "less";
|
if (!FLASH_4MB) last_version = "less";
|
||||||
|
|
||||||
if (last_version == firmware_version) case_of_update = 1;
|
if (last_version == FIRMWARE_VERSION) case_of_update = 1;
|
||||||
if (last_version != firmware_version) case_of_update = 2;
|
if (last_version != FIRMWARE_VERSION) case_of_update = 2;
|
||||||
if (last_version == "error") case_of_update = 3;
|
if (last_version == "error") case_of_update = 3;
|
||||||
if (last_version == "") case_of_update = 4;
|
if (last_version == "") case_of_update = 4;
|
||||||
if (last_version == "less") case_of_update = 5;
|
if (last_version == "less") case_of_update = 5;
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
#include "Global.h"
|
#include "Global.h"
|
||||||
|
|
||||||
|
#include "Utils/FileUtils.h"
|
||||||
|
|
||||||
void Web_server_init() {
|
void Web_server_init() {
|
||||||
/*********************************************************************************
|
/*********************************************************************************
|
||||||
***************************************OTA****************************************
|
***************************************OTA****************************************
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
#ifdef OTA_enable
|
#ifdef OTA_UPDATES_ENABLED
|
||||||
ArduinoOTA.onStart([]() {
|
ArduinoOTA.onStart([]() {
|
||||||
events.send("Update Start", "ota");
|
events.send("Update Start", "ota");
|
||||||
});
|
});
|
||||||
@@ -34,7 +36,7 @@ void Web_server_init() {
|
|||||||
/*********************************************************************************
|
/*********************************************************************************
|
||||||
**************************************MDNS****************************************
|
**************************************MDNS****************************************
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
#ifdef MDNS_enable
|
#ifdef MDNS_ENABLED
|
||||||
MDNS.addService("http", "tcp", 80);
|
MDNS.addService("http", "tcp", 80);
|
||||||
#endif
|
#endif
|
||||||
//LittleFS.begin();
|
//LittleFS.begin();
|
||||||
@@ -55,6 +57,7 @@ void Web_server_init() {
|
|||||||
**************************************WEB****************************************
|
**************************************WEB****************************************
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
|
|
||||||
server.addHandler(new SPIFFSEditor(LittleFS, jsonReadStr(configSetupJson, "weblogin").c_str(), jsonReadStr(configSetupJson, "webpass").c_str()));
|
server.addHandler(new SPIFFSEditor(LittleFS, jsonReadStr(configSetupJson, "weblogin").c_str(), jsonReadStr(configSetupJson, "webpass").c_str()));
|
||||||
#elif defined(ESP8266)
|
#elif defined(ESP8266)
|
||||||
server.addHandler(new SPIFFSEditor(jsonReadStr(configSetupJson, "weblogin").c_str(), jsonReadStr(configSetupJson, "webpass").c_str()));
|
server.addHandler(new SPIFFSEditor(jsonReadStr(configSetupJson, "weblogin").c_str(), jsonReadStr(configSetupJson, "webpass").c_str()));
|
||||||
|
|||||||
@@ -63,8 +63,7 @@ bool StartAPMode() {
|
|||||||
WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str());
|
WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str());
|
||||||
IPAddress myIP = WiFi.softAPIP();
|
IPAddress myIP = WiFi.softAPIP();
|
||||||
led_blink("on");
|
led_blink("on");
|
||||||
Serial.print("[I] AP IP: ");
|
Serial.printf("[I] AP IP: %s\n", myIP.toString().c_str());
|
||||||
Serial.println(myIP);
|
|
||||||
jsonWriteStr(configSetupJson, "ip", myIP.toString());
|
jsonWriteStr(configSetupJson, "ip", myIP.toString());
|
||||||
|
|
||||||
//if (jsonReadInt(configOptionJson, "pass_status") != 1) {
|
//if (jsonReadInt(configOptionJson, "pass_status") != 1) {
|
||||||
@@ -89,7 +88,7 @@ boolean RouterFind(String ssid) {
|
|||||||
Serial.printf("[I][WIFI] scan result = %d\n", n);
|
Serial.printf("[I][WIFI] scan result = %d\n", n);
|
||||||
if (n == -2) {
|
if (n == -2) {
|
||||||
// не было запущено, запускаем
|
// не было запущено, запускаем
|
||||||
Serial.println("[I][WIFI] scanning has not been triggered, start scanning");
|
Serial.println("[I][WIFI] start scanning");
|
||||||
// async, show_hidden
|
// async, show_hidden
|
||||||
WiFi.scanNetworks(true, false);
|
WiFi.scanNetworks(true, false);
|
||||||
} else if (n == -1) {
|
} else if (n == -1) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ void createWidget (String widget_name, String page_name, String page_number, St
|
|||||||
jsonWriteStr(widget, "descr", widget_name);
|
jsonWriteStr(widget, "descr", widget_name);
|
||||||
jsonWriteStr(widget, "topic", prex + "/" + topic);
|
jsonWriteStr(widget, "topic", prex + "/" + topic);
|
||||||
|
|
||||||
#ifdef layout_in_ram
|
#ifdef LAYOUT_IN_RAM
|
||||||
all_widgets += widget + "\r\n";
|
all_widgets += widget + "\r\n";
|
||||||
#else
|
#else
|
||||||
addFile("layout.txt", widget);
|
addFile("layout.txt", widget);
|
||||||
@@ -46,7 +46,7 @@ void createWidgetParam (String widget_name, String page_name, String page_numbe
|
|||||||
if (name2 != "") jsonWriteStr(widget, name2, param2);
|
if (name2 != "") jsonWriteStr(widget, name2, param2);
|
||||||
if (name3 != "") jsonWriteStr(widget, name3, param3);
|
if (name3 != "") jsonWriteStr(widget, name3, param3);
|
||||||
|
|
||||||
#ifdef layout_in_ram
|
#ifdef LAYOUT_IN_RAM
|
||||||
all_widgets += widget + "\r\n";
|
all_widgets += widget + "\r\n";
|
||||||
#else
|
#else
|
||||||
addFile("layout.txt", widget);
|
addFile("layout.txt", widget);
|
||||||
@@ -72,7 +72,7 @@ void createChart (String widget_name, String page_name, String page_number, Str
|
|||||||
jsonWriteStr(widget, "maxCount", maxCount);
|
jsonWriteStr(widget, "maxCount", maxCount);
|
||||||
jsonWriteStr(widget, "topic", prex + "/" + topic);
|
jsonWriteStr(widget, "topic", prex + "/" + topic);
|
||||||
|
|
||||||
#ifdef layout_in_ram
|
#ifdef LAYOUT_IN_RAM
|
||||||
all_widgets += widget + "\r\n";
|
all_widgets += widget + "\r\n";
|
||||||
#else
|
#else
|
||||||
addFile("layout.txt", widget);
|
addFile("layout.txt", widget);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ void setup() {
|
|||||||
|
|
||||||
setChipId();
|
setChipId();
|
||||||
|
|
||||||
File_system_init();
|
fileSystemInit();
|
||||||
Serial.println("[V] LittleFS");
|
Serial.println("[V] LittleFS");
|
||||||
|
|
||||||
CMD_init();
|
CMD_init();
|
||||||
@@ -40,14 +40,14 @@ void setup() {
|
|||||||
Time_Init();
|
Time_Init();
|
||||||
Serial.println("[V] Time_Init");
|
Serial.println("[V] Time_Init");
|
||||||
|
|
||||||
#ifdef UDP_enable
|
#ifdef UDP_ENABLED
|
||||||
UDP_init();
|
UDP_init();
|
||||||
Serial.println("[V] UDP_init");
|
Serial.println("[V] UDP_init");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ts.add(
|
ts.add(
|
||||||
TEST, 10000, [&](void*) {
|
TEST, 10000, [&](void*) {
|
||||||
getMemoryLoad("[I] sysinfo ");
|
printMemoryStatus("[I] sysinfo ");
|
||||||
},
|
},
|
||||||
nullptr, true);
|
nullptr, true);
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ void setup() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void loop() {
|
void loop() {
|
||||||
#ifdef OTA_enable
|
#ifdef OTA_UPDATES_ENABLED
|
||||||
ArduinoOTA.handle();
|
ArduinoOTA.handle();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ void loop() {
|
|||||||
handleCMD_loop();
|
handleCMD_loop();
|
||||||
handleButton();
|
handleButton();
|
||||||
handleScenario();
|
handleScenario();
|
||||||
#ifdef UDP_enable
|
#ifdef UDP_ENABLED
|
||||||
handleUdp();
|
handleUdp();
|
||||||
#endif
|
#endif
|
||||||
ts.update();
|
ts.update();
|
||||||
@@ -79,7 +79,7 @@ void not_async_actions() {
|
|||||||
do_mqtt_connection();
|
do_mqtt_connection();
|
||||||
do_upgrade_url();
|
do_upgrade_url();
|
||||||
do_upgrade();
|
do_upgrade();
|
||||||
#ifdef UDP_enable
|
#ifdef UDP_ENABLED
|
||||||
do_udp_data_parse();
|
do_udp_data_parse();
|
||||||
do_mqtt_send_settings_to_udp();
|
do_mqtt_send_settings_to_udp();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
21
src/main.cpp
21
src/main.cpp
@@ -50,17 +50,17 @@ void sendCONFIG(String topik, String widgetConfig, String key, String date) {
|
|||||||
void led_blink(String satus) {
|
void led_blink(String satus) {
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#ifdef blink_pin
|
#ifdef blink_pin
|
||||||
pinMode(blink_pin, OUTPUT);
|
pinMode(LED_PIN, OUTPUT);
|
||||||
if (satus == "off") {
|
if (satus == "off") {
|
||||||
noTone(blink_pin);
|
noTone(LED_PIN);
|
||||||
digitalWrite(blink_pin, HIGH);
|
digitalWrite(LED_PIN, HIGH);
|
||||||
}
|
}
|
||||||
if (satus == "on") {
|
if (satus == "on") {
|
||||||
noTone(blink_pin);
|
noTone(LED_PIN);
|
||||||
digitalWrite(blink_pin, LOW);
|
digitalWrite(LED_PIN, LOW);
|
||||||
}
|
}
|
||||||
if (satus == "slow") tone(blink_pin, 1);
|
if (satus == "slow") tone(LED_PIN, 1);
|
||||||
if (satus == "fast") tone(blink_pin, 20);
|
if (satus == "fast") tone(LED_PIN, 20);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -68,7 +68,10 @@ void led_blink(String satus) {
|
|||||||
const String getChipId() {
|
const String getChipId() {
|
||||||
String res;
|
String res;
|
||||||
#ifdef ESP32
|
#ifdef ESP32
|
||||||
res = String(ESP.getEfuseMac());
|
char buf[32] = {0};
|
||||||
|
uint32_t mac = ESP.getEfuseMac();
|
||||||
|
sprintf(buf, "%0X", mac);
|
||||||
|
res = String(buf);
|
||||||
#endif
|
#endif
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
res = String(ESP.getChipId()) + "-" + String(ESP.getFlashChipId());
|
res = String(ESP.getChipId()) + "-" + String(ESP.getFlashChipId());
|
||||||
@@ -81,7 +84,7 @@ void setChipId() {
|
|||||||
Serial.println(chipId);
|
Serial.println(chipId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void getMemoryLoad(String text) {
|
void printMemoryStatus(String text) {
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
uint32_t all_memory = 52864;
|
uint32_t all_memory = 52864;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,9 +18,9 @@ unsigned int udp_port = 4210;
|
|||||||
void handleUdp_esp32();
|
void handleUdp_esp32();
|
||||||
void add_dev_in_list(String fileName, String id, String dev_name, String ip);
|
void add_dev_in_list(String fileName, String id, String dev_name, String ip);
|
||||||
|
|
||||||
#ifdef UDP_enable
|
#ifdef UDP_ENABLED
|
||||||
void UDP_init() {
|
void UDP_init() {
|
||||||
LittleFS.remove("/dev.csv");
|
removeFile("/dev.csv");
|
||||||
addFile("dev.csv", "device id;device name;ip address");
|
addFile("dev.csv", "device id;device name;ip address");
|
||||||
|
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
@@ -123,8 +123,8 @@ void do_udp_data_parse() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void add_dev_in_list(String filename, String id, String dev_name, String ip) {
|
void add_dev_in_list(String filename, String id, String dev_name, String ip) {
|
||||||
File configFile = LittleFS.open("/" + filename, "r");
|
auto file = seekFile("/" + filename);
|
||||||
if (!configFile.find(id.c_str())) {
|
if (!file.find(id.c_str())) {
|
||||||
addFile(filename, id + ";" + dev_name + "; <a href=\"http://" + ip + "\" target=\"_blank\"\">" + ip + "</a>");
|
addFile(filename, id + ";" + dev_name + "; <a href=\"http://" + ip + "\" target=\"_blank\"\">" + ip + "</a>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user