diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..a835519e4 --- /dev/null +++ b/.clang-format @@ -0,0 +1,29 @@ +Language: Cpp +BasedOnStyle: LLVM +AlignAfterOpenBracket: BlockIndent +AlignArrayOfStructures: Left +AlignConsecutiveAssignments: true +AlignConsecutiveMacros: AcrossComments +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: false +AllowShortBlocksOnASingleLine: Empty +AllowShortFunctionsOnASingleLine: Empty +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BreakBeforeTernaryOperators: true +ColumnLimit: 120 +ContinuationIndentWidth: 4 +EmptyLineBeforeAccessModifier: Always +FixNamespaceComments: true +IndentAccessModifiers: false +IndentCaseLabels: true +IndentWidth: 4 +LambdaBodyIndentation: Signature +MaxEmptyLinesToKeep: 1 +# PointerAlignment: Left # TODO enable this and reformat project +QualifierAlignment: Left +ReflowComments: true +SeparateDefinitionBlocks: Always +TabWidth: 4 +UseTab: Always diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ba7d83269..abbf440fd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -6,7 +6,6 @@ jobs: lint-clang-format: name: Lint with clang-format runs-on: ubuntu-latest - if: ${{ false }} # disable for now steps: - name: Checkout uses: actions/checkout@v2 diff --git a/arduino/libretuya/api/Flash.h b/arduino/libretuya/api/Flash.h index 0b0094965..7aaecbb2b 100644 --- a/arduino/libretuya/api/Flash.h +++ b/arduino/libretuya/api/Flash.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */ + #pragma once #include diff --git a/arduino/libretuya/api/LibreTuyaAPI.cpp b/arduino/libretuya/api/LibreTuyaAPI.cpp index 1be6967f1..9a2525aa9 100644 --- a/arduino/libretuya/api/LibreTuyaAPI.cpp +++ b/arduino/libretuya/api/LibreTuyaAPI.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-29. */ + #include "LibreTuyaAPI.h" __weak char *strdup(const char *s) { diff --git a/arduino/libretuya/api/LibreTuyaAPI.h b/arduino/libretuya/api/LibreTuyaAPI.h index 11f6c997b..ab166b9b5 100644 --- a/arduino/libretuya/api/LibreTuyaAPI.h +++ b/arduino/libretuya/api/LibreTuyaAPI.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-28. */ + #pragma once // LibreTuya version macros diff --git a/arduino/libretuya/api/LibreTuyaConfig.h b/arduino/libretuya/api/LibreTuyaConfig.h index a606ae522..8bb7e4323 100644 --- a/arduino/libretuya/api/LibreTuyaConfig.h +++ b/arduino/libretuya/api/LibreTuyaConfig.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-28. */ + #pragma once // see docs/API Configuration diff --git a/arduino/libretuya/api/lt_logger.c b/arduino/libretuya/api/lt_logger.c index e0a25fa18..edae7bd2b 100644 --- a/arduino/libretuya/api/lt_logger.c +++ b/arduino/libretuya/api/lt_logger.c @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-28. */ + #include "lt_logger.h" #include diff --git a/arduino/libretuya/api/lt_logger.h b/arduino/libretuya/api/lt_logger.h index 65a3df304..2f5c03df6 100644 --- a/arduino/libretuya/api/lt_logger.h +++ b/arduino/libretuya/api/lt_logger.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-28. */ + #pragma once #include "LibreTuyaConfig.h" diff --git a/arduino/libretuya/common/WMath.cpp b/arduino/libretuya/common/WMath.cpp new file mode 100644 index 000000000..8bfd2b97e --- /dev/null +++ b/arduino/libretuya/common/WMath.cpp @@ -0,0 +1,55 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +void randomSeed(uint32_t dwSeed) { + if (dwSeed != 0) { + srand(dwSeed); + } +} + +long random(long howbig) { + if (howbig == 0) { + return 0; + } + + return rand() % howbig; +} + +long random(long howsmall, long howbig) { + if (howsmall >= howbig) { + return howsmall; + } + + long diff = howbig - howsmall; + + return random(diff) + howsmall; +} + +extern long map(long x, long in_min, long in_max, long out_min, long out_max) { + return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; +} + +extern uint16_t makeWord(uint16_t w) { + return w; +} + +extern uint16_t makeWord(uint8_t h, uint8_t l) { + return (h << 8) | l; +} diff --git a/arduino/realtek-ambz/cores/arduino/Reset.h b/arduino/libretuya/common/abi.cpp similarity index 59% rename from arduino/realtek-ambz/cores/arduino/Reset.h rename to arduino/libretuya/common/abi.cpp index 373f6d174..b1b8e68ad 100644 --- a/arduino/realtek-ambz/cores/arduino/Reset.h +++ b/arduino/libretuya/common/abi.cpp @@ -1,5 +1,5 @@ /* - Copyright (c) 2012 Arduino. All right reserved. + Copyright (c) 2014 Arduino LLC. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -16,19 +16,21 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef RESET_H -#define RESET_H +#include -#ifdef __cplusplus -extern "C" { -#endif +extern "C" void __cxa_pure_virtual(void) __attribute__((__noreturn__)); +extern "C" void __cxa_deleted_virtual(void) __attribute__((__noreturn__)); -void initiateReset(int ms); -void tickReset(); -void cancelReset(); - -#ifdef __cplusplus +void __cxa_pure_virtual(void) { + // We might want to write some diagnostics to uart in this case + // std::terminate(); + while (1) + ; } -#endif -#endif +void __cxa_deleted_virtual(void) { + // We might want to write some diagnostics to uart in this case + // std::terminate(); + while (1) + ; +} diff --git a/arduino/realtek-ambz/cores/arduino/avr/dtostrf.c b/arduino/libretuya/common/dtostrf.c similarity index 79% rename from arduino/realtek-ambz/cores/arduino/avr/dtostrf.c rename to arduino/libretuya/common/dtostrf.c index d4c41f87f..7f64023fa 100644 --- a/arduino/realtek-ambz/cores/arduino/avr/dtostrf.c +++ b/arduino/libretuya/common/dtostrf.c @@ -18,16 +18,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifdef ARDUINO_AMEBA #include -#else -#include -#endif -char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { - char fmt[20]; - sprintf(fmt, "%%%d.%df", width, prec); - sprintf(sout, fmt, val); - return sout; +char *dtostrf(double val, signed char width, unsigned char prec, char *sout) { + char fmt[20]; + sprintf(fmt, "%%%d.%df", width, prec); + sprintf(sout, fmt, val); + return sout; } - diff --git a/arduino/realtek-ambz/cores/arduino/hooks.c b/arduino/libretuya/common/hooks.c similarity index 81% rename from arduino/realtek-ambz/cores/arduino/hooks.c rename to arduino/libretuya/common/hooks.c index a8c207f30..3f9b0a92c 100644 --- a/arduino/realtek-ambz/cores/arduino/hooks.c +++ b/arduino/libretuya/common/hooks.c @@ -1,5 +1,5 @@ /* - Copyright (c) 2012 Arduino. All right reserved. + Copyright (c) 2015 Arduino LLC. All right reserved. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -29,12 +29,7 @@ static void __empty() { // Empty } -#include "cmsis_os.h" - -void yield(void) { - vTaskDelay(1); - taskYIELD(); -} +void yield(void) __attribute__((weak, alias("__empty"))); /** * SysTick hook @@ -46,7 +41,8 @@ static int __false() { // Return false return 0; } -int sysTickHook(void) __attribute__ ((weak, alias("__false"))); + +int sysTickHook(void) __attribute__((weak, alias("__false"))); /** * SVC hook @@ -60,5 +56,6 @@ static void __halt() { while (1) ; } -void svcHook(void) __attribute__ ((weak, alias("__halt"))); -void pendSVHook(void) __attribute__ ((weak, alias("__halt"))); + +void svcHook(void) __attribute__((weak, alias("__halt"))); +void pendSVHook(void) __attribute__((weak, alias("__halt"))); diff --git a/arduino/libretuya/common/itoa.c b/arduino/libretuya/common/itoa.c new file mode 100644 index 000000000..0493f8b0a --- /dev/null +++ b/arduino/libretuya/common/itoa.c @@ -0,0 +1,111 @@ +/* + Copyright (c) 2014 Arduino LLC. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +char *ltoa(long value, char *string, int radix) { + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v; + int sign; + char *sp; + + if (string == NULL) { + return 0; + } + + if (radix > 36 || radix <= 1) { + return 0; + } + + sign = (radix == 10 && value < 0); + if (sign) { + v = -value; + } else { + v = (unsigned long)value; + } + + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i + '0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + if (sign) + *sp++ = '-'; + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} + +char *ultoa(unsigned long value, char *string, int radix) { + char tmp[33]; + char *tp = tmp; + long i; + unsigned long v = value; + char *sp; + + if (string == NULL) { + return 0; + } + + if (radix > 36 || radix <= 1) { + return 0; + } + + while (v || tp == tmp) { + i = v % radix; + v = v / radix; + if (i < 10) + *tp++ = i + '0'; + else + *tp++ = i + 'a' - 10; + } + + sp = string; + + while (tp > tmp) + *sp++ = *--tp; + *sp = 0; + + return string; +} + +char *itoa(int value, char *string, int radix) { + return ltoa(value, string, radix); +} + +char *utoa(unsigned int value, char *string, int radix) { + return ultoa(value, string, radix); +} + +#ifdef __cplusplus +} // extern "C" +#endif diff --git a/arduino/libretuya/common/wiring_shift.c b/arduino/libretuya/common/wiring_shift.c new file mode 100644 index 000000000..d215d682d --- /dev/null +++ b/arduino/libretuya/common/wiring_shift.c @@ -0,0 +1,54 @@ +/* + Copyright (c) 2014 Arduino. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include + +uint8_t shiftIn(pin_size_t ulDataPin, pin_size_t ulClockPin, BitOrder ulBitOrder) { + uint8_t value = 0; + uint8_t i; + + for (i = 0; i < 8; ++i) { + digitalWrite(ulClockPin, HIGH); + + if (ulBitOrder == LSBFIRST) { + value |= digitalRead(ulDataPin) << i; + } else { + value |= digitalRead(ulDataPin) << (7 - i); + } + + digitalWrite(ulClockPin, LOW); + } + + return value; +} + +void shiftOut(pin_size_t ulDataPin, pin_size_t ulClockPin, BitOrder ulBitOrder, uint8_t ulVal) { + uint8_t i; + + for (i = 0; i < 8; i++) { + if (ulBitOrder == LSBFIRST) { + digitalWrite(ulDataPin, !!(ulVal & (1 << i))); + } else { + digitalWrite(ulDataPin, !!(ulVal & (1 << (7 - i)))); + } + + digitalWrite(ulClockPin, HIGH); + digitalWrite(ulClockPin, LOW); + } +} diff --git a/arduino/libretuya/compat/FS.h b/arduino/libretuya/compat/FS.h index deb849bb7..4751126b0 100644 --- a/arduino/libretuya/compat/FS.h +++ b/arduino/libretuya/compat/FS.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-30. */ + #pragma once #include diff --git a/arduino/libretuya/compat/FSImpl.h b/arduino/libretuya/compat/FSImpl.h index 6f037f8a9..fc53bc352 100644 --- a/arduino/libretuya/compat/FSImpl.h +++ b/arduino/libretuya/compat/FSImpl.h @@ -1 +1,3 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-30. */ + // nop diff --git a/arduino/libretuya/compat/WiFiAP.h b/arduino/libretuya/compat/WiFiAP.h index 42faf3d87..7ecef0bd9 100644 --- a/arduino/libretuya/compat/WiFiAP.h +++ b/arduino/libretuya/compat/WiFiAP.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-26. */ + #pragma once // ESP32 WiFi examples use WiFiAP.h include diff --git a/arduino/libretuya/compat/pgmspace.h b/arduino/libretuya/compat/pgmspace.h index 818039072..503ccd4ee 100644 --- a/arduino/libretuya/compat/pgmspace.h +++ b/arduino/libretuya/compat/pgmspace.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-30. */ + #pragma once #include diff --git a/arduino/libretuya/compat/vfs_api.h b/arduino/libretuya/compat/vfs_api.h index 6f037f8a9..fc53bc352 100644 --- a/arduino/libretuya/compat/vfs_api.h +++ b/arduino/libretuya/compat/vfs_api.h @@ -1 +1,3 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-30. */ + // nop diff --git a/arduino/libretuya/libraries/HTTPClient/strptime.h b/arduino/libretuya/libraries/HTTPClient/strptime.h index 7ef19f49b..62b9b56b2 100644 --- a/arduino/libretuya/libraries/HTTPClient/strptime.h +++ b/arduino/libretuya/libraries/HTTPClient/strptime.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-29. */ + #pragma once #include diff --git a/arduino/libretuya/libraries/HTTPClient/strptime/.clang-format b/arduino/libretuya/libraries/HTTPClient/strptime/.clang-format new file mode 100644 index 000000000..47a38a93f --- /dev/null +++ b/arduino/libretuya/libraries/HTTPClient/strptime/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: Never diff --git a/arduino/libretuya/libraries/HTTPClient/strptime.c b/arduino/libretuya/libraries/HTTPClient/strptime/strptime.c similarity index 100% rename from arduino/libretuya/libraries/HTTPClient/strptime.c rename to arduino/libretuya/libraries/HTTPClient/strptime/strptime.c diff --git a/arduino/libretuya/libraries/NetUtils/IPv6Address.cpp b/arduino/libretuya/libraries/NetUtils/IPv6Address.cpp index 0c11a7bc9..af948393f 100644 --- a/arduino/libretuya/libraries/NetUtils/IPv6Address.cpp +++ b/arduino/libretuya/libraries/NetUtils/IPv6Address.cpp @@ -17,75 +17,82 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "IPv6Address.h" + #include #include -#include "IPv6Address.h" - -IPv6Address::IPv6Address() -{ - memset(_address.bytes, 0, sizeof(_address.bytes)); +IPv6Address::IPv6Address() { + memset(_address.bytes, 0, sizeof(_address.bytes)); } -IPv6Address::IPv6Address(const uint8_t *address) -{ - memcpy(_address.bytes, address, sizeof(_address.bytes)); +IPv6Address::IPv6Address(const uint8_t *address) { + memcpy(_address.bytes, address, sizeof(_address.bytes)); } -IPv6Address::IPv6Address(const uint32_t *address) -{ - memcpy(_address.bytes, (const uint8_t *)address, sizeof(_address.bytes)); +IPv6Address::IPv6Address(const uint32_t *address) { + memcpy(_address.bytes, (const uint8_t *)address, sizeof(_address.bytes)); } -IPv6Address& IPv6Address::operator=(const uint8_t *address) -{ - memcpy(_address.bytes, address, sizeof(_address.bytes)); - return *this; +IPv6Address &IPv6Address::operator=(const uint8_t *address) { + memcpy(_address.bytes, address, sizeof(_address.bytes)); + return *this; } -bool IPv6Address::operator==(const uint8_t* addr) const -{ - return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; +bool IPv6Address::operator==(const uint8_t *addr) const { + return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0; } -size_t IPv6Address::printTo(Print& p) const -{ - /* size_t n = 0; - for(int i = 0; i < 16; i+=2) { - if(i){ - n += p.print(':'); - } - n += p.printf("%02x", _address.bytes[i]); - n += p.printf("%02x", _address.bytes[i+1]); +size_t IPv6Address::printTo(Print &p) const { + /* size_t n = 0; + for(int i = 0; i < 16; i+=2) { + if(i){ + n += p.print(':'); + } + n += p.printf("%02x", _address.bytes[i]); + n += p.printf("%02x", _address.bytes[i+1]); - } - return n; */ + } + return n; */ } -String IPv6Address::toString() const -{ - char szRet[40]; - sprintf(szRet,"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", - _address.bytes[0], _address.bytes[1], _address.bytes[2], _address.bytes[3], - _address.bytes[4], _address.bytes[5], _address.bytes[6], _address.bytes[7], - _address.bytes[8], _address.bytes[9], _address.bytes[10], _address.bytes[11], - _address.bytes[12], _address.bytes[13], _address.bytes[14], _address.bytes[15]); - return String(szRet); +String IPv6Address::toString() const { + char szRet[40]; + sprintf( + szRet, + "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x", + _address.bytes[0], + _address.bytes[1], + _address.bytes[2], + _address.bytes[3], + _address.bytes[4], + _address.bytes[5], + _address.bytes[6], + _address.bytes[7], + _address.bytes[8], + _address.bytes[9], + _address.bytes[10], + _address.bytes[11], + _address.bytes[12], + _address.bytes[13], + _address.bytes[14], + _address.bytes[15] + ); + return String(szRet); } -bool IPv6Address::fromString(const char *address) -{ - //format 0011:2233:4455:6677:8899:aabb:ccdd:eeff - if(strlen(address) != 39){ - return false; - } - char * pos = (char *)address; - size_t i = 0; - for(i = 0; i < 16; i+=2) { - if(!sscanf(pos, "%2hhx", &_address.bytes[i]) || !sscanf(pos+2, "%2hhx", &_address.bytes[i+1])){ - return false; - } - pos += 5; - } - return true; +bool IPv6Address::fromString(const char *address) { + // format 0011:2233:4455:6677:8899:aabb:ccdd:eeff + if (strlen(address) != 39) { + return false; + } + char *pos = (char *)address; + size_t i = 0; + for (i = 0; i < 16; i += 2) { + if (!sscanf(pos, "%2hhx", &_address.bytes[i]) || !sscanf(pos + 2, "%2hhx", &_address.bytes[i + 1])) { + return false; + } + pos += 5; + } + return true; } diff --git a/arduino/libretuya/libraries/NetUtils/IPv6Address.h b/arduino/libretuya/libraries/NetUtils/IPv6Address.h index a26df7959..6d5c40068 100644 --- a/arduino/libretuya/libraries/NetUtils/IPv6Address.h +++ b/arduino/libretuya/libraries/NetUtils/IPv6Address.h @@ -19,80 +19,79 @@ #pragma once -#include -#include #include +#include +#include // A class to make it easier to handle and pass around IP addresses namespace arduino { -class IPv6Address: public Printable -{ -private: - union { - uint8_t bytes[16]; // IPv4 address - uint32_t dword[4]; - } _address; - - // Access the raw byte array containing the address. Because this returns a pointer - // to the internal structure rather than a copy of the address this function should only - // be used when you know that the usage of the returned uint8_t* will be transient and not - // stored. - uint8_t* raw_address() - { - return _address.bytes; - } - -public: - // Constructors - IPv6Address(); - IPv6Address(const uint8_t *address); - IPv6Address(const uint32_t *address); - virtual ~IPv6Address() {} - - bool fromString(const char *address); - bool fromString(const String &address) { return fromString(address.c_str()); } - - operator const uint8_t*() const - { - return _address.bytes; - } - operator const uint32_t*() const - { - return _address.dword; - } - bool operator==(const IPv6Address& addr) const - { - return (_address.dword[0] == addr._address.dword[0]) - && (_address.dword[1] == addr._address.dword[1]) - && (_address.dword[2] == addr._address.dword[2]) - && (_address.dword[3] == addr._address.dword[3]); - } - bool operator==(const uint8_t* addr) const; - - // Overloaded index operator to allow getting and setting individual octets of the address - uint8_t operator[](int index) const - { - return _address.bytes[index]; - } - uint8_t& operator[](int index) - { - return _address.bytes[index]; - } - - // Overloaded copy operators to allow initialisation of IPv6Address objects from other types - IPv6Address& operator=(const uint8_t *address); - - // TODO implement printTo() - virtual size_t printTo(Print& p) const; - String toString() const; - - friend class UDP; - friend class Client; - friend class Server; +class IPv6Address : public Printable { + private: + union { + uint8_t bytes[16]; // IPv4 address + uint32_t dword[4]; + } _address; + + // Access the raw byte array containing the address. Because this returns a pointer + // to the internal structure rather than a copy of the address this function should only + // be used when you know that the usage of the returned uint8_t* will be transient and not + // stored. + uint8_t *raw_address() { + return _address.bytes; + } + + public: + // Constructors + IPv6Address(); + IPv6Address(const uint8_t *address); + IPv6Address(const uint32_t *address); + + virtual ~IPv6Address() {} + + bool fromString(const char *address); + + bool fromString(const String &address) { + return fromString(address.c_str()); + } + + operator const uint8_t *() const { + return _address.bytes; + } + + operator const uint32_t *() const { + return _address.dword; + } + + bool operator==(const IPv6Address &addr) const { + return (_address.dword[0] == addr._address.dword[0]) && (_address.dword[1] == addr._address.dword[1]) && + (_address.dword[2] == addr._address.dword[2]) && (_address.dword[3] == addr._address.dword[3]); + } + + bool operator==(const uint8_t *addr) const; + + // Overloaded index operator to allow getting and setting individual octets of the address + uint8_t operator[](int index) const { + return _address.bytes[index]; + } + + uint8_t &operator[](int index) { + return _address.bytes[index]; + } + + // Overloaded copy operators to allow initialisation of IPv6Address objects from other types + IPv6Address &operator=(const uint8_t *address); + + // TODO implement printTo() + virtual size_t printTo(Print &p) const; + String toString() const; + + friend class UDP; + friend class Client; + friend class Server; }; -} +} // namespace arduino using arduino::IPv6Address; diff --git a/arduino/libretuya/libraries/NetUtils/LwIPRxBuffer.cpp b/arduino/libretuya/libraries/NetUtils/LwIPRxBuffer.cpp index d9207f1b1..2b0c1a31c 100644 --- a/arduino/libretuya/libraries/NetUtils/LwIPRxBuffer.cpp +++ b/arduino/libretuya/libraries/NetUtils/LwIPRxBuffer.cpp @@ -19,7 +19,7 @@ size_t LwIPRxBuffer::r_available() { return 0; } uint16_t count = 0; - int res = lwip_ioctl(_sock, FIONREAD, &count); + int res = lwip_ioctl(_sock, FIONREAD, &count); if (res < 0) { _failed = true; return 0; diff --git a/arduino/libretuya/libraries/NetUtils/api/IPv6Address.h b/arduino/libretuya/libraries/NetUtils/api/IPv6Address.h index b7aa4588d..d41722f44 100644 --- a/arduino/libretuya/libraries/NetUtils/api/IPv6Address.h +++ b/arduino/libretuya/libraries/NetUtils/api/IPv6Address.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-30. */ + #pragma once #include "../IPv6Address.h" diff --git a/arduino/libretuya/libraries/base64/.clang-format b/arduino/libretuya/libraries/base64/.clang-format new file mode 100644 index 000000000..47a38a93f --- /dev/null +++ b/arduino/libretuya/libraries/base64/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: Never diff --git a/arduino/realtek-ambz/cores/arduino/Arduino.h b/arduino/realtek-ambz/cores/arduino/Arduino.h index 24efee26c..07ff75bf4 100644 --- a/arduino/realtek-ambz/cores/arduino/Arduino.h +++ b/arduino/realtek-ambz/cores/arduino/Arduino.h @@ -1,58 +1,29 @@ -/* - Arduino.h - Main include file for the Arduino SDK - Copyright (c) 2005-2013 Arduino Team. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ +/* Copyright (c) Kuba Szczodrzyński 2022-04-23. */ #pragma once #ifdef __cplusplus #include "WCharacterFixup.h" #endif + #define PinMode PinModeArduino // this conflicts with SDK enum #include #include #undef PinMode #ifdef __cplusplus -extern "C" { -#endif // __cplusplus - +extern "C" uint32_t SystemCoreClock; +#else extern uint32_t SystemCoreClock; +#endif +#define clockCyclesPerMicrosecond() (SystemCoreClock / 1000000L) +#define clockCyclesToMicroseconds(a) (((a)*1000L) / (SystemCoreClock / 1000L)) +#define microsecondsToClockCycles(a) ((a) * (SystemCoreClock / 1000000L)) -#define clockCyclesPerMicrosecond() ( SystemCoreClock / 1000000L ) -#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (SystemCoreClock / 1000L) ) -#define microsecondsToClockCycles(a) ( (a) * (SystemCoreClock / 1000000L) ) +#define interrupts() vPortClearInterruptMask(0) +#define noInterrupts() ulPortSetInterruptMask() +// Include platform-specific code #include "WVariant.h" - -#ifdef __cplusplus -} // extern "C" -#endif - // Include board variant #include "variant.h" - -#define interrupts() vPortClearInterruptMask(0) -#define noInterrupts() ulPortSetInterruptMask() - -/* - * \brief SAM3 products have only one reference for ADC - */ -typedef enum _eAnalogReference -{ - AR_DEFAULT, -} eAnalogReference ; diff --git a/arduino/realtek-ambz/cores/arduino/CountingStream.h b/arduino/realtek-ambz/cores/arduino/CountingStream.h deleted file mode 100644 index 89a091d87..000000000 --- a/arduino/realtek-ambz/cores/arduino/CountingStream.h +++ /dev/null @@ -1,7 +0,0 @@ -#include - -class CountingStream : public Print -{ - virtual size_t write(uint8_t) { return 1; }; - virtual size_t write(const uint8_t *buffer, size_t size) { return size; }; -}; diff --git a/arduino/realtek-ambz/cores/arduino/FunctionPointer.h b/arduino/realtek-ambz/cores/arduino/FunctionPointer.h deleted file mode 100644 index 8d422175f..000000000 --- a/arduino/realtek-ambz/cores/arduino/FunctionPointer.h +++ /dev/null @@ -1,198 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2015 ARM Limited - * - * 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 MBED_FUNCTIONPOINTER_H -#define MBED_FUNCTIONPOINTER_H - -#include -#include - - -/* If we had variaditic templates, this wouldn't be a problem, but until C++11 is enabled, we are stuck with multiple classes... */ - -/** A class for storing and calling a pointer to a static or member function - */ -template -class FunctionPointerArg1{ -public: - /** Create a FunctionPointer, attaching a static function - * - * @param function The static function to attach (default is none) - */ - FunctionPointerArg1(R (*function)(A1) = 0) { - attach(function); - } - - /** Create a FunctionPointer, attaching a member function - * - * @param object The object pointer to invoke the member function on (i.e. the this pointer) - * @param function The address of the member function to attach - */ - template - FunctionPointerArg1(T *object, R (T::*member)(A1)) { - attach(object, member); - } - - /** Attach a static function - * - * @param function The static function to attach (default is none) - */ - void attach(R (*function)(A1)) { - _p.function = function; - _membercaller = 0; - } - - /** Attach a member function - * - * @param object The object pointer to invoke the member function on (i.e. the this pointer) - * @param function The address of the member function to attach - */ - template - void attach(T *object, R (T::*member)(A1)) { - _p.object = static_cast(object); - *reinterpret_cast(_member) = member; - _membercaller = &FunctionPointerArg1::membercaller; - } - - /** Call the attached static or member function - */ - R call(A1 a) { - if (_membercaller == 0 && _p.function) { - return _p.function(a); - } else if (_membercaller && _p.object) { - return _membercaller(_p.object, _member, a); - } - return (R)0; - } - - /** Get registered static function - */ - R(*get_function(A1))() { - return _membercaller ? (R(*)(A1))0 : (R(*)(A1))_p.function; - } - - R operator ()(A1 a) { - return call(a); - } - operator bool(void) const { - return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL; - } - -private: - template - static R membercaller(void *object, uintptr_t *member, A1 a) { - T* o = static_cast(object); - R (T::**m)(A1) = reinterpret_cast(member); - return (o->**m)(a); - } - - union { - R (*function)(A1); // static function pointer - void *object; // object this pointer - } _p; - uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller - R (*_membercaller)(void*, uintptr_t*, A1); // registered membercaller function to convert back and call _m.member on _object -}; - -/** A class for storing and calling a pointer to a static or member function (R ()(void)) - */ -template -class FunctionPointerArg1{ -public: - /** Create a FunctionPointer, attaching a static function - * - * @param function The static function to attach (default is none) - */ - FunctionPointerArg1(R (*function)(void) = 0) { - attach(function); - } - - /** Create a FunctionPointer, attaching a member function - * - * @param object The object pointer to invoke the member function on (i.e. the this pointer) - * @param function The address of the void member function to attach - */ - template - FunctionPointerArg1(T *object, R (T::*member)(void)) { - attach(object, member); - } - - /** Attach a static function - * - * @param function The void static function to attach (default is none) - */ - void attach(R (*function)(void)) { - _p.function = function; - _membercaller = 0; - } - - /** Attach a member function - * - * @param object The object pointer to invoke the member function on (i.e. the this pointer) - * @param function The address of the void member function to attach - */ - template - void attach(T *object, R (T::*member)(void)) { - _p.object = static_cast(object); - *reinterpret_cast(_member) = member; - _membercaller = &FunctionPointerArg1::membercaller; - } - - /** Call the attached static or member function - */ - R call(){ - if (_membercaller == 0 && _p.function) { - return _p.function(); - } else if (_membercaller && _p.object) { - return _membercaller(_p.object, _member); - } - return (R)0; - } - - /** Get registered static function - */ - R(*get_function())() { - return _membercaller ? (R(*)())0 : (R(*)())_p.function; - } - - R operator ()(void) { - return call(); - } - operator bool(void) const { - return (_membercaller != NULL ? _p.object : (void*)_p.function) != NULL; - } - -private: - template - static R membercaller(void *object, uintptr_t *member) { - T* o = static_cast(object); - R (T::**m)(void) = reinterpret_cast(member); - return (o->**m)(); - } - - union { - R (*function)(void); // static function pointer - void *object; // object this pointer - } _p; - uintptr_t _member[4]; // aligned raw member function pointer storage - converted back by registered _membercaller - R (*_membercaller)(void*, uintptr_t*); // registered membercaller function to convert back and call _m.member on _object -}; - -typedef FunctionPointerArg1 FunctionPointer; -typedef FunctionPointerArg1 event_callback_t; - - -#endif - diff --git a/arduino/realtek-ambz/cores/arduino/LOGUARTClass.cpp b/arduino/realtek-ambz/cores/arduino/LOGUARTClass.cpp index 6b337e8eb..671ce0e42 100644 --- a/arduino/realtek-ambz/cores/arduino/LOGUARTClass.cpp +++ b/arduino/realtek-ambz/cores/arduino/LOGUARTClass.cpp @@ -16,117 +16,83 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "Arduino.h" - #include "LOGUARTClass.h" -#define LOG_UART_MODIFIABLE_BAUD_RATE 1 - -#ifdef __cplusplus -extern "C" { -#endif +#include -#include "osdep_service.h" -#include "rtl8710b.h" -extern int LOGUART_SetBaud(uint32_t BaudRate); // from fixups/log_uart.c - -#ifdef __cplusplus -} -#endif +#define LOG_UART_MODIFIABLE_BAUD_RATE 1 RingBuffer rx_buffer0; -LOGUARTClass::LOGUARTClass(int dwIrq, RingBuffer* pRx_buffer ) -{ - _rx_buffer = pRx_buffer; - _dwIrq = dwIrq; +LOGUARTClass::LOGUARTClass(int dwIrq, RingBuffer *pRx_buffer) { + _rx_buffer = pRx_buffer; + _dwIrq = dwIrq; } -// Protected Methods ////////////////////////////////////////////////////////////// - - - - -// Public Methods ////////////////////////////////////////////////////////////// +void IrqHandler(void) { + uint8_t data = 0; + BOOL PullMode = _FALSE; + uint32_t IrqEn = DiagGetIsrEnReg(); + DiagSetIsrEnReg(0); -void IrqHandler( void ) -{ - - uint8_t data = 0; - BOOL PullMode = _FALSE; - uint32_t IrqEn = DiagGetIsrEnReg(); - - DiagSetIsrEnReg(0); - - data = DiagGetChar(PullMode); - if ( data > 0 ) + data = DiagGetChar(PullMode); + if (data > 0) rx_buffer0.store_char(data); - DiagSetIsrEnReg(IrqEn); - + DiagSetIsrEnReg(IrqEn); } - -void LOGUARTClass::begin( const uint32_t dwBaudRate ) -{ - DIAG_UartReInit((IRQ_FUN) IrqHandler); - NVIC_SetPriority(UART_LOG_IRQ, 10); - LOGUART_SetBaud(dwBaudRate); +void LOGUARTClass::begin(const uint32_t dwBaudRate) { + DIAG_UartReInit((IRQ_FUN)IrqHandler); + NVIC_SetPriority(UART_LOG_IRQ, 10); + LOGUART_SetBaud(dwBaudRate); } -void LOGUARTClass::end( void ) -{ - // clear any received data - _rx_buffer->_iHead = _rx_buffer->_iTail ; +void LOGUARTClass::end(void) { + // clear any received data + _rx_buffer->_iHead = _rx_buffer->_iTail; } -int LOGUARTClass::available( void ) -{ - return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE ; +int LOGUARTClass::available(void) { + return (uint32_t)(SERIAL_BUFFER_SIZE + _rx_buffer->_iHead - _rx_buffer->_iTail) % SERIAL_BUFFER_SIZE; } -int LOGUARTClass::peek( void ) -{ +int LOGUARTClass::peek(void) { - if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) - return -1 ; - - return _rx_buffer->_aucBuffer[_rx_buffer->_iTail] ; + if (_rx_buffer->_iHead == _rx_buffer->_iTail) + return -1; + return _rx_buffer->_aucBuffer[_rx_buffer->_iTail]; } -int LOGUARTClass::read( void ) -{ - // if the head isn't ahead of the tail, we don't have any characters - if ( _rx_buffer->_iHead == _rx_buffer->_iTail ) - return -1 ; - - uint8_t uc = _rx_buffer->_aucBuffer[_rx_buffer->_iTail] ; - _rx_buffer->_iTail = (unsigned int)(_rx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE ; - return uc ; +int LOGUARTClass::read(void) { + // if the head isn't ahead of the tail, we don't have any characters + if (_rx_buffer->_iHead == _rx_buffer->_iTail) + return -1; + uint8_t uc = _rx_buffer->_aucBuffer[_rx_buffer->_iTail]; + _rx_buffer->_iTail = (unsigned int)(_rx_buffer->_iTail + 1) % SERIAL_BUFFER_SIZE; + return uc; } -void LOGUARTClass::flush( void ) -{ -// TODO: -// while ( serial_writable(&(this->sobj)) != 1 ); -/* - // Wait for transmission to complete - while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) - ; -*/ +void LOGUARTClass::flush(void) { + // TODO: + // while ( serial_writable(&(this->sobj)) != 1 ); + /* + // Wait for transmission to complete + while ((_pUart->UART_SR & UART_SR_TXRDY) != UART_SR_TXRDY) + ; + */ } -size_t LOGUARTClass::write( const uint8_t uc_data ) -{ - DiagPutChar(uc_data); - return 1; +size_t LOGUARTClass::write(const uint8_t uc_data) { + DiagPutChar(uc_data); + return 1; } LOGUARTClass Serial(UART_LOG_IRQ, &rx_buffer0); bool Serial_available() { - return Serial.available() > 0; + return Serial.available() > 0; } diff --git a/arduino/realtek-ambz/cores/arduino/LOGUARTClass.h b/arduino/realtek-ambz/cores/arduino/LOGUARTClass.h index 16e263d9f..392cf9d28 100644 --- a/arduino/realtek-ambz/cores/arduino/LOGUARTClass.h +++ b/arduino/realtek-ambz/cores/arduino/LOGUARTClass.h @@ -8,7 +8,7 @@ This library 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public @@ -18,36 +18,41 @@ #pragma once -#include "api/HardwareSerial.h" -#include "api/RingBuffer.h" +#include +#include using namespace arduino; -class LOGUARTClass : public HardwareSerial -{ +// TODO this class begs to be rewritten :( + +class LOGUARTClass : public HardwareSerial { public: - LOGUARTClass(int dwIrq, RingBuffer* pRx_buffer ); + LOGUARTClass(int dwIrq, RingBuffer *pRx_buffer); + + void begin(const uint32_t dwBaudRate); + + inline void begin(const uint32_t dwBaudRate, uint16_t config) { + begin(dwBaudRate); // TODO implement this properly + } - void begin(const uint32_t dwBaudRate); - inline void begin(const uint32_t dwBaudRate, uint16_t config) { - begin(dwBaudRate); // TODO implement this properly - } - void end(void); - int available(void); - int peek(void); - int read(void); - void flush(void); - size_t write(const uint8_t c); + void end(void); + int available(void); + int peek(void); + int read(void); + void flush(void); + size_t write(const uint8_t c); - using Print::write; // pull in write(str) and write(buf, size) from Print + using Print::write; // pull in write(str) and write(buf, size) from Print - operator bool() { return true; }; // UART always active + operator bool() { + return true; // UART always active + } protected: - RingBuffer *_rx_buffer; + RingBuffer *_rx_buffer; - int _dwIrq; + int _dwIrq; private: - friend bool Serial_available(); + friend bool Serial_available(); }; diff --git a/arduino/realtek-ambz/cores/arduino/PowerManagement.h b/arduino/realtek-ambz/cores/arduino/PowerManagement.h deleted file mode 100644 index 0633cbeb1..000000000 --- a/arduino/realtek-ambz/cores/arduino/PowerManagement.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef _POWER_MANAGEMENT_H_ -#define _POWER_MANAGEMENT_H_ - -#include - -/** - * @class PowerManagementClass PowerManagement.h - * @brief Power management in Ameba - */ -class PowerManagementClass { -public: - - /** - * @brief Allow OS automatically save power while idle - * - * As OS consider it would idle for more than 2s, it will invoke system suspend. - * If wlan is associated with AP, than it will under asslociated idle state. - */ - static void sleep(void); - static void sleep(uint32_t bitflg); - - /** - * @brief Disallow OS automatically save power while idle - */ - static void active(void); - static void active(uint32_t bitflg); - - /** - * @brief Reserved PLL while sleep - * - * Reserve PLL would keep FIFO of peripherals (Ex. UART) but cost more power (around 5mA). - * If we don't reserve PLL, it saves more power but we might missing data because FIFO is turned of this way. - * - * @param[in] reserve true for reserved, false for non-reserved - */ - static void setPllReserved(bool reserve); - - /** - * @brief Enter deepsleep immediately - * - * Invoke deepsleep would make system enter deepsleep state immediately. - * It's the state that saves most power. - * As it wakeup from deepsleep, the system would behave just like reboot. - * - * @param[in] duration_ms wakeup after specific time in unit of millisecond - */ - static void deepsleep(uint32_t duration_ms); - - /** - * @brief Check if system is allowed enter any power save state - * - * The pin 18 (GPIOE_5) is designed as safe lock. - * If pin 18 is HIGH, then we prevent Ameba enter any power save state.\n\n - * Under any power save state, we are not able to flash image to Ameba. - * Thus if user misuse deepsleep and make Ameba enter deepsleep immediately after boot up, - * then he would find it's hard to flash image. - * In this case, he can pull up pin 18. - * - * @return true if system not allowed enter any power save state, and false vise versa - */ - static bool safeLock(); - - /** - * @brief Reboot system - * - * Reboot system in soft way. Some registers is not powered off in this case, but mostly we could regard this as reboot. - */ - static void softReset(); - -private: - static bool reservePLL; -}; - -extern PowerManagementClass PowerManagement; - -#endif \ No newline at end of file diff --git a/arduino/realtek-ambz/cores/arduino/Tone.cpp b/arduino/realtek-ambz/cores/arduino/Tone.cpp index b3fa3050d..816114e12 100644 --- a/arduino/realtek-ambz/cores/arduino/Tone.cpp +++ b/arduino/realtek-ambz/cores/arduino/Tone.cpp @@ -1,17 +1,12 @@ -#if 1 // !defined(BOARD_RTL8710) +#include -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { +extern void pinRemoveMode(pin_size_t pinNumber); extern void _tone(uint32_t ulPin, unsigned int frequency, unsigned long duration); -} -#endif -// a wrapper that support default value of duration -void tone(uint32_t ulPin, unsigned int frequency, unsigned long duration) -{ - _tone(ulPin, frequency, duration); +void tone(uint32_t ulPin, unsigned int frequency, unsigned long duration) { + _tone(ulPin, frequency, duration); } -#endif +void noTone(uint32_t ulPin) { + pinRemoveMode(ulPin); +} diff --git a/arduino/realtek-ambz/cores/arduino/WInterrupts.c b/arduino/realtek-ambz/cores/arduino/WInterrupts.c index 934a38032..b4e747108 100644 --- a/arduino/realtek-ambz/cores/arduino/WInterrupts.c +++ b/arduino/realtek-ambz/cores/arduino/WInterrupts.c @@ -1,16 +1,14 @@ -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gpio_api.h" -#include "gpio_irq_api.h" -#include "gpio_irq_ex_api.h" +#include +#include +#include +#include extern void *gpio_pin_struct[PINS_COUNT]; extern void *gpio_irq_handler_list[PINS_COUNT]; +extern bool pinInvalid(pin_size_t pinNumber); +extern void pinRemoveMode(pin_size_t pinNumber); + void gpioIrqHandler(uint32_t id, gpio_irq_event event) { if (gpio_irq_handler_list[id] != NULL) { ((void (*)(uint32_t, uint32_t))gpio_irq_handler_list[id])(id, (uint32_t)event); @@ -36,7 +34,7 @@ void attachInterrupt(pin_size_t interruptNumber, voidFuncPtr callback, PinStatus if (g_APinDescription[interruptNumber].ulPinType == NOT_INITIAL) { // allocate memory if pin not used before - gpio = malloc(sizeof(gpio_irq_t)); + gpio = malloc(sizeof(gpio_irq_t)); gpio_pin_struct[interruptNumber] = gpio; gpio_irq_init(gpio, g_APinDescription[interruptNumber].pinname, gpioIrqHandler, interruptNumber); g_APinDescription[interruptNumber].ulPinType = PIO_GPIO_IRQ; @@ -78,7 +76,3 @@ void detachInterrupt(pin_size_t interruptNumber) { } gpio_irq_handler_list[interruptNumber] = NULL; } - -#ifdef __cplusplus -} -#endif diff --git a/arduino/realtek-ambz/cores/arduino/WMath.cpp b/arduino/realtek-ambz/cores/arduino/WMath.cpp deleted file mode 100644 index c2351a624..000000000 --- a/arduino/realtek-ambz/cores/arduino/WMath.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include -#include "api/Common.h" - -extern "C" { -extern void rtl_srandom( uint32_t seed ); -extern uint32_t rtl_random( void ); -} - -#ifndef srand -#define srand rtl_srandom -#endif -#ifndef rand -#define rand rtl_random -#endif - -extern void randomSeed( uint32_t dwSeed ) -{ - if ( dwSeed != 0 ) - { - srand( dwSeed ) ; - } -} - -extern long random( long howbig ) -{ - if ( howbig == 0 ) - { - return 0 ; - } - - return rand() % howbig; -} - -extern long random( long howsmall, long howbig ) -{ - if (howsmall >= howbig) - { - return howsmall; - } - - long diff = howbig - howsmall; - - return random(diff) + howsmall; -} - -extern long map(long x, long in_min, long in_max, long out_min, long out_max) -{ - return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; -} - -extern uint16_t makeWord( uint16_t w ) -{ - return w ; -} - -extern uint16_t makeWord( uint8_t h, uint8_t l ) -{ - return (h << 8) | l ; -} diff --git a/arduino/realtek-ambz/cores/arduino/WVariant.h b/arduino/realtek-ambz/cores/arduino/WVariant.h index 0d627b8a6..f18b66cac 100644 --- a/arduino/realtek-ambz/cores/arduino/WVariant.h +++ b/arduino/realtek-ambz/cores/arduino/WVariant.h @@ -1,118 +1,60 @@ #pragma once -#include "wiring_os.h" -#include "wiring_watchdog.h" +#include +#include +#include #ifdef __cplusplus extern "C" { #endif -#include -#include -#include -#define boolean boolean_rtl -#include "rtl_lib.h" -#include "rand.h" -#include "rt_lib_rom.h" -#undef boolean +#include "sdk_extern.h" +#include "sdk_mem.h" +#include "sdk_os.h" -/* moved from Arduino.h */ -/* - * \brief Set CPU CLK 166MHz - * clk : 0 - 166666666 Hz, 1 - 83333333 Hz, 2 - 41666666 Hz, 3 - 20833333 Hz, 4 - 10416666 Hz, 5 - 4000000 Hz - * baud: 38400,... - */ -extern void Init_CPU_CLK_UART(int clkn, int baud); -extern void sys_info(void); -/* HalGetChipId: - * 0xff - RTL8711AM, 0xfe - RTL8195AM, 0xfd - RTL8711AF, - * 0xfc - RTL8710AF, 0xfb - RTL8711AN, 0xfa - RTL8710AM */ -extern unsigned char HalGetChipId(void); -extern unsigned int HalGetCpuClk(void); - -extern void wait_us(int us); -#define delay_us wait_us - -extern void yield(void); - -extern void *pvPortMalloc(size_t xWantedSize); -extern void *pvPortZalloc(size_t size); -extern void *pvPortCalloc(size_t nmemb, size_t size); -extern void *pvPortReAlloc(void *pv, size_t xWantedSize); -extern void vPortFree(void *pv); - -#define malloc pvPortMalloc -#define zalloc pvPortZalloc -#define calloc pvPortCalloc -#define realloc pvPortReAlloc -#define free vPortFree - -#ifndef printf -#define printf rtl_printf -#endif -#ifndef sprintf -#define sprintf rtl_sprintf -#endif - -#define NOT_INITIAL (1UL<<0) -#define PIO_GPIO (1UL<<1) -#define PIO_PWM (1UL<<2) -#define PIO_I2C (1UL<<3) -#define PIO_ADC (1UL<<4) -#define PIO_DAC (1UL<<5) -#define PIO_GPIO_IRQ (1UL<<6) +#define NOT_INITIAL (1UL << 0) +#define PIO_GPIO (1UL << 1) +#define PIO_PWM (1UL << 2) +#define PIO_I2C (1UL << 3) +#define PIO_ADC (1UL << 4) +#define PIO_DAC (1UL << 5) +#define PIO_GPIO_IRQ (1UL << 6) #define PWM_MODE_ENABLED 1 #define PWM_MODE_DISABLED 0 -/* Types used for the tables below */ -typedef struct _PinDescription -{ - // HW PinNames - uint32_t pinname; - // Current Pin Type - uint32_t ulPinType; - // Supported Pin Function - uint32_t ulPinAttribute; - // Current Pin Mode - uint32_t ulPinMode; -} PinDescription ; +#define DEFAULT 1 +#define EXTERNAL 0 -/* Pins table to be instanciated into variant.cpp */ +#define round(x) ((x) >= 0 ? (long)((x) + 0.5) : (long)((x)-0.5)) + +typedef enum _eAnalogReference { + AR_DEFAULT, +} eAnalogReference; + +// Types used for the table below +typedef struct _PinDescription { + // HW PinNames + uint32_t pinname; + // Current Pin Type + uint32_t ulPinType; + // Supported Pin Function + uint32_t ulPinAttribute; + // Current Pin Mode + uint32_t ulPinMode; +} PinDescription; + +// Pins table to be instantiated into variant.cpp extern PinDescription g_APinDescription[]; -extern bool pinInvalid(pin_size_t pinNumber); -extern void pinRemoveMode(pin_size_t pinNumber); - -/* moved from wiring_digital.h */ -/**************************** Extend API by RTK ***********************************/ -extern uint32_t digitalPinToPort( uint32_t pinNumber ); -extern uint32_t digitalPinToBitMask( uint32_t pinNumber ); - -/* moved from wiring_analog.h */ -/* - * \brief Set the resolution of analogRead return values. Default is 10 bits (range from 0 to 1023). - * - * \param res - */ +// Additional Wiring functions +extern uint32_t digitalPinToPort(uint32_t pinNumber); +extern uint32_t digitalPinToBitMask(uint32_t pinNumber); extern void analogReadResolution(int res); -/* - * \brief Set the resolution of analogWrite parameters. Default is 8 bits (range from 0 to 255). - * - * \param res - */ extern void analogWriteResolution(int res); -extern void analogOutputInit( void ) ; +extern void analogOutputInit(void); extern void analogWritePeriod(int us); - -/* moved from wiring_constants.h */ -#define DEFAULT 1 -#define EXTERNAL 0 - -#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5)) - -extern uint32_t ulPortSetInterruptMask( void ); -extern void vPortClearInterruptMask( uint32_t ulNewMask ); +extern void wait_for_debug(); #ifdef __cplusplus } // extern "C" diff --git a/arduino/realtek-ambz/cores/arduino/WebSocketClient.cpp b/arduino/realtek-ambz/cores/arduino/WebSocketClient.cpp deleted file mode 100644 index 747beb987..000000000 --- a/arduino/realtek-ambz/cores/arduino/WebSocketClient.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * WebSocketClient + SSL/TSL - * RTL8710AF pvvx 12/12/2016 - * - */ - -#include "Arduino.h" -#include "WebSocketClient.h" - -WebSocketClient::WebSocketClient() { -} - -WebSocketClient::WebSocketClient(char *url, int port, char *path, char* origin) { - client = create_wsclient(url, port, path, origin); -} - -WebSocketClient::~WebSocketClient() { - close(); -} - -int WebSocketClient::begin(char *url, int port, char *path, char* origin) { - client = create_wsclient(url, port, path, origin); - if(client != NULL) return 1; - else return 0; -} - -int WebSocketClient::connect() { - if(client != NULL) return ws_connect_url(client); - else return -1; -} - -void WebSocketClient::send(char* message, int message_len, int use_mask) { - if(client != NULL && client->readyState > CLOSED) { - ws_send(message, message_len, use_mask, client); - ws_poll(0, client); - } -} - -void WebSocketClient::sendBinary(uint8_t* message, int message_len, int use_mask) { - if(client != NULL && client->readyState > CLOSED) { - ws_sendBinary(message, message_len, use_mask, client); - ws_poll(0, client); - } -} - -void WebSocketClient::sendPing() { - if(client != NULL && client->readyState > CLOSED) { - ws_sendPing(client); - ws_poll(0, client); - } -} - -void WebSocketClient::poll(int timeout) { - if(client != NULL) ws_poll(timeout, client); -} - -readyStateValues WebSocketClient::getReadyState() { - if(client != NULL) return ws_getReadyState(client); - else return CLOSED; -} - -void WebSocketClient::dispatch(void (*callback)(wsclient_context *, int)) -{ - if(client != NULL) ws_dispatch(callback); -} - -void WebSocketClient::close() { - if(client != NULL) { - ws_close(client); - if(client->ssl) { - free(client->ssl); - client->ssl = NULL; - } - client = NULL; - } -} - -extern "C" void set_ssl_func(wsclient_context *wsclient); // in example_wsclient.c - -void WebSocketClient::ssl_func_on(void) -{ - set_ssl_func(client); -/* - client->fun_ops.ssl_fun_ops.memory_set_own = memory_set_own; - client->fun_ops.ssl_fun_ops.net_connect = net_connect; - client->fun_ops.ssl_fun_ops.ssl_init = ssl_init; - client->fun_ops.ssl_fun_ops.ssl_set_endpoint = ssl_set_endpoint; - client->fun_ops.ssl_fun_ops.ssl_set_authmode = ssl_set_authmode; - client->fun_ops.ssl_fun_ops.ssl_set_rng = ssl_set_rng; - client->fun_ops.ssl_fun_ops.ssl_set_bio = ssl_set_bio; - client->fun_ops.ssl_fun_ops.ssl_handshake = ssl_handshake; - client->fun_ops.ssl_fun_ops.net_close = net_close; - client->fun_ops.ssl_fun_ops.ssl_free = ssl_free; - client->fun_ops.ssl_fun_ops.ssl_read = ssl_read; - client->fun_ops.ssl_fun_ops.ssl_write = ssl_write; - client->fun_ops.ssl_fun_ops.net_recv = net_recv; - client->fun_ops.ssl_fun_ops.net_send = net_send; - client->ssl = (void *)zalloc(sizeof(struct _ssl_context)); // 380 bytes -*/ -} diff --git a/arduino/realtek-ambz/cores/arduino/WebSocketClient.h b/arduino/realtek-ambz/cores/arduino/WebSocketClient.h deleted file mode 100644 index 4ea14e4d6..000000000 --- a/arduino/realtek-ambz/cores/arduino/WebSocketClient.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * WebSocketClient + SSL/TSL - * RTL8710AF pvvx 12/12/2016 - * - */ -#ifndef WEBSOCKETCLIENT_H_ -#define WEBSOCKETCLIENT_H_ - -#include -extern "C" { -#include "libwsclient.h" -#include "wsclient_api.h" -} - -class WebSocketClient { -public: - WebSocketClient(); - ~WebSocketClient(); - -/************************************************************************************************* -** Function Name : begin -** Description : Creating the websocket client context structure -** Input : url:websocket server's url -** port:websocket server's port, if not given, default 80 for "ws", 443 for "wss" -** origin: the address or url of your self -** Return : Ok: 1 -** Failed: 0 -**************************************************************************************************/ - WebSocketClient(char *url, int port, char *path = NULL, char* origin = NULL); - int begin(char *url, int port, char *path = NULL, char* origin = NULL); - -/************************************************************************************************* -** Function Name : connect -** Description : Connecting to the websocket server -** Input : wsclient: the websocket client context created by create_wsclientfunction -** Return : Connected: the socket value -** Failed: -1 -**************************************************************************************************/ - int connect(); - -/************************************************************************************************* -** Function Name : ws_send -** Description : Create the sending string data and copy to tx_buf -** Input : message: the string that send to server(cannot exceeding the MAX_DATA_LEN -** message_len: the length of the string -** use_mask: 0/1; 1 means using mask for bynary -** wsclient: the websocket client context -** Return : None -**************************************************************************************************/ - void send(char* message, int message_len, int use_mask); - -/************************************************************************************************* -** Function Name : sendBinary -** Description : Create the sending binary data and copy to tx_buf -** Input : message: the binary that send to server(cannot exceeding the MAX_DATA_LEN -** message_len: the length of the binary -** use_mask: 0/1; 1 means using mask for bynary -** wsclient: the websocket client context -** Return : None -**************************************************************************************************/ - void sendBinary(uint8_t* message, int message_len, int use_mask); - -/************************************************************************************************* -** Function Name : sendPing -** Description : Sending Ping to websocket server -** Input : wsclient: the websocket client context -** Return : None -**************************************************************************************************/ - void sendPing(); - -/************************************************************************************************* -** Function Name : poll -** Description : Receicing data from server and send the data in tx_buf -** Input : timeout(in milliseconds) - wsclient: the websocket client context -** Return : None -**************************************************************************************************/ - void poll(int timeout); - -/************************************************************************************************* -** Function Name : dispatch -** Description : callback function when getting message from server -** Input : function that resolve the message received and the message length -** Return : None -**************************************************************************************************/ - void dispatch(void (*callback)(wsclient_context *, int)); - -/************************************************************************************************* -** Function Name : getReadyState -** Description : Getting the connection status -** Input : wsclient: the websocket client context -** Return : readyStateValues(4 types: CLOSING, CLOSED, CONNECTING, OPEN ) -**************************************************************************************************/ - readyStateValues getReadyState(); - -/************************************************************************************************* -** Function Name : close -** Description : Closing the connection with websocket server -** Input : wsclient: the websocket client context -** Return : None -**************************************************************************************************/ - void close(); - -/************************************************************************************************* -** Function Name : ssl_func_on -** Description : Set SSL/TSL function -** Input : None -** Return : None -**************************************************************************************************/ - void ssl_func_on(void); - -private: - wsclient_context *client; -}; - -#endif // WEBSOCKETCLIENT_H_ diff --git a/arduino/realtek-ambz/cores/arduino/b64.cpp b/arduino/realtek-ambz/cores/arduino/b64.cpp deleted file mode 100644 index 6a8b9da02..000000000 --- a/arduino/realtek-ambz/cores/arduino/b64.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// Simple Base64 code -// (c) Copyright 2010 MCQN Ltd. -// Released under Apache License, version 2.0 - -#include "b64.h" - -/* Simple test program -#include -void main() -{ - char* in = "amcewen"; - char out[22]; - - b64_encode(in, 15, out, 22); - out[21] = '\0'; - - printf(out); -} -*/ - -int b64_encode(const unsigned char* aInput, int aInputLen, unsigned char* aOutput, int aOutputLen) -{ - // Work out if we've got enough space to encode the input - // Every 6 bits of input becomes a byte of output - if (aOutputLen < (aInputLen*8)/6) - { - // FIXME Should we return an error here, or just the length - return (aInputLen*8)/6; - } - - // If we get here we've got enough space to do the encoding - - const char* b64_dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - if (aInputLen == 3) - { - aOutput[0] = b64_dictionary[aInput[0] >> 2]; - aOutput[1] = b64_dictionary[(aInput[0] & 0x3)<<4|(aInput[1]>>4)]; - aOutput[2] = b64_dictionary[(aInput[1]&0x0F)<<2|(aInput[2]>>6)]; - aOutput[3] = b64_dictionary[aInput[2]&0x3F]; - } - else if (aInputLen == 2) - { - aOutput[0] = b64_dictionary[aInput[0] >> 2]; - aOutput[1] = b64_dictionary[(aInput[0] & 0x3)<<4|(aInput[1]>>4)]; - aOutput[2] = b64_dictionary[(aInput[1]&0x0F)<<2]; - aOutput[3] = '='; - } - else if (aInputLen == 1) - { - aOutput[0] = b64_dictionary[aInput[0] >> 2]; - aOutput[1] = b64_dictionary[(aInput[0] & 0x3)<<4]; - aOutput[2] = '='; - aOutput[3] = '='; - } - else - { - // Break the input into 3-byte chunks and process each of them - int i; - for (i = 0; i < aInputLen/3; i++) - { - b64_encode(&aInput[i*3], 3, &aOutput[i*4], 4); - } - if (aInputLen % 3 > 0) - { - // It doesn't fit neatly into a 3-byte chunk, so process what's left - b64_encode(&aInput[i*3], aInputLen % 3, &aOutput[i*4], aOutputLen - (i*4)); - } - } -} - - diff --git a/arduino/realtek-ambz/cores/arduino/b64.h b/arduino/realtek-ambz/cores/arduino/b64.h deleted file mode 100644 index 99d44eda0..000000000 --- a/arduino/realtek-ambz/cores/arduino/b64.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef b64_h -#define b64_h - -int b64_encode(const unsigned char* aInput, int aInputLen, unsigned char* aOutput, int aOutputLen); - -#endif - diff --git a/arduino/realtek-ambz/cores/arduino/cxxabi-compat.cpp b/arduino/realtek-ambz/cores/arduino/cxxabi-compat.cpp deleted file mode 100644 index 7370b0be1..000000000 --- a/arduino/realtek-ambz/cores/arduino/cxxabi-compat.cpp +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -extern "C" void __cxa_pure_virtual(void) ; - -/* We compile with nodefaultlibs, so we need to provide an error - * handler for an empty pure virtual function */ -extern "C" void __cxa_pure_virtual(void) { - while(1) - ; -} diff --git a/arduino/realtek-ambz/cores/arduino/debug.h b/arduino/realtek-ambz/cores/arduino/debug.h deleted file mode 100644 index ce9045b1f..000000000 --- a/arduino/realtek-ambz/cores/arduino/debug.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef ARD_DEBUG_H -#define ARD_DEBUG_H - -#include -#include - -#ifdef DEBUG_RTL_CORE -#define DEBUGV(...) rtl_printf(__VA_ARGS__) -#endif - -#ifndef DEBUGV -#define DEBUGV(...) -#endif - -#ifdef __cplusplus -void hexdump(void * addr, int len = 16); -#else -void hexdump(void * addr, int len); -#endif - -#ifdef __cplusplus -extern "C" { -#endif -void print_udp_pcb(void); -void print_tcp_pcb(void); -void DumpForOneBytes(void *addr, int cnt); // cnt max 0x70 ! - -void __panic_func(const char* file, int line, const char* func) __attribute__((noreturn)); -#define panic() __panic_func(__FILE__, __LINE__, __func__) - -#ifdef __cplusplus -} -#endif - - -#endif//ARD_DEBUG_H diff --git a/arduino/realtek-ambz/cores/arduino/itoa.c b/arduino/realtek-ambz/cores/arduino/itoa.c deleted file mode 100644 index 7e35179f8..000000000 --- a/arduino/realtek-ambz/cores/arduino/itoa.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "api/itoa.h" -#include - -#ifdef __cplusplus -extern "C"{ -#endif // __cplusplus - -extern char* ltoa(long value, char *string, int radix) -{ - char tmp[33]; - char *tp = tmp; - long i; - unsigned long v; - int sign; - char *sp; - - if ( string == NULL ) - { - return 0 ; - } - - if (radix > 36 || radix <= 1) - { - return 0 ; - } - - sign = (radix == 10 && value < 0); - if (sign) - { - v = -value; - } - else - { - v = (unsigned long)value; - } - - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+'0'; - else - *tp++ = i + 'a' - 10; - } - - sp = string; - - if (sign) - *sp++ = '-'; - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - - return string; -} - -extern char* ultoa(unsigned long value, char *string, int radix) -{ - char tmp[33]; - char *tp = tmp; - long i; - unsigned long v = value; - char *sp; - - if ( string == NULL ) - { - return 0; - } - - if (radix > 36 || radix <= 1) - { - return 0; - } - - while (v || tp == tmp) - { - i = v % radix; - v = v / radix; - if (i < 10) - *tp++ = i+'0'; - else - *tp++ = i + 'a' - 10; - } - - sp = string; - - - while (tp > tmp) - *sp++ = *--tp; - *sp = 0; - - return string; -} - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus diff --git a/arduino/realtek-ambz/cores/arduino/libwsclient.h b/arduino/realtek-ambz/cores/arduino/libwsclient.h deleted file mode 100644 index 3c4a9a264..000000000 --- a/arduino/realtek-ambz/cores/arduino/libwsclient.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef EASYWSCLIENT_H -#define EASYWSCLIENT_H -#include - -/****************Define the debug message level*********************/ -#define DEBUG_WSCLIENT 1 - -#define WSCLIENT_LOG(level, fmt, ...) printf("\n\r[WSCLIENT %s] %s: " fmt "\n", level, __FUNCTION__, ##__VA_ARGS__) -#if DEBUG_WSCLIENT == 2 -#define WSCLIENT_DEBUG(fmt, ...) WSCLIENT_LOG("DEBUG", fmt, ##__VA_ARGS__) -#else -#define WSCLIENT_DEBUG(fmt, ...) -#endif -#if DEBUG_WSCLIENT -#define WSCLIENT_ERROR(fmt, ...) WSCLIENT_LOG("ERROR", fmt, ##__VA_ARGS__) -#else -#define WSCLIENT_ERROR(fmt, ...) -#endif -/*******************************************************************/ - -/****************Define the structures used*************************/ -typedef enum{ - CLOSING, - CLOSED, - CONNECTING, - OPEN -} readyStateValues; - -struct wsheader_type{ - unsigned header_size; - int fin; - int mask; - enum opcode_type { - CONTINUATION = 0x0, - TEXT_FRAME = 0x1, - BINARY_FRAME = 0x2, - CLOSE = 8, - PING = 9, - PONG = 0xa, - } opcode; - int N0; - uint64_t N; - uint8_t masking_key[4]; -}; - -struct _wsclient_context; -struct _ssl_context; - -struct ssl_fun_ops{ - int (*memory_set_own)( void * (*malloc_func)( size_t ),void (*free_func)( void * ) ); - int (*net_connect)( int *fd, const char *host, int port ); - int (*ssl_init)( struct _ssl_context *ssl ); - void (*ssl_set_endpoint)( struct _ssl_context *ssl, int endpoint ); - void (*ssl_set_authmode)( struct _ssl_context *ssl, int authmode ); - void (*ssl_set_rng)( struct _ssl_context *ssl, - int (*f_rng)(void *, unsigned char *, size_t), - void *p_rng ); - void (*ssl_set_bio)( struct _ssl_context *ssl, - int (*f_recv)(void *, unsigned char *, size_t), void *p_recv, - int (*f_send)(void *, const unsigned char *, size_t), void *p_send ); - int (*ssl_handshake)( struct _ssl_context *ssl ); - void (*net_close)( int fd ); - void (*ssl_free)( struct _ssl_context *ssl ); - int (*ssl_read)( struct _ssl_context *ssl, unsigned char *buf, size_t len ); - int (*ssl_write)( struct _ssl_context *ssl, const unsigned char *buf, size_t len ); - const char *(*ssl_get_ciphersuite)( const struct _ssl_context *ssl ); - int (*net_recv)( void *ctx, unsigned char *buf, size_t len ); - int (*net_send)( void *ctx, const unsigned char *buf, size_t len ); -}; - -struct ws_fun_ops{ - int (*hostname_connect)(struct _wsclient_context *wsclient); - void (*client_close)(struct _wsclient_context *wsclient); - int (*client_send)(struct _wsclient_context *wsclient, unsigned char *data, size_t data_len); - int (*client_read)(struct _wsclient_context *wsclient, unsigned char *data, size_t data_len); - struct ssl_fun_ops ssl_fun_ops; -}; - -typedef struct _wsclient_context{ - char host[128]; - char path[128]; - char origin[200]; - int port; - uint8_t use_ssl; - int sockfd; - readyStateValues readyState; - int tx_len; - void *ssl; - uint8_t *txbuf; - uint8_t *rxbuf; - uint8_t *receivedData; - struct ws_fun_ops fun_ops; -}wsclient_context; -/*******************************************************************/ - -/****************General functions used by wsclient*****************/ -void ws_get_random_bytes(void *buf, size_t len); -void* ws_malloc(unsigned int size); -void ws_free(void *buf); -int ws_client_handshake(wsclient_context *wsclient); -int ws_check_handshake(wsclient_context *wsclient); -void ws_sendData(uint8_t type, size_t message_size, uint8_t* message, int useMask, wsclient_context *wsclient); -/*******************************************************************/ - -/*************Functions used by wsclient without SSL****************/ - -int ws_hostname_connect(wsclient_context *wsclient); -int ws_client_read(wsclient_context *wsclient, unsigned char *data, size_t data_len); -int ws_client_send(wsclient_context *wsclient, unsigned char *data, size_t data_len); -void ws_client_close(wsclient_context *wsclient); -/*******************************************************************/ - -/***************Functions used by wsclient with SSL*****************/ -int wss_hostname_connect(wsclient_context *wsclient); -int wss_client_read(wsclient_context *wsclient, unsigned char *data, size_t data_len); -int wss_client_send(wsclient_context *wsclient, unsigned char *data, size_t data_len); -void wss_client_close(wsclient_context *wsclient); -/*******************************************************************/ - -#endif diff --git a/arduino/realtek-ambz/cores/arduino/lwip_info.c b/arduino/realtek-ambz/cores/arduino/lwip_info.c deleted file mode 100644 index e94ba9cb0..000000000 --- a/arduino/realtek-ambz/cores/arduino/lwip_info.c +++ /dev/null @@ -1,122 +0,0 @@ -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwip_netconf.h" -#include "lwip/udp.h" -#include "lwip/tcpip.h" -#include "lwip/err.h" -//#include "lwip/mem.h" -#include "lwip/tcp.h" -#include "lwip/tcp_impl.h" -#include "lwip/udp.h" - -/* Get one byte from the 4-byte address */ -#define ip4_addr1(ipaddr) (((u8_t*)(ipaddr))[0]) -#define ip4_addr2(ipaddr) (((u8_t*)(ipaddr))[1]) -#define ip4_addr3(ipaddr) (((u8_t*)(ipaddr))[2]) -#define ip4_addr4(ipaddr) (((u8_t*)(ipaddr))[3]) -/* These are cast to u16_t, with the intent that they are often arguments - * to printf using the U16_F format from cc.h. */ -#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) -#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) -#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) -#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) - -#define IP2STR(ipaddr) ip4_addr1_16(ipaddr), \ - ip4_addr2_16(ipaddr), \ - ip4_addr3_16(ipaddr), \ - ip4_addr4_16(ipaddr) - -#define IPSTR "%d.%d.%d.%d" - -extern const char * const tcp_state_str[]; -/* -static const char * const tcp_state_str[] = { - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RCVD", - "ESTABLISHED", - "FIN_WAIT_1", - "FIN_WAIT_2", - "CLOSE_WAIT", - "CLOSING", - "LAST_ACK", - "TIME_WAIT" -}; -*/ -/****************************************************************************** - * FunctionName : debug - * Parameters : - * Returns : -*******************************************************************************/ -void print_udp_pcb(void) -{ - struct udp_pcb *pcb; - bool prt_none = true; - rtl_printf("UDP pcbs:\n"); - for(pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { - rtl_printf("flg:%02x\t" IPSTR ":%d\t" IPSTR ":%d\trecv:%p\n", pcb->flags, IP2STR(&pcb->local_ip), pcb->local_port, IP2STR(&pcb->remote_ip), pcb->remote_port, pcb->recv ); - prt_none = false; - } - if(prt_none) rtl_printf("none\n"); -} -/****************************************************************************** - * FunctionName : debug - * Parameters : - * Returns : -*******************************************************************************/ -void print_tcp_pcb(void) -{ - struct tcp_pcb *pcb; - rtl_printf("Active PCB states:\n"); - bool prt_none = true; - for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); - prt_none = false; - } - if(prt_none) rtl_printf("none\n"); - rtl_printf("Listen PCB states:\n"); - prt_none = true; - for(pcb = (struct tcp_pcb *)tcp_listen_pcbs.pcbs; pcb != NULL; pcb = pcb->next) { - rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); - prt_none = false; - } - if(prt_none) rtl_printf("none\n"); - rtl_printf("TIME-WAIT PCB states:\n"); - prt_none = true; - for(pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - rtl_printf("Port %d|%d\tflg:%02x\ttmr:%p\t%s\n", pcb->local_port, pcb->remote_port, pcb->flags, pcb->tmr, tcp_state_str[pcb->state]); - prt_none = false; - } - if(prt_none) rtl_printf("none\n"); -} -/****************************************************************************** - * FunctionName : debug - * Parameters : - * Returns : -*******************************************************************************/ -#if 0 -//------------------------------------------------------------------------------ -void chow_tcp_connection_info(void) -{ - rtl_printf("TCP Server connections:\n"); - TCP_SERV_CFG * p; - TCP_SERV_CONN * ts_conn; - bool prt_none = true; - for(p = phcfg; p != NULL; p = p->next) { - for(ts_conn = p->conn_links; ts_conn != NULL; ts_conn = ts_conn->next) { - rtl_printf("%d "IPSTR ":%d %s\n", p->port, ts_conn->remote_ip.b[0], ts_conn->remote_ip.b[1], ts_conn->remote_ip.b[2], ts_conn->remote_ip.b[3], ts_conn->remote_port, tspsrv_srvconn_state_msg(ts_conn->state) ); - prt_none = false; - } - } - if(prt_none) rtl_printf("none\n"); -} -#endif - -#ifdef __cplusplus -} -#endif diff --git a/arduino/realtek-ambz/cores/arduino/main.cpp b/arduino/realtek-ambz/cores/arduino/main.cpp index d3b07d6e4..8a02de6ed 100644 --- a/arduino/realtek-ambz/cores/arduino/main.cpp +++ b/arduino/realtek-ambz/cores/arduino/main.cpp @@ -18,87 +18,62 @@ */ #define ARDUINO_MAIN -#include "Arduino.h" -#include "cmsis_os.h" - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#include "rtl8710b.h" -#include "FreeRTOS.h" -#include "task.h" -#include "diag.h" -extern void HalCpuClkConfig(u8 CpuType); -extern void SystemCoreClockUpdate(void); -extern void En32KCalibration(void); -extern int tcm_heap_freeSpace(void); -extern void console_init(void); - -#ifdef __cplusplus -} // extern "C" -#endif -osThreadId main_tid = 0; +#include +#include // Weak empty variant initialization function. // May be redefined by variant files. void initVariant() __attribute__((weak)); -void initVariant() { } + +void initVariant() {} // Initialize C library extern "C" void __libc_init_array(void); -/* - * \brief Init Random() - * \note Use in void __low_level_init(void) { Init_Rand(); } ! - */ -void Init_Rand(void) -{ - extern u32 _rand_z1, _rand_z2, _rand_z3, _rand_z4, _rand_first; - u32 *p = (u32 *)0x1FFFFF00; - while(p < (u32 *)0x20000000) _rand_z1 ^= *p++; - _rand_z1 ^= (*((u32 *)0x40002018) << 24) ^ (*((u32 *)0x40002118) << 16) ^ (*((u32 *)0x40002218) << 8) ^ *((u32 *)0x40002318); - _rand_z2 = ((_rand_z1 & 0x007F00FF) << 7) ^ ((_rand_z1 & 0x0F80FF00) >> 8); - _rand_z3 = ((_rand_z2 & 0x007F00FF) << 7) ^ ((_rand_z2 & 0x0F80FF00) >> 8); - _rand_z4 = ((_rand_z3 & 0x007F00FF) << 7) ^ ((_rand_z3 & 0x0F80FF00) >> 8); - _rand_first = 1; -} +osThreadId main_tid = 0; -/* - * \brief handle sketch - */ -void main_task( void const *arg ) -{ - setup(); - - for (;;) - { - loop(); - if (serialEventRun) serialEventRun(); - yield(); - } +void main_task(const void *arg) { + setup(); + + for (;;) { + loop(); + if (serialEventRun) + serialEventRun(); + yield(); + } } +int main(void) { + LT_BANNER(); + init(); -/* - * \brief Main entry point of Arduino application - */ -int main( void ) -{ - LT_BANNER(); - init(); + __libc_init_array(); + + initVariant(); - __libc_init_array(); + osThreadDef(main_task, osPriorityRealtime, 1, 4096 * 4); + main_tid = osThreadCreate(osThread(main_task), NULL); - initVariant(); + osKernelStart(); - osThreadDef(main_task, osPriorityRealtime, 1, 4096*4); - main_tid = osThreadCreate(osThread (main_task), NULL); + while (1) + ; - osKernelStart(); + return 0; +} + +void serialEvent() __attribute__((weak)); +bool Serial_available() __attribute__((weak)); - while(1); +void serialEventRun(void) { + if (Serial_available && serialEvent && Serial_available()) + serialEvent(); +} - return 0; +void wait_for_debug() { + while (((CoreDebug->DHCSR) & CoreDebug_DHCSR_C_DEBUGEN_Msk) == 0) { + asm("nop"); + } + delay(1000); } diff --git a/arduino/realtek-ambz/cores/arduino/netbios.h b/arduino/realtek-ambz/cores/arduino/netbios.h deleted file mode 100644 index 32566b102..000000000 --- a/arduino/realtek-ambz/cores/arduino/netbios.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __NETBIOS_H__ -#define __NETBIOS_H__ - -/** default port number for "NetBIOS Name service */ -#define NETBIOS_PORT 137 - -/** size of a NetBIOS name */ -#define NETBIOS_NAME_LEN 16 - -#ifndef NET_IF_NUM -#define NET_IF_NUM 2 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -extern char netbios_name[NET_IF_NUM][NETBIOS_NAME_LEN + 1]; // default netifs/interfacenum: 0 - SoftAP, 1 - Station, 2 - Ethernet - -// struct udp_pcb * netbios_pcb(void); -void netbios_init(void); -bool netbios_set_name(unsigned char interfacenum, char * name); // default netifs/interfacenum: 0 - SoftAP, 1 - Station, 2 - Ethernet -bool netbios_off(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __NETBIOS_H__ */ diff --git a/arduino/realtek-ambz/cores/arduino/rtl_sys.cpp b/arduino/realtek-ambz/cores/arduino/rtl_sys.cpp deleted file mode 100644 index b2b2e2ff5..000000000 --- a/arduino/realtek-ambz/cores/arduino/rtl_sys.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - Copyright (c) 2014 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#include - -extern void *pvPortMalloc( size_t xWantedSize ); -extern size_t xPortGetFreeHeapSize( void ); -extern size_t xPortGetMinimumEverFreeHeapSize( void ); - -extern void *tcm_heap_malloc(int size); -extern void *tcm_heap_calloc(int size); -extern void tcm_heap_free(void * mem); -extern void tcm_heap_dump(void); -extern int tcm_heap_freeSpace(void); - - -__attribute__((noreturn)) void __panic_func(const char* file, int line, const char* func) -{ - DiagPrintf("\r\nPanic: %s, line: %d, %s\r\n"); - while(1); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -void hexdump(void * ptr, int cnt) -{ - char * p = (char *) ptr; - int c = cnt; - while(c > 64) { - DumpForOneBytes((void *)p, 64); - p += 64; - c -= 64; - } - if(c != 0) DumpForOneBytes((void *)p, c); -} - -void debug_on(void) -{ - ConfigDebugErr = -1; - ConfigDebugInfo = -1; - ConfigDebugWarn = -1; - CfgSysDebugErr = -1; - CfgSysDebugInfo = -1; - CfgSysDebugWarn = -1; -} - -void sys_info(void) { - rtl_printf("\r\nCLK CPU\t\t%d Hz\r\nRAM heap\t%d bytes\r\nTCM heap\t%d bytes\r\n", - HalGetCpuClk(), xPortGetFreeHeapSize(), tcm_heap_freeSpace()); -} - -void *pvPortZalloc(size_t size) { - void *pvReturn = pvPortMalloc(size); - if (pvReturn) - memset(pvReturn, 0, size); - return pvReturn; -} - -void *pvPortCalloc(size_t nmemb, size_t size) { - return pvPortZalloc(nmemb * size); -} diff --git a/arduino/realtek-ambz/cores/arduino/sdk_extern.h b/arduino/realtek-ambz/cores/arduino/sdk_extern.h new file mode 100644 index 000000000..388faacf4 --- /dev/null +++ b/arduino/realtek-ambz/cores/arduino/sdk_extern.h @@ -0,0 +1,37 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-05-06. */ + +#pragma once + +#include +#include +#include + +#define boolean boolean_rtl +#include +#include +#include +#include +#include +#include +#undef boolean + +// stdio.h +#define printf rtl_printf +#define sprintf rtl_sprintf + +// moved from syscalls.h +#define _close __rtl_close +#define _fstat __rtl_fstat +#define _isatty __rtl_isatty +#define _lseek __rtl_lseek +#define _open __rtl_open +#define _read __rtl_read +#define _write __rtl_write +#define _sbrk __rtl_sbrk + +#define delay_us wait_us + +extern void wait_us(int us); +extern int LOGUART_SetBaud(uint32_t BaudRate); // from fixups/log_uart.c +extern void DumpForOneBytes(void *addr, int cnt); // cnt max 0x70! +extern void SystemCoreClockUpdate(void); diff --git a/arduino/realtek-ambz/cores/arduino/sdk_mem.c b/arduino/realtek-ambz/cores/arduino/sdk_mem.c new file mode 100644 index 000000000..a91b8c4dd --- /dev/null +++ b/arduino/realtek-ambz/cores/arduino/sdk_mem.c @@ -0,0 +1,16 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-05-06. */ + +#include "sdk_mem.h" + +#include // for memset + +void *pvPortZalloc(size_t size) { + void *pvReturn = pvPortMalloc(size); + if (pvReturn) + memset(pvReturn, 0, size); + return pvReturn; +} + +void *pvPortCalloc(size_t nmemb, size_t size) { + return pvPortZalloc(nmemb * size); +} diff --git a/arduino/realtek-ambz/cores/arduino/sdk_mem.h b/arduino/realtek-ambz/cores/arduino/sdk_mem.h new file mode 100644 index 000000000..2f0e9e276 --- /dev/null +++ b/arduino/realtek-ambz/cores/arduino/sdk_mem.h @@ -0,0 +1,19 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-05-06. */ + +#pragma once + +#include + +// provide extern functions directly, as callers +// generally don't expect needing to include malloc() +extern void *pvPortMalloc(size_t xWantedSize); +extern void *pvPortZalloc(size_t size); +extern void *pvPortCalloc(size_t nmemb, size_t size); +extern void *pvPortReAlloc(void *pv, size_t xWantedSize); +extern void vPortFree(void *pv); + +#define malloc pvPortMalloc +#define zalloc pvPortZalloc +#define calloc pvPortCalloc +#define realloc pvPortReAlloc +#define free vPortFree diff --git a/arduino/realtek-ambz/cores/arduino/sdk_os.c b/arduino/realtek-ambz/cores/arduino/sdk_os.c new file mode 100644 index 000000000..801ecdf71 --- /dev/null +++ b/arduino/realtek-ambz/cores/arduino/sdk_os.c @@ -0,0 +1,110 @@ +#include "sdk_os.h" + +#include +#include + +uint32_t os_thread_create(void (*task)(const void *argument), void *argument, int priority, uint32_t stack_size) { + + osThreadDef_t thread_def; + + thread_def.pthread = task; + thread_def.tpriority = (osPriority)priority; + // the underlying freertos implementation on cmsis os divide stack size by 4 + thread_def.stacksize = stack_size * 4; + thread_def.name = "ARDUINO"; + + return (uint32_t)osThreadCreate(&thread_def, argument); +} + +uint32_t os_thread_get_id(void) { + return osThreadGetId(); +} + +uint32_t os_thread_terminate(uint32_t thread_id) { + return (uint32_t)osThreadTerminate(thread_id); +} + +uint32_t os_thread_yield(void) { + return (uint32_t)osThreadYield(); +} + +uint32_t os_thread_set_priority(uint32_t thread_id, int priority) { + return (uint32_t)osThreadSetPriority(thread_id, (osPriority)priority); +} + +int os_thread_get_priority(uint32_t thread_id) { + return (int)osThreadGetPriority(thread_id); +} + +int32_t os_signal_set(uint32_t thread_id, int32_t signals) { + return osSignalSet(thread_id, signals); +} + +int32_t os_signal_clear(uint32_t thread_id, int32_t signals) { + return osSignalClear(thread_id, signals); +} + +os_event_t os_signal_wait(int32_t signals, uint32_t millisec) { + + osEvent evt; + os_event_t ret; + + evt = osSignalWait(signals, millisec); + ret.status = (uint32_t)evt.status; + ret.value.signals = evt.value.signals; + ret.def.message_id = evt.def.message_id; + + return ret; +} + +typedef void (*os_ptimer)(const void *argument); + +uint32_t os_timer_create(void (*callback)(const void *argument), uint8_t isPeriodic, void *argument) { + + osTimerDef_t *pTimerDef; + + pTimerDef = (osTimerDef_t *)malloc(sizeof(osTimerDef_t)); + pTimerDef->ptimer = callback; + pTimerDef->custom = (struct os_timer_custom *)malloc(sizeof(struct os_timer_custom)); + + return osTimerCreate(pTimerDef, (isPeriodic ? osTimerPeriodic : osTimerOnce), argument); +} + +uint32_t os_timer_start(uint32_t timer_id, uint32_t millisec) { + return osTimerStart(timer_id, millisec); +} + +uint32_t os_timer_stop(uint32_t timer_id) { + return osTimerStop(timer_id); +} + +uint32_t os_timer_delete(uint32_t timer_id) { + + osTimerDef_t *pTimerDef; + + pTimerDef = (osTimerDef_t *)pvTimerGetTimerID(timer_id); + free(pTimerDef->custom); + free(pTimerDef); + + return osTimerDelete(timer_id); +} + +uint32_t os_semaphore_create(int32_t count) { + return (uint32_t)osSemaphoreCreate(NULL, count); +} + +int32_t os_semaphore_wait(uint32_t semaphore_id, uint32_t millisec) { + if (osSemaphoreWait((osSemaphoreId)semaphore_id, millisec) == 0) { + return 1; + } else { + return 0; + } +} + +uint32_t os_semaphore_release(uint32_t semaphore_id) { + return (uint32_t)osSemaphoreRelease((osSemaphoreId)semaphore_id); +} + +uint32_t os_semaphore_delete(uint32_t semaphore_id) { + return (uint32_t)osSemaphoreDelete((osSemaphoreId)semaphore_id); +} diff --git a/arduino/realtek-ambz/cores/arduino/wiring_os.h b/arduino/realtek-ambz/cores/arduino/sdk_os.h similarity index 74% rename from arduino/realtek-ambz/cores/arduino/wiring_os.h rename to arduino/realtek-ambz/cores/arduino/sdk_os.h index df81905e2..c3483d991 100644 --- a/arduino/realtek-ambz/cores/arduino/wiring_os.h +++ b/arduino/realtek-ambz/cores/arduino/sdk_os.h @@ -1,13 +1,4 @@ -/** @file wiring_os.h */ - -/** - * @defgroup wiring_os wiring_os - * OS realted function for thread, signal, software timer, semaphore - * @{ - */ - -#ifndef _WIRING_OS_H_ -#define _WIRING_OS_H_ +#pragma once #ifdef __cplusplus extern "C" { @@ -21,33 +12,33 @@ extern "C" { * @{ */ /** function completed; no error or event occurred. */ -#define OS_OK 0x00 +#define OS_OK 0x00 /** function completed; signal event occurred. */ -#define OS_EVENT_SIGNAL 0x08 +#define OS_EVENT_SIGNAL 0x08 /** function completed; message event occurred. */ -#define OS_EVENT_MESSAGE 0x10 +#define OS_EVENT_MESSAGE 0x10 /** function completed; mail event occurred. */ -#define OS_EVENT_MAIL 0x20 +#define OS_EVENT_MAIL 0x20 /** function completed; timeout occurred. */ -#define OS_EVENT_TIMEOUT 0x40 +#define OS_EVENT_TIMEOUT 0x40 /** parameter error: a mandatory parameter was missing or specified an incorrect object. */ -#define OS_ERROR_PARAMETER 0x80 +#define OS_ERROR_PARAMETER 0x80 /** resource not available: a specified resource was not available. */ -#define OS_ERROR_RESOURCE 0x81 +#define OS_ERROR_RESOURCE 0x81 /** resource not available within given time: a specified resource was not available within the timeout period. */ #define OS_ERROR_TIMEOUT_RESOURCE 0xC1 /** not allowed in ISR context: the function cannot be called from interrupt service routines. */ -#define OS_ERROR_ISR 0x82 +#define OS_ERROR_ISR 0x82 /** function called multiple times from ISR with same object. */ -#define OS_ERROR_ISR_RECURSIVE 0x83 +#define OS_ERROR_ISR_RECURSIVE 0x83 /** system cannot determine priority or thread has illegal priority. */ -#define OS_ERROR_PRIORITY 0x84 +#define OS_ERROR_PRIORITY 0x84 /** system is out of memory: it was impossible to allocate or reserve memory for the operation. */ -#define OS_ERROR_NO_MEMORY 0x85 +#define OS_ERROR_NO_MEMORY 0x85 /** value of a parameter is out of range. */ -#define OS_ERROR_VALUE 0x86 +#define OS_ERROR_VALUE 0x86 /** unspecified RTOS error: run-time error but no other error message fits. */ -#define OS_ERROR_OS 0xFF +#define OS_ERROR_OS 0xFF /** @} */ // end of group os_status /** @@ -56,19 +47,19 @@ extern "C" { * @{ */ /** priority: idle (lowest) */ -#define OS_PRIORITY_IDLE (-3) +#define OS_PRIORITY_IDLE (-3) /** priority: low */ -#define OS_PRIORITY_LOW (-2) +#define OS_PRIORITY_LOW (-2) /** priority: below normal */ -#define OS_PRIORITY_BELOW_NORMAL (-1) +#define OS_PRIORITY_BELOW_NORMAL (-1) /** priority: normal (default) */ -#define OS_PRIORITY_NORMAL ( 0) +#define OS_PRIORITY_NORMAL (0) /** priority: above normal */ -#define OS_PRIORITY_ABOVENORMAL (+1) +#define OS_PRIORITY_ABOVENORMAL (+1) /** priority: high */ -#define OS_PRIORITY_HIGH (+2) +#define OS_PRIORITY_HIGH (+2) /** priority: realtime (highest) */ -#define OS_PRIORITY_REALTIME (+3) +#define OS_PRIORITY_REALTIME (+3) /** @} */ // end of group os_priority #ifndef DEFAULT_STACK_SIZE @@ -87,16 +78,18 @@ extern "C" { * Redefine osEvent in cmsis_os.h */ typedef struct { - uint32_t status; ///< status code: event or error information - union { - uint32_t v; ///< message as 32-bit value - void *p; ///< message or mail as void pointer - int32_t signals; ///< signal flags - } value; ///< event value - union { - void *mail_id; ///< mail id obtained by osMailCreate - void *message_id; ///< message id obtained by osMessageCreate - } def; ///< event definition + uint32_t status; ///< status code: event or error information + + union { + uint32_t v; ///< message as 32-bit value + void *p; ///< message or mail as void pointer + int32_t signals; ///< signal flags + } value; ///< event value + + union { + void *mail_id; ///< mail id obtained by osMailCreate + void *message_id; ///< message id obtained by osMessageCreate + } def; ///< event definition } os_event_t; /** @@ -108,12 +101,14 @@ typedef struct { * @ingroup thread_management * @brief Create a thread and add it to Active Threads and set it to state READY. * - * @param[in] task Function pointer which is the thread body. It should not run into the end of function unless os_thread_terminate is invoked + * @param[in] task Function pointer which is the thread body. It should not run into the end of function unless + * os_thread_terminate is invoked * @param[in] argument the data pointer which brings to task - * @param[in] priority The underlying os is FreeRTOS. It executes tasks with highest priority which are not in idle state.\n - * If there are more than 2 tasks to be executed, then they share the time slice. + * @param[in] priority The underlying os is FreeRTOS. It executes tasks with highest priority which are not in idle + * state.\n If there are more than 2 tasks to be executed, then they share the time slice. * @param[in] stack_size The stack_size is used as memory heap only for this task. \n - * The local variables and call stacks would occupy this heap. Please make sure the the stack_size is big enough to avoid curroption + * The local variables and call stacks would occupy this heap. Please make sure the the stack_size is big enough to + * avoid curroption * @return The thread id which is used in thread operation and signaling. */ extern uint32_t os_thread_create(void (*task)(const void *argument), void *argument, int priority, uint32_t stack_size); @@ -124,7 +119,7 @@ extern uint32_t os_thread_create(void (*task)(const void *argument), void *argum * * @return Current thread id which calls os_thread_get_id */ -extern uint32_t os_thread_get_id( void ); +extern uint32_t os_thread_get_id(void); /** * @ingroup thread_management @@ -141,9 +136,10 @@ extern uint32_t os_thread_terminate(uint32_t thread_id); * @ingroup thread_management * @brief Pass control to next thread that is in state \b READY. * - * By default the minimal execution unit is 1 millisecond. In a scenario that if a thread with smaller want to handout execution right to a thread with - * higher priority immediately without waiting for the ending of current 1 millisecond, then invoke os_thread_yield can transfer exection right to - * OS's idle task and check which is the next execution thread. + * By default the minimal execution unit is 1 millisecond. In a scenario that if a thread with smaller want to handout + * execution right to a thread with higher priority immediately without waiting for the ending of current 1 millisecond, + * then invoke os_thread_yield can transfer exection right to OS's idle task and check which is the next execution + * thread. * * @return os_status code */ @@ -168,7 +164,7 @@ extern uint32_t os_thread_set_priority(uint32_t thread_id, int priority); */ extern int os_thread_get_priority(uint32_t thread_id); -/** +/** * @defgroup signal_management signal_management * Signaling between threads include set, clear, and wait */ @@ -196,7 +192,7 @@ extern int32_t os_signal_clear(uint32_t thread_id, int32_t signals); /** * @ingroup signal_management * @brief Wait for one or more Signal Flags to become signaled for the current \b RUNNING thread. - * + * * @param[in] signals the signals to be wait * @param[in] millisec the timeout value if no signal comes in. Fill in 0xFFFFFFFF for infinite wait. * @return os_status code @@ -208,14 +204,14 @@ extern os_event_t os_signal_wait(int32_t signals, uint32_t millisec); * Software timer management include create, start, stop, delete. */ -/** - * @ingroup timer_management +/** + * @ingroup timer_management * @brief specify timer type that invoke only once */ -#define OS_TIMER_ONCE (0) +#define OS_TIMER_ONCE (0) -/** - * @ingroup timer_management +/** + * @ingroup timer_management * @brief specify timer type that invoke periodically */ #define OS_TIMER_PERIODIC (1) @@ -229,7 +225,7 @@ extern os_event_t os_signal_wait(int32_t signals, uint32_t millisec); * @param[in] argument The argument that is bring into callback function * @return timer id */ -extern uint32_t os_timer_create(void (*callback)(void const *argument), uint8_t isPeriodic, void *argument); +extern uint32_t os_timer_create(void (*callback)(const void *argument), uint8_t isPeriodic, void *argument); /** * @ingroup timer_management @@ -239,7 +235,7 @@ extern uint32_t os_timer_create(void (*callback)(void const *argument), uint8_t * @param[in] millisec The delays after timer starts * @return os_status code */ -extern uint32_t os_timer_start (uint32_t timer_id, uint32_t millisec); +extern uint32_t os_timer_start(uint32_t timer_id, uint32_t millisec); /** * @ingroup timer_management @@ -248,7 +244,7 @@ extern uint32_t os_timer_start (uint32_t timer_id, uint32_t millisec); * @param[in] timer_id The timer id obtained from by os_timer_create * @return os_status code */ -extern uint32_t os_timer_stop (uint32_t timer_id); +extern uint32_t os_timer_stop(uint32_t timer_id); /** * @ingroup timer_management @@ -304,7 +300,3 @@ extern uint32_t os_semaphore_delete(uint32_t semaphore_id); #ifdef __cplusplus } #endif - -#endif - -/** @} */ // end of group wiring_os \ No newline at end of file diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/LICENSE b/arduino/realtek-ambz/cores/arduino/spiffs/LICENSE deleted file mode 100644 index e9b0c6777..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2013-2015 Peter Andersson (pelleplutt1976gmail.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/README.md b/arduino/realtek-ambz/cores/arduino/spiffs/README.md deleted file mode 100644 index 5f8efd8da..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/README.md +++ /dev/null @@ -1,146 +0,0 @@ -# SPIFFS (SPI Flash File System) -**V0.3.4** - -Copyright (c) 2013-2016 Peter Andersson (pelleplutt1976 at gmail.com) - -For legal stuff, see [LICENSE](https://github.com/pellepl/spiffs/blob/master/LICENSE). Basically, you may do whatever you want with the source. Use, modify, sell, print it out, roll it and smoke it - as long as I won't be held responsible. - -Love to hear feedback though! - - -## INTRODUCTION - -Spiffs is a file system intended for SPI NOR flash devices on embedded targets. - -Spiffs is designed with following characteristics in mind: - - Small (embedded) targets, sparse RAM without heap - - Only big areas of data (blocks) can be erased - - An erase will reset all bits in block to ones - - Writing pulls one to zeroes - - Zeroes can only be pulled to ones by erase - - Wear leveling - - -## FEATURES - -What spiffs does: - - Specifically designed for low ram usage - - Uses statically sized ram buffers, independent of number of files - - Posix-like api: open, close, read, write, seek, stat, etc - - It can be run on any NOR flash, not only SPI flash - theoretically also on embedded flash of an microprocessor - - Multiple spiffs configurations can be run on same target - and even on same SPI flash device - - Implements static wear leveling - - Built in file system consistency checks - -What spiffs does not: - - Presently, spiffs does not support directories. It produces a flat structure. Creating a file with path *tmp/myfile.txt* will create a file called *tmp/myfile.txt* instead of a *myfile.txt* under directory *tmp*. - - It is not a realtime stack. One write operation might take much longer than another. - - Poor scalability. Spiffs is intended for small memory devices - the normal sizes for SPI flashes. Going beyond ~128MB is probably a bad idea. This is a side effect of the design goal to use as little ram as possible. - - Presently, it does not detect or handle bad blocks. - - -## MORE INFO - -See the [wiki](https://github.com/pellepl/spiffs/wiki) for configuring, integrating and using spiffs. - -For design, see [docs/TECH_SPEC](https://github.com/pellepl/spiffs/blob/master/docs/TECH_SPEC). - -For a generic spi flash driver, see [this](https://github.com/pellepl/spiflash_driver). - -## HISTORY - -### 0.3.4 -- Added user callback file func. -- Fixed a stat bug with obj id. -- SPIFFS_probe_fs added -- Add possibility to compile a read-only version of spiffs -- Make magic dependent on fs length, if needed (see #59 & #66) (thanks @hreintke) -- Exposed SPIFFS_open_by_page_function -- Zero-size file cannot be seek #57 (thanks @lishen2) -- Add tell and eof functions #54 (thanks @raburton) -- Make api string params const #53 (thanks @raburton) -- Preserve user_data during mount() #51 (thanks @rojer) - -New API functions: -- `SPIFFS_set_file_callback_func` - register a callback informing about file events -- `SPIFFS_probe_fs` - probe a spi flash trying to figure out size of fs -- `SPIFFS_open_by_page` - open a file by page index -- `SPIFFS_eof` - checks if end of file is reached -- `SPIFFS_tell` - returns current file offset - -New config defines: -- `SPIFFS_READ_ONLY` -- `SPIFFS_USE_MAGIC_LENGTH` - -### 0.3.3 -**Might not be compatible with 0.3.2 structures. See issue #40** -- Possibility to add integer offset to file handles -- Truncate function presumes too few free pages #49 -- Bug in truncate function #48 (thanks @PawelDefee) -- Update spiffs_gc.c - remove unnecessary parameter (thanks @PawelDefee) -- Update INTEGRATION docs (thanks @PawelDefee) -- Fix pointer truncation in 64-bit platforms (thanks @igrr) -- Zero-sized files cannot be read #44 (thanks @rojer) -- (More) correct calculation of max_id in obj_lu_find #42 #41 (thanks @lishen2) -- Check correct error code in obj_lu_find_free #41 (thanks @lishen2) -- Moar comments for SPIFFS_lseek (thanks @igrr) -- Fixed padding in spiffs_page_object_ix #40 (thanks @jmattsson @lishen2) -- Fixed gc_quick test (thanks @jmattsson) -- Add SPIFFS_EXCL flag #36 -- SPIFFS_close may fail silently if cache is enabled #37 -- User data in callbacks #34 -- Ignoring SINGLETON build in cache setup (thanks Luca) -- Compilation error fixed #32 (thanks @chotasanjiv) -- Align cand_scores (thanks @hefloryd) -- Fix build warnings when SPIFFS_CACHE is 0 (thanks @ajaybhargav) - -New config defines: -- `SPIFFS_FILEHDL_OFFSET` - -### 0.3.2 -- Limit cache size if too much cache is given (thanks pgeiem) -- New feature - Controlled erase. #23 -- SPIFFS_rename leaks file descriptors #28 (thanks benpicco) -- moved dbg print defines in test framework to params_test.h -- lseek should return the resulting offset (thanks hefloryd) -- fixed type on dbg ifdefs -- silence warning about signed/unsigned comparison when spiffs_obj_id is 32 bit (thanks benpicco) -- Possible error in test_spiffs.c #21 (thanks yihcdaso-yeskela) -- Cache might writethrough too often #16 -- even moar testrunner updates -- Test framework update and some added tests -- Some thoughts for next gen -- Test sigsevs when having too many sectors #13 (thanks alonewolfx2) -- GC might be suboptimal #11 -- Fix eternal readdir when objheader at last block, last entry - -New API functions: -- `SPIFFS_gc_quick` - call a nonintrusive gc -- `SPIFFS_gc` - call a full-scale intrusive gc - -### 0.3.1 -- Removed two return warnings, was too triggerhappy on release - -### 0.3.0 -- Added existing namecheck when creating files -- Lots of static analysis bugs #6 -- Added rename func -- Fix SPIFFS_read length when reading beyond file size -- Added reading beyond file length testcase -- Made build a bit more configurable -- Changed name in spiffs from "errno" to "err_code" due to conflicts compiling in mingw -- Improved GC checks, fixed an append bug, more robust truncate for very special case -- GC checks preempts GC, truncate even less picky -- Struct alignment needed for some targets, define in spiffs config #10 -- Spiffs filesystem magic, definable in config - -New config defines: -- `SPIFFS_USE_MAGIC` - enable or disable magic check upon mount -- `SPIFFS_ALIGNED_OBJECT_INDEX_TABLES` - alignment for certain targets - -New API functions: -- `SPIFFS_rename` - rename files -- `SPIFFS_clearerr` - clears last errno -- `SPIFFS_info` - returns info on used and total bytes in fs -- `SPIFFS_format` - formats the filesystem -- `SPIFFS_mounted` - checks if filesystem is mounted diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/TECH_SPEC b/arduino/realtek-ambz/cores/arduino/spiffs/TECH_SPEC deleted file mode 100644 index b4755a6db..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/TECH_SPEC +++ /dev/null @@ -1,239 +0,0 @@ -* USING SPIFFS - -TODO - - -* SPIFFS DESIGN - -Spiffs is inspired by YAFFS. However, YAFFS is designed for NAND flashes, and -for bigger targets with much more ram. Nevertheless, many wise thoughts have -been borrowed from YAFFS when writing spiffs. Kudos! - -The main complication writing spiffs was that it cannot be assumed the target -has a heap. Spiffs must go along only with the work ram buffer given to it. -This forces extra implementation on many areas of spiffs. - - -** SPI flash devices using NOR technology - -Below is a small description of how SPI flashes work internally. This is to -give an understanding of the design choices made in spiffs. - -SPI flash devices are physically divided in blocks. On some SPI flash devices, -blocks are further divided into sectors. Datasheets sometimes name blocks as -sectors and vice versa. - -Common memory capacaties for SPI flashes are 512kB up to 8MB of data, where -blocks may be 64kB. Sectors can be e.g. 4kB, if supported. Many SPI flashes -have uniform block sizes, whereas others have non-uniform - the latter meaning -that e.g. the first 16 blocks are 4kB big, and the rest are 64kB. - -The entire memory is linear and can be read and written in random access. -Erasing can only be done block- or sectorwise; or by mass erase. - -SPI flashes can normally be erased from 100.000 up to 1.000.000 cycles before -they fail. - -A clean SPI flash from factory have all bits in entire memory set to one. A -mass erase will reset the device to this state. Block or sector erasing will -put the all bits in the area given by the sector or block to ones. Writing to a -NOR flash pulls ones to zeroes. Writing 0xFF to an address is simply a no-op. - -Writing 0b10101010 to a flash address holding 0b00001111 will yield 0b00001010. - -This way of "write by nand" is used considerably in spiffs. - -Common characteristics of NOR flashes are quick reads, but slow writes. - -And finally, unlike NAND flashes, NOR flashes seem to not need any error -correction. They always write correctly I gather. - - -** Spiffs logical structure - -Some terminology before proceeding. Physical blocks/sectors means sizes stated -in the datasheet. Logical blocks and pages is something the integrator choose. - - -** Blocks and pages - -Spiffs is allocated to a part or all of the memory of the SPI flash device. -This area is divided into logical blocks, which in turn are divided into -logical pages. The boundary of a logical block must coincide with one or more -physical blocks. The sizes for logical blocks and logical pages always remain -the same, they are uniform. - -Example: non-uniform flash mapped to spiffs with 128kB logical blocks - -PHYSICAL FLASH BLOCKS SPIFFS LOGICAL BLOCKS: 128kB - -+-----------------------+ - - - +-----------------------+ -| Block 1 : 16kB | | Block 1 : 128kB | -+-----------------------+ | | -| Block 2 : 16kB | | | -+-----------------------+ | | -| Block 3 : 16kB | | | -+-----------------------+ | | -| Block 4 : 16kB | | | -+-----------------------+ | | -| Block 5 : 64kB | | | -+-----------------------+ - - - +-----------------------+ -| Block 6 : 64kB | | Block 2 : 128kB | -+-----------------------+ | | -| Block 7 : 64kB | | | -+-----------------------+ - - - +-----------------------+ -| Block 8 : 64kB | | Block 3 : 128kB | -+-----------------------+ | | -| Block 9 : 64kB | | | -+-----------------------+ - - - +-----------------------+ -| ... | | ... | - -A logical block is divided further into a number of logical pages. A page -defines the smallest data holding element known to spiffs. Hence, if a file -is created being one byte big, it will occupy one page for index and one page -for data - it will occupy 2 x size of a logical page on flash. -So it seems it is good to select a small page size. - -Each page has a metadata header being normally 5 to 9 bytes. This said, a very -small page size will make metadata occupy a lot of the memory on the flash. A -page size of 64 bytes will waste 8-14% on metadata, while 256 bytes 2-4%. -So it seems it is good to select a big page size. - -Also, spiffs uses a ram buffer being two times the page size. This ram buffer -is used for loading and manipulating pages, but it is also used for algorithms -to find free file ids, scanning the file system, etc. Having too small a page -size means less work buffer for spiffs, ending up in more reads operations and -eventually gives a slower file system. - -Choosing the page size for the system involves many factors: - - How big is the logical block size - - What is the normal size of most files - - How much ram can be spent - - How much data (vs metadata) must be crammed into the file system - - How fast must spiffs be - - Other things impossible to find out - -So, chosing the Optimal Page Size (tm) seems tricky, to say the least. Don't -fret - there is no optimal page size. This varies from how the target will use -spiffs. Use the golden rule: - - ~~~ Logical Page Size = Logical Block Size / 256 ~~~ - -This is a good starting point. The final page size can then be derived through -heuristical experimenting for us non-analytical minds. - - -** Objects, indices and look-ups - -A file, or an object as called in spiffs, is identified by an object id. -Another YAFFS rip-off. This object id is a part of the page header. So, all -pages know to which object/file they belong - not counting the free pages. - -An object is made up of two types of pages: object index pages and data pages. -Data pages contain the data written by user. Index pages contain metadata about -the object, more specifically what data pages are part of the object. - -The page header also includes something called a span index. Let's say a file -is written covering three data pages. The first data page will then have span -index 0, the second span index 1, and the last data page will have span index -2. Simple as that. - -Finally, each page header contain flags, telling if the page is used, -deleted, finalized, holds index or data, and more. - -Object indices also have span indices, where an object index with span index 0 -is referred to as the object index header. This page does not only contain -references to data pages, but also extra info such as object name, object size -in bytes, flags for file or directory, etc. - -If one were to create a file covering three data pages, named e.g. -"spandex-joke.txt", given object id 12, it could look like this: - -PAGE 0 - -PAGE 1 page header: [obj_id:12 span_ix:0 flags:USED|DATA] - - -PAGE 2 page header: [obj_id:12 span_ix:1 flags:USED|DATA] - - -PAGE 3 page header: [obj_id:545 span_ix:13 flags:USED|DATA] - - -PAGE 4 page header: [obj_id:12 span_ix:2 flags:USED|DATA] - - -PAGE 5 page header: [obj_id:12 span_ix:0 flags:USED|INDEX] - obj ix header: [name:spandex-joke.txt size:600 bytes flags:FILE] - obj ix: [1 2 4] - -Looking in detail at page 5, the object index header page, the object index -array refers to each data page in order, as mentioned before. The index of the -object index array correlates with the data page span index. - - entry ix: 0 1 2 - obj ix: [1 2 4] - | | | - PAGE 1, DATA, SPAN_IX 0 --------/ | | - PAGE 2, DATA, SPAN_IX 1 --------/ | - PAGE 4, DATA, SPAN_IX 2 --------/ - -Things to be unveiled in page 0 - well.. Spiffs is designed for systems low on -ram. We cannot keep a dynamic list on the whereabouts of each object index -header so we can find a file fast. There might not even be a heap! But, we do -not want to scan all page headers on the flash to find the object index header. - -The first page(s) of each block contains the so called object look-up. These -are not normal pages, they do not have a header. Instead, they are arrays -pointing out what object-id the rest of all pages in the block belongs to. - -By this look-up, only the first page(s) in each block must to scanned to find -the actual page which contains the object index header of the desired object. - -The object lookup is redundant metadata. The assumption is that it presents -less overhead reading a full page of data to memory from each block and search -that, instead of reading a small amount of data from each page (i.e. the page -header) in all blocks. Each read operation from SPI flash normally contains -extra data as the read command itself and the flash address. Also, depending on -the underlying implementation, other criterions may need to be passed for each -read transaction, like mutexes and such. - -The veiled example unveiled would look like this, with some extra pages: - -PAGE 0 [ 12 12 545 12 12 34 34 4 0 0 0 0 ...] -PAGE 1 page header: [obj_id:12 span_ix:0 flags:USED|DATA] ... -PAGE 2 page header: [obj_id:12 span_ix:1 flags:USED|DATA] ... -PAGE 3 page header: [obj_id:545 span_ix:13 flags:USED|DATA] ... -PAGE 4 page header: [obj_id:12 span_ix:2 flags:USED|DATA] ... -PAGE 5 page header: [obj_id:12 span_ix:0 flags:USED|INDEX] ... -PAGE 6 page header: [obj_id:34 span_ix:0 flags:USED|DATA] ... -PAGE 7 page header: [obj_id:34 span_ix:1 flags:USED|DATA] ... -PAGE 8 page header: [obj_id:4 span_ix:1 flags:USED|INDEX] ... -PAGE 9 page header: [obj_id:23 span_ix:0 flags:DELETED|INDEX] ... -PAGE 10 page header: [obj_id:23 span_ix:0 flags:DELETED|DATA] ... -PAGE 11 page header: [obj_id:23 span_ix:1 flags:DELETED|DATA] ... -PAGE 12 page header: [obj_id:23 span_ix:2 flags:DELETED|DATA] ... -... - -Ok, so why are page 9 to 12 marked as 0 when they belong to object id 23? These -pages are deleted, so this is marked both in page header flags and in the look -up. This is an example where spiffs uses NOR flashes "nand-way" of writing. - -As a matter of fact, there are two object id's which are special: - -obj id 0 (all bits zeroes) - indicates a deleted page in object look up -obj id 0xff.. (all bits ones) - indicates a free page in object look up - -Actually, the object id's have another quirk: if the most significant bit is -set, this indicates an object index page. If the most significant bit is zero, -this indicates a data page. So to be fully correct, page 0 in above example -would look like this: - -PAGE 0 [ 12 12 545 12 *12 34 34 *4 0 0 0 0 ...] - -where the asterisk means the msb of the object id is set. - -This is another way to speed up the searches when looking for object indices. -By looking on the object id's msb in the object lookup, it is also possible -to find out whether the page is an object index page or a data page. - diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/TODO b/arduino/realtek-ambz/cores/arduino/spiffs/TODO deleted file mode 100644 index c947316a8..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/TODO +++ /dev/null @@ -1,15 +0,0 @@ -* When mending lost pages, also see if they fit into length specified in object index header - -SPIFFS2 thoughts - -* Instead of exact object id:s in the object lookup tables, use a hash of span index and object id. - Eg. object id xor:ed with bit-reversed span index. - This should decrease number of actual pages that needs to be visited when looking thru the obj lut. - -* Logical number of each block. When moving stuff in a garbage collected page, the free - page is assigned the same number as the garbage collected. Thus, object index pages do not have to - be rewritten. - -* Steal one page, use as a bit parity page. When starting an fs modification operation, write one bit - as zero. When ending, write another bit as zero. On mount, if number of zeroes in page is uneven, a - check is automatically run. \ No newline at end of file diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs.h b/arduino/realtek-ambz/cores/arduino/spiffs/spiffs.h deleted file mode 100644 index c625d9315..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs.h +++ /dev/null @@ -1,681 +0,0 @@ -/* - * spiffs.h - * - * Created on: May 26, 2013 - * Author: petera - */ - -#ifndef SPIFFS_H_ -#define SPIFFS_H_ -#if defined(__cplusplus) -extern "C" { -#endif - -#include "spiffs_config.h" - -#define SPIFFS_OK 0 -#define SPIFFS_ERR_NOT_MOUNTED -10000 -#define SPIFFS_ERR_FULL -10001 -#define SPIFFS_ERR_NOT_FOUND -10002 -#define SPIFFS_ERR_END_OF_OBJECT -10003 -#define SPIFFS_ERR_DELETED -10004 -#define SPIFFS_ERR_NOT_FINALIZED -10005 -#define SPIFFS_ERR_NOT_INDEX -10006 -#define SPIFFS_ERR_OUT_OF_FILE_DESCS -10007 -#define SPIFFS_ERR_FILE_CLOSED -10008 -#define SPIFFS_ERR_FILE_DELETED -10009 -#define SPIFFS_ERR_BAD_DESCRIPTOR -10010 -#define SPIFFS_ERR_IS_INDEX -10011 -#define SPIFFS_ERR_IS_FREE -10012 -#define SPIFFS_ERR_INDEX_SPAN_MISMATCH -10013 -#define SPIFFS_ERR_DATA_SPAN_MISMATCH -10014 -#define SPIFFS_ERR_INDEX_REF_FREE -10015 -#define SPIFFS_ERR_INDEX_REF_LU -10016 -#define SPIFFS_ERR_INDEX_REF_INVALID -10017 -#define SPIFFS_ERR_INDEX_FREE -10018 -#define SPIFFS_ERR_INDEX_LU -10019 -#define SPIFFS_ERR_INDEX_INVALID -10020 -#define SPIFFS_ERR_NOT_WRITABLE -10021 -#define SPIFFS_ERR_NOT_READABLE -10022 -#define SPIFFS_ERR_CONFLICTING_NAME -10023 -#define SPIFFS_ERR_NOT_CONFIGURED -10024 - -#define SPIFFS_ERR_NOT_A_FS -10025 -#define SPIFFS_ERR_MOUNTED -10026 -#define SPIFFS_ERR_ERASE_FAIL -10027 -#define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028 - -#define SPIFFS_ERR_NO_DELETED_BLOCKS -10029 - -#define SPIFFS_ERR_FILE_EXISTS -10030 - -#define SPIFFS_ERR_NOT_A_FILE -10031 -#define SPIFFS_ERR_RO_NOT_IMPL -10032 -#define SPIFFS_ERR_RO_ABORTED_OPERATION -10033 -#define SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS -10034 -#define SPIFFS_ERR_PROBE_NOT_A_FS -10035 -#define SPIFFS_ERR_INTERNAL -10050 - -#define SPIFFS_ERR_TEST -10100 - - -// spiffs file descriptor index type. must be signed -typedef s16_t spiffs_file; -// spiffs file descriptor flags -typedef u16_t spiffs_flags; -// spiffs file mode -typedef u16_t spiffs_mode; -// object type -typedef u8_t spiffs_obj_type; - -struct spiffs_t; - -#if SPIFFS_HAL_CALLBACK_EXTRA - -/* spi read call function type */ -typedef s32_t (*spiffs_read)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *dst); -/* spi write call function type */ -typedef s32_t (*spiffs_write)(struct spiffs_t *fs, u32_t addr, u32_t size, u8_t *src); -/* spi erase call function type */ -typedef s32_t (*spiffs_erase)(struct spiffs_t *fs, u32_t addr, u32_t size); - -#else // SPIFFS_HAL_CALLBACK_EXTRA - -/* spi read call function type */ -typedef s32_t (*spiffs_read)(u32_t addr, u32_t size, u8_t *dst); -/* spi write call function type */ -typedef s32_t (*spiffs_write)(u32_t addr, u32_t size, u8_t *src); -/* spi erase call function type */ -typedef s32_t (*spiffs_erase)(u32_t addr, u32_t size); -#endif // SPIFFS_HAL_CALLBACK_EXTRA - -/* file system check callback report operation */ -typedef enum { - SPIFFS_CHECK_LOOKUP = 0, - SPIFFS_CHECK_INDEX, - SPIFFS_CHECK_PAGE -} spiffs_check_type; - -/* file system check callback report type */ -typedef enum { - SPIFFS_CHECK_PROGRESS = 0, - SPIFFS_CHECK_ERROR, - SPIFFS_CHECK_FIX_INDEX, - SPIFFS_CHECK_FIX_LOOKUP, - SPIFFS_CHECK_DELETE_ORPHANED_INDEX, - SPIFFS_CHECK_DELETE_PAGE, - SPIFFS_CHECK_DELETE_BAD_FILE, -} spiffs_check_report; - -/* file system check callback function */ -#if SPIFFS_HAL_CALLBACK_EXTRA -typedef void (*spiffs_check_callback)(struct spiffs_t *fs, spiffs_check_type type, spiffs_check_report report, - u32_t arg1, u32_t arg2); -#else // SPIFFS_HAL_CALLBACK_EXTRA -typedef void (*spiffs_check_callback)(spiffs_check_type type, spiffs_check_report report, - u32_t arg1, u32_t arg2); -#endif // SPIFFS_HAL_CALLBACK_EXTRA - -/* file system listener callback operation */ -typedef enum { - /* the file has been created */ - SPIFFS_CB_CREATED = 0, - /* the file has been updated or moved to another page */ - SPIFFS_CB_UPDATED, - /* the file has been deleted */ - SPIFFS_CB_DELETED, -} spiffs_fileop_type; - -/* file system listener callback function */ -typedef void (*spiffs_file_callback)(struct spiffs_t *fs, spiffs_fileop_type op, spiffs_obj_id obj_id, spiffs_page_ix pix); - -#ifndef SPIFFS_DBG -#define SPIFFS_DBG(...) \ - print(__VA_ARGS__) -#endif -#ifndef SPIFFS_GC_DBG -#define SPIFFS_GC_DBG(...) printf(__VA_ARGS__) -#endif -#ifndef SPIFFS_CACHE_DBG -#define SPIFFS_CACHE_DBG(...) printf(__VA_ARGS__) -#endif -#ifndef SPIFFS_CHECK_DBG -#define SPIFFS_CHECK_DBG(...) printf(__VA_ARGS__) -#endif - -/* Any write to the filehandle is appended to end of the file */ -#define SPIFFS_APPEND (1<<0) -/* If the opened file exists, it will be truncated to zero length before opened */ -#define SPIFFS_TRUNC (1<<1) -/* If the opened file does not exist, it will be created before opened */ -#define SPIFFS_CREAT (1<<2) -/* The opened file may only be read */ -#define SPIFFS_RDONLY (1<<3) -/* The opened file may only be writted */ -#define SPIFFS_WRONLY (1<<4) -/* The opened file may be both read and writted */ -#define SPIFFS_RDWR (SPIFFS_RDONLY | SPIFFS_WRONLY) -/* Any writes to the filehandle will never be cached */ -#define SPIFFS_DIRECT (1<<5) -/* If SPIFFS_CREAT and SPIFFS_EXCL are set, SPIFFS_open() shall fail if the file exists */ -#define SPIFFS_EXCL (1<<6) - -#define SPIFFS_SEEK_SET (0) -#define SPIFFS_SEEK_CUR (1) -#define SPIFFS_SEEK_END (2) - -#define SPIFFS_TYPE_FILE (1) -#define SPIFFS_TYPE_DIR (2) -#define SPIFFS_TYPE_HARD_LINK (3) -#define SPIFFS_TYPE_SOFT_LINK (4) - -#ifndef SPIFFS_LOCK -#define SPIFFS_LOCK(fs) -#endif - -#ifndef SPIFFS_UNLOCK -#define SPIFFS_UNLOCK(fs) -#endif - -// phys structs - -// spiffs spi configuration struct -typedef struct { - // physical read function - spiffs_read hal_read_f; - // physical write function - spiffs_write hal_write_f; - // physical erase function - spiffs_erase hal_erase_f; -#if SPIFFS_SINGLETON == 0 - // physical size of the spi flash - u32_t phys_size; - // physical offset in spi flash used for spiffs, - // must be on block boundary - u32_t phys_addr; - // physical size when erasing a block - u32_t phys_erase_block; - - // logical size of a block, must be on physical - // block size boundary and must never be less than - // a physical block - u32_t log_block_size; - // logical size of a page, must be at least - // log_block_size / 8 - u32_t log_page_size; - -#endif -#if SPIFFS_FILEHDL_OFFSET - // an integer offset added to each file handle - u16_t fh_ix_offset; -#endif -} spiffs_config; - -typedef struct spiffs_t { - // file system configuration - spiffs_config cfg; - // number of logical blocks - u32_t block_count; - - // cursor for free blocks, block index - spiffs_block_ix free_cursor_block_ix; - // cursor for free blocks, entry index - int free_cursor_obj_lu_entry; - // cursor when searching, block index - spiffs_block_ix cursor_block_ix; - // cursor when searching, entry index - int cursor_obj_lu_entry; - - // primary work buffer, size of a logical page - u8_t *lu_work; - // secondary work buffer, size of a logical page - u8_t *work; - // file descriptor memory area - u8_t *fd_space; - // available file descriptors - u32_t fd_count; - - // last error - s32_t err_code; - - // current number of free blocks - u32_t free_blocks; - // current number of busy pages - u32_t stats_p_allocated; - // current number of deleted pages - u32_t stats_p_deleted; - // flag indicating that garbage collector is cleaning - u8_t cleaning; - // max erase count amongst all blocks - spiffs_obj_id max_erase_count; - -#if SPIFFS_GC_STATS - u32_t stats_gc_runs; -#endif - -#if SPIFFS_CACHE - // cache memory - void *cache; - // cache size - u32_t cache_size; -#if SPIFFS_CACHE_STATS - u32_t cache_hits; - u32_t cache_misses; -#endif -#endif - - // check callback function - spiffs_check_callback check_cb_f; - // file callback function - spiffs_file_callback file_cb_f; - // mounted flag - u8_t mounted; - // user data - void *user_data; - // config magic - u32_t config_magic; -} spiffs; - -/* spiffs file status struct */ -typedef struct { - spiffs_obj_id obj_id; - u32_t size; - spiffs_obj_type type; - spiffs_page_ix pix; - u8_t name[SPIFFS_OBJ_NAME_LEN]; -} spiffs_stat; - -struct spiffs_dirent { - spiffs_obj_id obj_id; - u8_t name[SPIFFS_OBJ_NAME_LEN]; - spiffs_obj_type type; - u32_t size; - spiffs_page_ix pix; -}; - -typedef struct { - spiffs *fs; - spiffs_block_ix block; - int entry; -} spiffs_DIR; - -// functions - -#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 -/** - * Special function. This takes a spiffs config struct and returns the number - * of blocks this file system was formatted with. This function relies on - * that following info is set correctly in given config struct: - * - * phys_addr, log_page_size, and log_block_size. - * - * Also, hal_read_f must be set in the config struct. - * - * One must be sure of the correct page size and that the physical address is - * correct in the probed file system when calling this function. It is not - * checked if the phys_addr actually points to the start of the file system, - * so one might get a false positive if entering a phys_addr somewhere in the - * middle of the file system at block boundary. In addition, it is not checked - * if the page size is actually correct. If it is not, weird file system sizes - * will be returned. - * - * If this function detects a file system it returns the assumed file system - * size, which can be used to set the phys_size. - * - * Otherwise, it returns an error indicating why it is not regarded as a file - * system. - * - * Note: this function is not protected with SPIFFS_LOCK and SPIFFS_UNLOCK - * macros. It returns the error code directly, instead of as read by - * SPIFFS_errno. - * - * @param config essential parts of the physical and logical - * configuration of the file system. - */ -s32_t SPIFFS_probe_fs(spiffs_config *config); -#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 - -/** - * Initializes the file system dynamic parameters and mounts the filesystem. - * If SPIFFS_USE_MAGIC is enabled the mounting may fail with SPIFFS_ERR_NOT_A_FS - * if the flash does not contain a recognizable file system. - * In this case, SPIFFS_format must be called prior to remounting. - * @param fs the file system struct - * @param config the physical and logical configuration of the file system - * @param work a memory work buffer comprising 2*config->log_page_size - * bytes used throughout all file system operations - * @param fd_space memory for file descriptors - * @param fd_space_size memory size of file descriptors - * @param cache memory for cache, may be null - * @param cache_size memory size of cache - * @param check_cb_f callback function for reporting during consistency checks - */ -s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, - u8_t *fd_space, u32_t fd_space_size, - void *cache, u32_t cache_size, - spiffs_check_callback check_cb_f); - -/** - * Unmounts the file system. All file handles will be flushed of any - * cached writes and closed. - * @param fs the file system struct - */ -void SPIFFS_unmount(spiffs *fs); - -/** - * Creates a new file. - * @param fs the file system struct - * @param path the path of the new file - * @param mode ignored, for posix compliance - */ -s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode); - -/** - * Opens/creates a file. - * @param fs the file system struct - * @param path the path of the new file - * @param flags the flags for the open command, can be combinations of - * SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY, - * SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT - * @param mode ignored, for posix compliance - */ -spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode); - -/** - * Opens a file by given dir entry. - * Optimization purposes, when traversing a file system with SPIFFS_readdir - * a normal SPIFFS_open would need to traverse the filesystem again to find - * the file, whilst SPIFFS_open_by_dirent already knows where the file resides. - * @param fs the file system struct - * @param e the dir entry to the file - * @param flags the flags for the open command, can be combinations of - * SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY, - * SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT. - * SPIFFS_CREAT will have no effect in this case. - * @param mode ignored, for posix compliance - */ -spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode); - -/** - * Opens a file by given page index. - * Optimization purposes, opens a file by directly pointing to the page - * index in the spi flash. - * If the page index does not point to a file header SPIFFS_ERR_NOT_A_FILE - * is returned. - * @param fs the file system struct - * @param page_ix the page index - * @param flags the flags for the open command, can be combinations of - * SPIFFS_APPEND, SPIFFS_TRUNC, SPIFFS_CREAT, SPIFFS_RD_ONLY, - * SPIFFS_WR_ONLY, SPIFFS_RDWR, SPIFFS_DIRECT. - * SPIFFS_CREAT will have no effect in this case. - * @param mode ignored, for posix compliance - */ -spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode); - -/** - * Reads from given filehandle. - * @param fs the file system struct - * @param fh the filehandle - * @param buf where to put read data - * @param len how much to read - * @returns number of bytes read, or -1 if error - */ -s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len); - -/** - * Writes to given filehandle. - * @param fs the file system struct - * @param fh the filehandle - * @param buf the data to write - * @param len how much to write - * @returns number of bytes written, or -1 if error - */ -s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len); - -/** - * Moves the read/write file offset. Resulting offset is returned or negative if error. - * lseek(fs, fd, 0, SPIFFS_SEEK_CUR) will thus return current offset. - * @param fs the file system struct - * @param fh the filehandle - * @param offs how much/where to move the offset - * @param whence if SPIFFS_SEEK_SET, the file offset shall be set to offset bytes - * if SPIFFS_SEEK_CUR, the file offset shall be set to its current location plus offset - * if SPIFFS_SEEK_END, the file offset shall be set to the size of the file plus offse, which should be negative - */ -s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence); - -/** - * Removes a file by path - * @param fs the file system struct - * @param path the path of the file to remove - */ -s32_t SPIFFS_remove(spiffs *fs, const char *path); - -/** - * Removes a file by filehandle - * @param fs the file system struct - * @param fh the filehandle of the file to remove - */ -s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh); - -/** - * Gets file status by path - * @param fs the file system struct - * @param path the path of the file to stat - * @param s the stat struct to populate - */ -s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s); - -/** - * Gets file status by filehandle - * @param fs the file system struct - * @param fh the filehandle of the file to stat - * @param s the stat struct to populate - */ -s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s); - -/** - * Flushes all pending write operations from cache for given file - * @param fs the file system struct - * @param fh the filehandle of the file to flush - */ -s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh); - -/** - * Closes a filehandle. If there are pending write operations, these are finalized before closing. - * @param fs the file system struct - * @param fh the filehandle of the file to close - */ -s32_t SPIFFS_close(spiffs *fs, spiffs_file fh); - -/** - * Renames a file - * @param fs the file system struct - * @param old path of file to rename - * @param newPath new path of file - */ -s32_t SPIFFS_rename(spiffs *fs, const char *old, const char *newPath); - -/** - * Returns last error of last file operation. - * @param fs the file system struct - */ -s32_t SPIFFS_errno(spiffs *fs); - -/** - * Clears last error. - * @param fs the file system struct - */ -void SPIFFS_clearerr(spiffs *fs); - -/** - * Opens a directory stream corresponding to the given name. - * The stream is positioned at the first entry in the directory. - * On hydrogen builds the name argument is ignored as hydrogen builds always correspond - * to a flat file structure - no directories. - * @param fs the file system struct - * @param name the name of the directory - * @param d pointer the directory stream to be populated - */ -spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d); - -/** - * Closes a directory stream - * @param d the directory stream to close - */ -s32_t SPIFFS_closedir(spiffs_DIR *d); - -/** - * Reads a directory into given spifs_dirent struct. - * @param d pointer to the directory stream - * @param e the dirent struct to be populated - * @returns null if error or end of stream, else given dirent is returned - */ -struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e); - -/** - * Runs a consistency check on given filesystem. - * @param fs the file system struct - */ -s32_t SPIFFS_check(spiffs *fs); - -/** - * Returns number of total bytes available and number of used bytes. - * This is an estimation, and depends on if there a many files with little - * data or few files with much data. - * NB: If used number of bytes exceeds total bytes, a SPIFFS_check should - * run. This indicates a power loss in midst of things. In worst case - * (repeated powerlosses in mending or gc) you might have to delete some files. - * - * @param fs the file system struct - * @param total total number of bytes in filesystem - * @param used used number of bytes in filesystem - */ -s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used); - -/** - * Formats the entire file system. All data will be lost. - * The filesystem must not be mounted when calling this. - * - * NB: formatting is awkward. Due to backwards compatibility, SPIFFS_mount - * MUST be called prior to formatting in order to configure the filesystem. - * If SPIFFS_mount succeeds, SPIFFS_unmount must be called before calling - * SPIFFS_format. - * If SPIFFS_mount fails, SPIFFS_format can be called directly without calling - * SPIFFS_unmount first. - * - * @param fs the file system struct - */ -s32_t SPIFFS_format(spiffs *fs); - -/** - * Returns nonzero if spiffs is mounted, or zero if unmounted. - * @param fs the file system struct - */ -u8_t SPIFFS_mounted(spiffs *fs); - -/** - * Tries to find a block where most or all pages are deleted, and erase that - * block if found. Does not care for wear levelling. Will not move pages - * around. - * If parameter max_free_pages are set to 0, only blocks with only deleted - * pages will be selected. - * - * NB: the garbage collector is automatically called when spiffs needs free - * pages. The reason for this function is to give possibility to do background - * tidying when user knows the system is idle. - * - * Use with care. - * - * Setting max_free_pages to anything larger than zero will eventually wear - * flash more as a block containing free pages can be erased. - * - * Will set err_no to SPIFFS_OK if a block was found and erased, - * SPIFFS_ERR_NO_DELETED_BLOCK if no matching block was found, - * or other error. - * - * @param fs the file system struct - * @param max_free_pages maximum number allowed free pages in block - */ -s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages); - -/** - * Will try to make room for given amount of bytes in the filesystem by moving - * pages and erasing blocks. - * If it is physically impossible, err_no will be set to SPIFFS_ERR_FULL. If - * there already is this amount (or more) of free space, SPIFFS_gc will - * silently return. It is recommended to call SPIFFS_info before invoking - * this method in order to determine what amount of bytes to give. - * - * NB: the garbage collector is automatically called when spiffs needs free - * pages. The reason for this function is to give possibility to do background - * tidying when user knows the system is idle. - * - * Use with care. - * - * @param fs the file system struct - * @param size amount of bytes that should be freed - */ -s32_t SPIFFS_gc(spiffs *fs, u32_t size); - -/** - * Check if EOF reached. - * @param fs the file system struct - * @param fh the filehandle of the file to check - */ -s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh); - -/** - * Get position in file. - * @param fs the file system struct - * @param fh the filehandle of the file to check - */ -s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh); - -/** - * Registers a callback function that keeps track on operations on file - * headers. Do note, that this callback is called from within internal spiffs - * mechanisms. Any operations on the actual file system being callbacked from - * in this callback will mess things up for sure - do not do this. - * This can be used to track where files are and move around during garbage - * collection, which in turn can be used to build location tables in ram. - * Used in conjuction with SPIFFS_open_by_page this may improve performance - * when opening a lot of files. - * Must be invoked after mount. - * - * @param fs the file system struct - * @param cb_func the callback on file operations - */ -s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func); - -#if SPIFFS_TEST_VISUALISATION -/** - * Prints out a visualization of the filesystem. - * @param fs the file system struct - */ -s32_t SPIFFS_vis(spiffs *fs); -#endif - -#if SPIFFS_BUFFER_HELP -/** - * Returns number of bytes needed for the filedescriptor buffer given - * amount of file descriptors. - */ -u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs); - -#if SPIFFS_CACHE -/** - * Returns number of bytes needed for the cache buffer given - * amount of cache pages. - */ -u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages); -#endif -#endif - -#if SPIFFS_CACHE -#endif -#if defined(__cplusplus) -} -#endif - -#endif /* SPIFFS_H_ */ diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_cache.c b/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_cache.c deleted file mode 100644 index ea9bc82c5..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_cache.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - * spiffs_cache.c - * - * Created on: Jun 23, 2013 - * Author: petera - */ - -#include "spiffs.h" -#include "spiffs_nucleus.h" - -#if SPIFFS_CACHE - -// returns cached page for give page index, or null if no such cached page -static spiffs_cache_page *spiffs_cache_page_get(spiffs *fs, spiffs_page_ix pix) { - spiffs_cache *cache = spiffs_get_cache(fs); - if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) return 0; - int i; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && - cp->pix == pix ) { - SPIFFS_CACHE_DBG("CACHE_GET: have cache page %i for %04x\n", i, pix); - cp->last_access = cache->last_access; - return cp; - } - } - //SPIFFS_CACHE_DBG("CACHE_GET: no cache for %04x\n", pix); - return 0; -} - -// frees cached page -static s32_t spiffs_cache_page_free(spiffs *fs, int ix, u8_t write_back) { - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, ix); - if (cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) == 0 && - (cp->flags & SPIFFS_CACHE_FLAG_DIRTY)) { - u8_t *mem = spiffs_get_cache_page(fs, cache, ix); - res = SPIFFS_HAL_WRITE(fs, SPIFFS_PAGE_TO_PADDR(fs, cp->pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), mem); - } - - cp->flags = 0; - cache->cpage_use_map &= ~(1 << ix); - - if (cp->flags & SPIFFS_CACHE_FLAG_TYPE_WR) { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i objid %04x\n", ix, cp->obj_id); - } else { - SPIFFS_CACHE_DBG("CACHE_FREE: free cache page %i pix %04x\n", ix, cp->pix); - } - } - - return res; -} - -// removes the oldest accessed cached page -static s32_t spiffs_cache_page_remove_oldest(spiffs *fs, u8_t flag_mask, u8_t flags) { - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); - - if ((cache->cpage_use_map & cache->cpage_use_mask) != cache->cpage_use_mask) { - // at least one free cpage - return SPIFFS_OK; - } - - // all busy, scan thru all to find the cpage which has oldest access - int i; - int cand_ix = -1; - u32_t oldest_val = 0; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->last_access - cp->last_access) > oldest_val && - (cp->flags & flag_mask) == flags) { - oldest_val = cache->last_access - cp->last_access; - cand_ix = i; - } - } - - if (cand_ix >= 0) { - res = spiffs_cache_page_free(fs, cand_ix, 1); - } - - return res; -} - -// allocates a new cached page and returns it, or null if all cache pages are busy -static spiffs_cache_page *spiffs_cache_page_allocate(spiffs *fs) { - spiffs_cache *cache = spiffs_get_cache(fs); - if (cache->cpage_use_map == 0xffffffff) { - // out of cache memory - return 0; - } - int i; - for (i = 0; i < cache->cpage_count; i++) { - if ((cache->cpage_use_map & (1<cpage_use_map |= (1<last_access = cache->last_access; - SPIFFS_CACHE_DBG("CACHE_ALLO: allocated cache page %i\n", i); - return cp; - } - } - // out of cache entries - return 0; -} - -// drops the cache page for give page index -void spiffs_cache_drop_page(spiffs *fs, spiffs_page_ix pix) { - spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); - if (cp) { - spiffs_cache_page_free(fs, cp->ix, 0); - } -} - -// ------------------------------ - -// reads from spi flash or the cache -s32_t spiffs_phys_rd( - spiffs *fs, - u8_t op, - spiffs_file fh, - u32_t addr, - u32_t len, - u8_t *dst) { - (void)fh; - s32_t res = SPIFFS_OK; - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_cache_page_get(fs, SPIFFS_PADDR_TO_PAGE(fs, addr)); - cache->last_access++; - if (cp) { -#if SPIFFS_CACHE_STATS - fs->cache_hits++; -#endif - cp->last_access = cache->last_access; - } else { - if ((op & SPIFFS_OP_TYPE_MASK) == SPIFFS_OP_T_OBJ_LU2) { - // for second layer lookup functions, we do not cache in order to prevent shredding - return SPIFFS_HAL_READ(fs, addr, len, dst); - } -#if SPIFFS_CACHE_STATS - fs->cache_misses++; -#endif - res = spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); - cp = spiffs_cache_page_allocate(fs); - if (cp) { - cp->flags = SPIFFS_CACHE_FLAG_WRTHRU; - cp->pix = SPIFFS_PADDR_TO_PAGE(fs, addr); - } - s32_t res2 = SPIFFS_HAL_READ(fs, - addr - SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr), - SPIFFS_CFG_LOG_PAGE_SZ(fs), - spiffs_get_cache_page(fs, cache, cp->ix)); - if (res2 != SPIFFS_OK) { - res = res2; - } - } - u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - memcpy(dst, &mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], len); - return res; -} - -// writes to spi flash and/or the cache -s32_t spiffs_phys_wr( - spiffs *fs, - u8_t op, - spiffs_file fh, - u32_t addr, - u32_t len, - u8_t *src) { - (void)fh; - spiffs_page_ix pix = SPIFFS_PADDR_TO_PAGE(fs, addr); - spiffs_cache *cache = spiffs_get_cache(fs); - spiffs_cache_page *cp = spiffs_cache_page_get(fs, pix); - - if (cp && (op & SPIFFS_OP_COM_MASK) != SPIFFS_OP_C_WRTHRU) { - // have a cache page - // copy in data to cache page - - if ((op & SPIFFS_OP_COM_MASK) == SPIFFS_OP_C_DELE && - (op & SPIFFS_OP_TYPE_MASK) != SPIFFS_OP_T_OBJ_LU) { - // page is being deleted, wipe from cache - unless it is a lookup page - spiffs_cache_page_free(fs, cp->ix, 0); - return SPIFFS_HAL_WRITE(fs, addr, len, src); - } - - u8_t *mem = spiffs_get_cache_page(fs, cache, cp->ix); - memcpy(&mem[SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr)], src, len); - - cache->last_access++; - cp->last_access = cache->last_access; - - if (cp->flags & SPIFFS_CACHE_FLAG_WRTHRU) { - // page is being updated, no write-cache, just pass thru - return SPIFFS_HAL_WRITE(fs, addr, len, src); - } else { - return SPIFFS_OK; - } - } else { - // no cache page, no write cache - just write thru - return SPIFFS_HAL_WRITE(fs, addr, len, src); - } -} - -#if SPIFFS_CACHE_WR -// returns the cache page that this fd refers, or null if no cache page -spiffs_cache_page *spiffs_cache_page_get_by_fd(spiffs *fs, spiffs_fd *fd) { - spiffs_cache *cache = spiffs_get_cache(fs); - - if ((cache->cpage_use_map & cache->cpage_use_mask) == 0) { - // all cpages free, no cpage cannot be assigned to obj_id - return 0; - } - - int i; - for (i = 0; i < cache->cpage_count; i++) { - spiffs_cache_page *cp = spiffs_get_cache_page_hdr(fs, cache, i); - if ((cache->cpage_use_map & (1<flags & SPIFFS_CACHE_FLAG_TYPE_WR) && - cp->obj_id == fd->obj_id) { - return cp; - } - } - - return 0; -} - -// allocates a new cache page and refers this to given fd - flushes an old cache -// page if all cache is busy -spiffs_cache_page *spiffs_cache_page_allocate_by_fd(spiffs *fs, spiffs_fd *fd) { - // before this function is called, it is ensured that there is no already existing - // cache page with same object id - spiffs_cache_page_remove_oldest(fs, SPIFFS_CACHE_FLAG_TYPE_WR, 0); - spiffs_cache_page *cp = spiffs_cache_page_allocate(fs); - if (cp == 0) { - // could not get cache page - return 0; - } - - cp->flags = SPIFFS_CACHE_FLAG_TYPE_WR; - cp->obj_id = fd->obj_id; - fd->cache_page = cp; - return cp; -} - -// unrefers all fds that this cache page refers to and releases the cache page -void spiffs_cache_fd_release(spiffs *fs, spiffs_cache_page *cp) { - if (cp == 0) return; - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr != 0 && cur_fd->cache_page == cp) { - cur_fd->cache_page = 0; - } - } - spiffs_cache_page_free(fs, cp->ix, 0); - - cp->obj_id = 0; -} - -#endif - -// initializes the cache -void spiffs_cache_init(spiffs *fs) { - if (fs->cache == 0) return; - u32_t sz = fs->cache_size; - u32_t cache_mask = 0; - int i; - int cache_entries = - (sz - sizeof(spiffs_cache)) / (SPIFFS_CACHE_PAGE_SIZE(fs)); - if (cache_entries <= 0) return; - - for (i = 0; i < cache_entries; i++) { - cache_mask <<= 1; - cache_mask |= 1; - } - - spiffs_cache cache; - memset(&cache, 0, sizeof(spiffs_cache)); - cache.cpage_count = cache_entries; - cache.cpages = (u8_t *)((u8_t *)fs->cache + sizeof(spiffs_cache)); - - cache.cpage_use_map = 0xffffffff; - cache.cpage_use_mask = cache_mask; - memcpy(fs->cache, &cache, sizeof(spiffs_cache)); - - spiffs_cache *c = spiffs_get_cache(fs); - - memset(c->cpages, 0, c->cpage_count * SPIFFS_CACHE_PAGE_SIZE(fs)); - - c->cpage_use_map &= ~(c->cpage_use_mask); - for (i = 0; i < cache.cpage_count; i++) { - spiffs_get_cache_page_hdr(fs, c, i)->ix = i; - } -} - -#endif // SPIFFS_CACHE diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_check.c b/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_check.c deleted file mode 100644 index 8dd6665bd..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_check.c +++ /dev/null @@ -1,995 +0,0 @@ -/* - * spiffs_check.c - * - * Contains functionality for checking file system consistency - * and mending problems. - * Three levels of consistency checks are implemented: - * - * Look up consistency - * Checks if indices in lookup pages are coherent with page headers - * Object index consistency - * Checks if there are any orphaned object indices (missing object index headers). - * If an object index is found but not its header, the object index is deleted. - * This is critical for the following page consistency check. - * Page consistency - * Checks for pages that ought to be indexed, ought not to be indexed, are multiple indexed - * - * - * Created on: Jul 7, 2013 - * Author: petera - */ - - -#include "spiffs.h" -#include "spiffs_nucleus.h" - -#if !SPIFFS_READ_ONLY - -#if SPIFFS_HAL_CALLBACK_EXTRA -#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ - do { \ - if ((_fs)->check_cb_f) (_fs)->check_cb_f((_fs), (_type), (_rep), (_arg1), (_arg2)); \ - } while (0) -#else -#define CHECK_CB(_fs, _type, _rep, _arg1, _arg2) \ - do { \ - if ((_fs)->check_cb_f) (_fs)->check_cb_f((_type), (_rep), (_arg1), (_arg2)); \ - } while (0) -#endif - -//--------------------------------------- -// Look up consistency - -// searches in the object indices and returns the referenced page index given -// the object id and the data span index -// destroys fs->lu_work -static s32_t spiffs_object_get_data_page_index_reference( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix data_spix, - spiffs_page_ix *pix, - spiffs_page_ix *objix_pix) { - s32_t res; - - // calculate object index span index for given data page span index - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - - // find obj index for obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, objix_pix); - SPIFFS_CHECK_RES(res); - - // load obj index entry - u32_t addr = SPIFFS_PAGE_TO_PADDR(fs, *objix_pix); - if (objix_spix == 0) { - // get referenced page from object index header - addr += sizeof(spiffs_page_object_ix_header) + data_spix * sizeof(spiffs_page_ix); - } else { - // get referenced page from object index - addr += sizeof(spiffs_page_object_ix) + SPIFFS_OBJ_IX_ENTRY(fs, data_spix) * sizeof(spiffs_page_ix); - } - - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, 0, addr, sizeof(spiffs_page_ix), (u8_t *)pix); - - return res; -} - -// copies page contents to a new page -static s32_t spiffs_rewrite_page(spiffs *fs, spiffs_page_ix cur_pix, spiffs_page_header *p_hdr, spiffs_page_ix *new_pix) { - s32_t res; - res = spiffs_page_allocate_data(fs, p_hdr->obj_id, p_hdr, 0,0,0,0, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, - SPIFFS_PAGE_TO_PADDR(fs, *new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); - return res; -} - -// rewrites the object index for given object id and replaces the -// data page index to a new page index -static s32_t spiffs_rewrite_index(spiffs *fs, spiffs_obj_id obj_id, spiffs_span_ix data_spix, spiffs_page_ix new_data_pix, spiffs_page_ix objix_pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - spiffs_page_ix free_pix; - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - - // calculate object index span index for given data page span index - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (objix_spix == 0) { - // calc index in index header - entry = data_spix; - } else { - // calc entry in index - entry = SPIFFS_OBJ_IX_ENTRY(fs, data_spix); - - } - // load index - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; - - // be ultra safe, double check header against provided data - if (objix_p_hdr->obj_id != obj_id) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_OBJ_ID_MISM; - } - if (objix_p_hdr->span_ix != objix_spix) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_SPIX_MISM; - } - if ((objix_p_hdr->flags & (SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_INDEX | - SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET)) != - (SPIFFS_PH_FLAG_IXDELE | SPIFFS_PH_FLAG_DELET)) { - spiffs_page_delete(fs, free_pix); - return SPIFFS_ERR_CHECK_FLAGS_BAD; - } - - // rewrite in mem - if (objix_spix == 0) { - ((spiffs_page_ix*)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; - } else { - ((spiffs_page_ix*)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; - } - - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&obj_id); - SPIFFS_CHECK_RES(res); - res = spiffs_page_delete(fs, objix_pix); - - return res; -} - -// deletes an object just by marking object index header as deleted -static s32_t spiffs_delete_obj_lazy(spiffs *fs, spiffs_obj_id obj_id) { - spiffs_page_ix objix_hdr_pix; - s32_t res; - res = spiffs_obj_lu_find_id_and_span(fs, obj_id, 0, 0, &objix_hdr_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - return SPIFFS_OK; - } - SPIFFS_CHECK_RES(res); - u8_t flags = 0xff & ~SPIFFS_PH_FLAG_IXDELE; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&flags); - return res; -} - -// validates the given look up entry -static s32_t spiffs_lookup_check_validate(spiffs *fs, spiffs_obj_id lu_obj_id, spiffs_page_header *p_hdr, - spiffs_page_ix cur_pix, spiffs_block_ix cur_block, int cur_entry, int *reload_lu) { - (void)cur_block; - (void)cur_entry; - u8_t delete_page = 0; - s32_t res = SPIFFS_OK; - spiffs_page_ix objix_pix; - spiffs_page_ix ref_pix; - // check validity, take actions - if (((lu_obj_id == SPIFFS_OBJ_ID_DELETED) && (p_hdr->flags & SPIFFS_PH_FLAG_DELET)) || - ((lu_obj_id == SPIFFS_OBJ_ID_FREE) && (p_hdr->flags & SPIFFS_PH_FLAG_USED) == 0)) { - // look up entry deleted / free but used in page header - SPIFFS_CHECK_DBG("LU: pix %04x deleted/free in lu but not on page\n", cur_pix); - *reload_lu = 1; - delete_page = 1; - if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { - // header says data page - // data page can be removed if not referenced by some object index - res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; - } else { - SPIFFS_CHECK_RES(res); - if (ref_pix == cur_pix) { - // data page referenced by object index but deleted in lu - // copy page to new place and re-write the object index to new place - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: data page not found elsewhere, rewriting %04x to new page %04x\n", cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - SPIFFS_CHECK_DBG("LU: FIXUP: %04x rewritten to %04x, affected objix_pix %04x\n", cur_pix, new_pix, objix_pix); - res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("LU: FIXUP: index bad %i, cannot mend!\n", res); - res = spiffs_page_delete(fs, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); - } else { - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, p_hdr->obj_id, p_hdr->span_ix); - } - SPIFFS_CHECK_RES(res); - } - } - } else { - // header says index page - // index page can be removed if other index with same obj_id and spanix is found - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, 0); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no such index page found, check for a data page amongst page headers - // lu cannot be trusted - res = spiffs_obj_lu_find_id_and_span_by_phdr(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, 0); - if (res == SPIFFS_OK) { // ignore other errors - // got a data page also, assume lu corruption only, rewrite to new page - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: ix page with data not found elsewhere, rewriting %04x to new page %04x\n", cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - } - } else { - SPIFFS_CHECK_RES(res); - } - } - } - if (lu_obj_id != SPIFFS_OBJ_ID_FREE && lu_obj_id != SPIFFS_OBJ_ID_DELETED) { - // look up entry used - if ((p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG) != (lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG)) { - SPIFFS_CHECK_DBG("LU: pix %04x differ in obj_id lu:%04x ph:%04x\n", cur_pix, lu_obj_id, p_hdr->obj_id); - delete_page = 1; - if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0 || - (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) || - (p_hdr->flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_IXDELE)) == 0) { - // page deleted or not finalized, just remove it - } else { - if (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) { - // if data page, check for reference to this page - res = spiffs_object_get_data_page_index_reference(fs, p_hdr->obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; - } else { - SPIFFS_CHECK_RES(res); - // if found, rewrite page with object id, update index, and delete current - if (ref_pix == cur_pix) { - spiffs_page_ix new_pix; - res = spiffs_rewrite_page(fs, cur_pix, p_hdr, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_rewrite_index(fs, p_hdr->obj_id, p_hdr->span_ix, new_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("LU: FIXUP: index bad %i, cannot mend!\n", res); - res = spiffs_page_delete(fs, new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr->obj_id); - *reload_lu = 1; - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr->obj_id, 0); - } - SPIFFS_CHECK_RES(res); - } - } - } else { - // else if index, check for other pages with both obj_id's and spanix - spiffs_page_ix objix_pix_lu, objix_pix_ph; - // see if other object index page exists for lookup obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_lu); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_lu = 0; - } - SPIFFS_CHECK_RES(res); - // see if other object index exists for page header obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, 0, &objix_pix_ph); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_ph = 0; - } - SPIFFS_CHECK_RES(res); - // if both obj_id's found, just delete current - if (objix_pix_ph == 0 || objix_pix_lu == 0) { - // otherwise try finding first corresponding data pages - spiffs_page_ix data_pix_lu, data_pix_ph; - // see if other data page exists for look up obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_lu); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_lu = 0; - } - SPIFFS_CHECK_RES(res); - // see if other data page exists for page header obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &data_pix_ph); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_ph = 0; - } - SPIFFS_CHECK_RES(res); - - spiffs_page_header new_ph; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL); - new_ph.span_ix = p_hdr->span_ix; - spiffs_page_ix new_pix; - if ((objix_pix_lu && data_pix_lu && data_pix_ph && objix_pix_ph == 0) || - (objix_pix_lu == 0 && data_pix_ph && objix_pix_ph == 0)) { - // got a data page for page header obj id - // rewrite as obj_id_ph - new_ph.obj_id = p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG; - res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); - SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page %04x as %04x to pix %04x\n", cur_pix, new_ph.obj_id, new_pix); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - } else if ((objix_pix_ph && data_pix_ph && data_pix_lu && objix_pix_lu == 0) || - (objix_pix_ph == 0 && data_pix_lu && objix_pix_lu == 0)) { - // got a data page for look up obj id - // rewrite as obj_id_lu - new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; - SPIFFS_CHECK_DBG("LU: FIXUP: rewrite page %04x as %04x\n", cur_pix, new_ph.obj_id); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - res = spiffs_rewrite_page(fs, cur_pix, &new_ph, &new_pix); - SPIFFS_CHECK_RES(res); - *reload_lu = 1; - } else { - // cannot safely do anything - SPIFFS_CHECK_DBG("LU: FIXUP: nothing to do, just delete\n"); - } - } - } - } - } else if (((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX)) || - ((lu_obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0 && (p_hdr->flags & SPIFFS_PH_FLAG_INDEX) == 0)) { - SPIFFS_CHECK_DBG("LU: %04x lu/page index marking differ\n", cur_pix); - spiffs_page_ix data_pix, objix_pix_d; - // see if other data page exists for given obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - // see if other object index exists for given obj id and span index - res = spiffs_obj_lu_find_id_and_span(fs, lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG, p_hdr->span_ix, cur_pix, &objix_pix_d); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - objix_pix_d = 0; - } - SPIFFS_CHECK_RES(res); - - delete_page = 1; - // if other data page exists and object index exists, just delete page - if (data_pix && objix_pix_d) { - SPIFFS_CHECK_DBG("LU: FIXUP: other index and data page exists, simply remove\n"); - } else - // if only data page exists, make this page index - if (data_pix && objix_pix_d == 0) { - SPIFFS_CHECK_DBG("LU: FIXUP: other data page exists, make this index\n"); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_INDEX, lu_obj_id, p_hdr->span_ix); - spiffs_page_header new_ph; - spiffs_page_ix new_pix; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); - new_ph.obj_id = lu_obj_id | SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = p_hdr->span_ix; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); - SPIFFS_CHECK_RES(res); - } else - // if only index exists, make data page - if (data_pix == 0 && objix_pix_d) { - SPIFFS_CHECK_DBG("LU: FIXUP: other index page exists, make this data\n"); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, lu_obj_id, p_hdr->span_ix); - spiffs_page_header new_ph; - spiffs_page_ix new_pix; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); - new_ph.obj_id = lu_obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = p_hdr->span_ix; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &new_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_phys_cpy(fs, 0, SPIFFS_PAGE_TO_PADDR(fs, new_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + sizeof(spiffs_page_header), - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header)); - SPIFFS_CHECK_RES(res); - } else { - // if nothing exists, we cannot safely make a decision - delete - } - } - else if ((p_hdr->flags & SPIFFS_PH_FLAG_DELET) == 0) { - SPIFFS_CHECK_DBG("LU: pix %04x busy in lu but deleted on page\n", cur_pix); - delete_page = 1; - } else if ((p_hdr->flags & SPIFFS_PH_FLAG_FINAL)) { - SPIFFS_CHECK_DBG("LU: pix %04x busy but not final\n", cur_pix); - // page can be removed if not referenced by object index - *reload_lu = 1; - res = spiffs_object_get_data_page_index_reference(fs, lu_obj_id, p_hdr->span_ix, &ref_pix, &objix_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - // no object with this id, so remove page safely - res = SPIFFS_OK; - delete_page = 1; - } else { - SPIFFS_CHECK_RES(res); - if (ref_pix != cur_pix) { - SPIFFS_CHECK_DBG("LU: FIXUP: other finalized page is referred, just delete\n"); - delete_page = 1; - } else { - // page referenced by object index but not final - // just finalize - SPIFFS_CHECK_DBG("LU: FIXUP: unfinalized page is referred, finalizing\n"); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_FIX_LOOKUP, p_hdr->obj_id, p_hdr->span_ix); - u8_t flags = 0xff & ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), (u8_t*)&flags); - } - } - } - } - - if (delete_page) { - SPIFFS_CHECK_DBG("LU: FIXUP: deleting page %04x\n", cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - } - - return res; -} - -static s32_t spiffs_lookup_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, int cur_entry, - const void *user_const_p, void *user_var_p) { - (void)user_const_p; - (void)user_var_p; - s32_t res = SPIFFS_OK; - spiffs_page_header p_hdr; - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); - - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, - (cur_block * 256)/fs->block_count, 0); - - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - int reload_lu = 0; - - res = spiffs_lookup_check_validate(fs, obj_id, &p_hdr, cur_pix, cur_block, cur_entry, &reload_lu); - SPIFFS_CHECK_RES(res); - - if (res == SPIFFS_OK) { - return reload_lu ? SPIFFS_VIS_COUNTINUE_RELOAD : SPIFFS_VIS_COUNTINUE; - } - return res; -} - - -// Scans all object look up. For each entry, corresponding page header is checked for validity. -// If an object index header page is found, this is also checked -s32_t spiffs_lookup_consistency_check(spiffs *fs, u8_t check_all_objects) { - (void)check_all_objects; - s32_t res = SPIFFS_OK; - - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 0, 0); - - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_lookup_check_v, 0, 0, 0, 0); - - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } - - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_ERROR, res, 0); - } - - CHECK_CB(fs, SPIFFS_CHECK_LOOKUP, SPIFFS_CHECK_PROGRESS, 256, 0); - - return res; -} - -//--------------------------------------- -// Page consistency - -// Scans all pages (except lu pages), reserves 4 bits in working memory for each page -// bit 0: 0 == FREE|DELETED, 1 == USED -// bit 1: 0 == UNREFERENCED, 1 == REFERENCED -// bit 2: 0 == NOT_INDEX, 1 == INDEX -// bit 3: unused -// A consistent file system will have only pages being -// * x000 free, unreferenced, not index -// * x011 used, referenced only once, not index -// * x101 used, unreferenced, index -// The working memory might not fit all pages so several scans might be needed -static s32_t spiffs_page_consistency_check_i(spiffs *fs) { - const u32_t bits = 4; - const spiffs_page_ix pages_per_scan = SPIFFS_CFG_LOG_PAGE_SZ(fs) * 8 / bits; - - s32_t res = SPIFFS_OK; - spiffs_page_ix pix_offset = 0; - - // for each range of pages fitting into work memory - while (pix_offset < SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) { - // set this flag to abort all checks and rescan the page range - u8_t restart = 0; - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - - spiffs_block_ix cur_block = 0; - // build consistency bitmap for id range traversing all blocks - while (!restart && cur_block < fs->block_count) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, - (pix_offset*256)/(SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count) + - ((((cur_block * pages_per_scan * 256)/ (SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count))) / fs->block_count), - 0); - // traverse each page except for lookup pages - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_PAGES(fs) + SPIFFS_PAGES_PER_BLOCK(fs) * cur_block; - while (!restart && cur_pix < SPIFFS_PAGES_PER_BLOCK(fs) * (cur_block+1)) { - //if ((cur_pix & 0xff) == 0) - // SPIFFS_CHECK_DBG("PA: processing pix %08x, block %08x of pix %08x, block %08x\n", - // cur_pix, cur_block, SPIFFS_PAGES_PER_BLOCK(fs) * fs->block_count, fs->block_count); - - // read header - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - u8_t within_range = (cur_pix >= pix_offset && cur_pix < pix_offset + pages_per_scan); - const u32_t pix_byte_ix = (cur_pix - pix_offset) / (8/bits); - const u8_t pix_bit_ix = (cur_pix & ((8/bits)-1)) * bits; - - if (within_range && - (p_hdr.flags & SPIFFS_PH_FLAG_DELET) && (p_hdr.flags & SPIFFS_PH_FLAG_USED) == 0) { - // used - fs->work[pix_byte_ix] |= (1<<(pix_bit_ix + 0)); - } - if ((p_hdr.flags & SPIFFS_PH_FLAG_DELET) && - (p_hdr.flags & SPIFFS_PH_FLAG_IXDELE) && - (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) == 0) { - // found non-deleted index - if (within_range) { - fs->work[pix_byte_ix] |= (1<<(pix_bit_ix + 2)); - } - - // load non-deleted index - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - - // traverse index for referenced pages - spiffs_page_ix *object_page_index; - spiffs_page_header *objix_p_hdr = (spiffs_page_header *)fs->lu_work; - - int entries; - int i; - spiffs_span_ix data_spix_offset; - if (p_hdr.span_ix == 0) { - // object header page index - entries = SPIFFS_OBJ_HDR_IX_LEN(fs); - data_spix_offset = 0; - object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix_header)); - } else { - // object page index - entries = SPIFFS_OBJ_IX_LEN(fs); - data_spix_offset = SPIFFS_OBJ_HDR_IX_LEN(fs) + SPIFFS_OBJ_IX_LEN(fs) * (p_hdr.span_ix - 1); - object_page_index = (spiffs_page_ix *)((u8_t *)fs->lu_work + sizeof(spiffs_page_object_ix)); - } - - // for all entries in index - for (i = 0; !restart && i < entries; i++) { - spiffs_page_ix rpix = object_page_index[i]; - u8_t rpix_within_range = rpix >= pix_offset && rpix < pix_offset + pages_per_scan; - - if ((rpix != (spiffs_page_ix)-1 && rpix > SPIFFS_MAX_PAGES(fs)) - || (rpix_within_range && SPIFFS_IS_LOOKUP_PAGE(fs, rpix))) { - - // bad reference - SPIFFS_CHECK_DBG("PA: pix %04x bad pix / LU referenced from page %04x\n", - rpix, cur_pix); - // check for data page elsewhere - spiffs_page_ix data_pix; - res = spiffs_obj_lu_find_id_and_span(fs, objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, 0, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - if (data_pix == 0) { - // if not, allocate free page - spiffs_page_header new_ph; - new_ph.flags = 0xff & ~(SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL); - new_ph.obj_id = objix_p_hdr->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - new_ph.span_ix = data_spix_offset + i; - res = spiffs_page_allocate_data(fs, new_ph.obj_id, &new_ph, 0, 0, 0, 1, &data_pix); - SPIFFS_CHECK_RES(res); - SPIFFS_CHECK_DBG("PA: FIXUP: found no existing data page, created new @ %04x\n", data_pix); - } - // remap index - SPIFFS_CHECK_DBG("PA: FIXUP: rewriting index pix %04x\n", cur_pix); - res = spiffs_rewrite_index(fs, objix_p_hdr->obj_id | SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, data_pix, cur_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend - delete object\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, objix_p_hdr->obj_id, 0); - // delete file - res = spiffs_page_delete(fs, cur_pix); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, objix_p_hdr->obj_id, objix_p_hdr->span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - - } else if (rpix_within_range) { - - // valid reference - // read referenced page header - spiffs_page_header rp_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t*)&rp_hdr); - SPIFFS_CHECK_RES(res); - - // cross reference page header check - if (rp_hdr.obj_id != (p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) || - rp_hdr.span_ix != data_spix_offset + i || - (rp_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED)) != - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_INDEX)) { - SPIFFS_CHECK_DBG("PA: pix %04x has inconsistent page header ix id/span:%04x/%04x, ref id/span:%04x/%04x flags:%02x\n", - rpix, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, data_spix_offset + i, - rp_hdr.obj_id, rp_hdr.span_ix, rp_hdr.flags); - // try finding correct page - spiffs_page_ix data_pix; - res = spiffs_obj_lu_find_id_and_span(fs, p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - data_spix_offset + i, rpix, &data_pix); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - data_pix = 0; - } - SPIFFS_CHECK_RES(res); - if (data_pix == 0) { - // not found, this index is badly borked - SPIFFS_CHECK_DBG("PA: FIXUP: index bad, delete object id %04x\n", p_hdr.obj_id); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - SPIFFS_CHECK_RES(res); - break; - } else { - // found it, so rewrite index - SPIFFS_CHECK_DBG("PA: FIXUP: found correct data pix %04x, rewrite ix pix %04x id %04x\n", - data_pix, cur_pix, p_hdr.obj_id); - res = spiffs_rewrite_index(fs, p_hdr.obj_id, data_spix_offset + i, data_pix, cur_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend!\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - } - } - else { - // mark rpix as referenced - const u32_t rpix_byte_ix = (rpix - pix_offset) / (8/bits); - const u8_t rpix_bit_ix = (rpix & ((8/bits)-1)) * bits; - if (fs->work[rpix_byte_ix] & (1<<(rpix_bit_ix + 1))) { - SPIFFS_CHECK_DBG("PA: pix %04x multiple referenced from page %04x\n", - rpix, cur_pix); - // Here, we should have fixed all broken references - getting this means there - // must be multiple files with same object id. Only solution is to delete - // the object which is referring to this page - SPIFFS_CHECK_DBG("PA: FIXUP: removing object %04x and page %04x\n", - p_hdr.obj_id, cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - SPIFFS_CHECK_RES(res); - // extra precaution, delete this page also - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - restart = 1; - } - fs->work[rpix_byte_ix] |= (1<<(rpix_bit_ix + 1)); - } - } - } // for all index entries - } // found index - - // next page - cur_pix++; - } - // next block - cur_block++; - } - // check consistency bitmap - if (!restart) { - spiffs_page_ix objix_pix; - spiffs_page_ix rpix; - - u32_t byte_ix; - u8_t bit_ix; - for (byte_ix = 0; !restart && byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs); byte_ix++) { - for (bit_ix = 0; !restart && bit_ix < 8/bits; bit_ix ++) { - u8_t bitmask = (fs->work[byte_ix] >> (bit_ix * bits)) & 0x7; - spiffs_page_ix cur_pix = pix_offset + byte_ix * (8/bits) + bit_ix; - - // 000 ok - free, unreferenced, not index - - if (bitmask == 0x1) { - - // 001 - SPIFFS_CHECK_DBG("PA: pix %04x USED, UNREFERENCED, not index\n", cur_pix); - - u8_t rewrite_ix_to_this = 0; - u8_t delete_page = 0; - // check corresponding object index entry - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - res = spiffs_object_get_data_page_index_reference(fs, p_hdr.obj_id, p_hdr.span_ix, - &rpix, &objix_pix); - if (res == SPIFFS_OK) { - if (((rpix == (spiffs_page_ix)-1 || rpix > SPIFFS_MAX_PAGES(fs)) || (SPIFFS_IS_LOOKUP_PAGE(fs, rpix)))) { - // pointing to a bad page altogether, rewrite index to this - rewrite_ix_to_this = 1; - SPIFFS_CHECK_DBG("PA: corresponding ref is bad: %04x, rewrite to this %04x\n", rpix, cur_pix); - } else { - // pointing to something else, check what - spiffs_page_header rp_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, rpix), sizeof(spiffs_page_header), (u8_t*)&rp_hdr); - SPIFFS_CHECK_RES(res); - if (((p_hdr.obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) == rp_hdr.obj_id) && - ((rp_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_FINAL)) == - (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_DELET))) { - // pointing to something else valid, just delete this page then - SPIFFS_CHECK_DBG("PA: corresponding ref is good but different: %04x, delete this %04x\n", rpix, cur_pix); - delete_page = 1; - } else { - // pointing to something weird, update index to point to this page instead - if (rpix != cur_pix) { - SPIFFS_CHECK_DBG("PA: corresponding ref is weird: %04x %s%s%s%s, rewrite this %04x\n", rpix, - (rp_hdr.flags & SPIFFS_PH_FLAG_INDEX) ? "" : "INDEX ", - (rp_hdr.flags & SPIFFS_PH_FLAG_DELET) ? "" : "DELETED ", - (rp_hdr.flags & SPIFFS_PH_FLAG_USED) ? "NOTUSED " : "", - (rp_hdr.flags & SPIFFS_PH_FLAG_FINAL) ? "NOTFINAL " : "", - cur_pix); - rewrite_ix_to_this = 1; - } else { - // should not happen, destined for fubar - } - } - } - } else if (res == SPIFFS_ERR_NOT_FOUND) { - SPIFFS_CHECK_DBG("PA: corresponding ref not found, delete %04x\n", cur_pix); - delete_page = 1; - res = SPIFFS_OK; - } - - if (rewrite_ix_to_this) { - // if pointing to invalid page, redirect index to this page - SPIFFS_CHECK_DBG("PA: FIXUP: rewrite index id %04x data spix %04x to point to this pix: %04x\n", - p_hdr.obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_rewrite_index(fs, p_hdr.obj_id, p_hdr.span_ix, cur_pix, objix_pix); - if (res <= _SPIFFS_ERR_CHECK_FIRST && res > _SPIFFS_ERR_CHECK_LAST) { - // index bad also, cannot mend this file - SPIFFS_CHECK_DBG("PA: FIXUP: index bad %i, cannot mend!\n", res); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_BAD_FILE, p_hdr.obj_id, 0); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - res = spiffs_delete_obj_lazy(fs, p_hdr.obj_id); - } else { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_FIX_INDEX, p_hdr.obj_id, p_hdr.span_ix); - } - SPIFFS_CHECK_RES(res); - restart = 1; - continue; - } else if (delete_page) { - SPIFFS_CHECK_DBG("PA: FIXUP: deleting page %04x\n", cur_pix); - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_DELETE_PAGE, cur_pix, 0); - res = spiffs_page_delete(fs, cur_pix); - } - SPIFFS_CHECK_RES(res); - } - if (bitmask == 0x2) { - - // 010 - SPIFFS_CHECK_DBG("PA: pix %04x FREE, REFERENCED, not index\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } - - // 011 ok - busy, referenced, not index - - if (bitmask == 0x4) { - - // 100 - SPIFFS_CHECK_DBG("PA: pix %04x FREE, unreferenced, INDEX\n", cur_pix); - - // this should never happen, major fubar - } - - // 101 ok - busy, unreferenced, index - - if (bitmask == 0x6) { - - // 110 - SPIFFS_CHECK_DBG("PA: pix %04x FREE, REFERENCED, INDEX\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } - if (bitmask == 0x7) { - - // 111 - SPIFFS_CHECK_DBG("PA: pix %04x USED, REFERENCED, INDEX\n", cur_pix); - - // no op, this should be taken care of when checking valid references - } - } - } - } - - SPIFFS_CHECK_DBG("PA: processed %04x, restart %i\n", pix_offset, restart); - // next page range - if (!restart) { - pix_offset += pages_per_scan; - } - } // while page range not reached end - return res; -} - -// Checks consistency amongst all pages and fixes irregularities -s32_t spiffs_page_consistency_check(spiffs *fs) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 0, 0); - s32_t res = spiffs_page_consistency_check_i(fs); - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_ERROR, res, 0); - } - CHECK_CB(fs, SPIFFS_CHECK_PAGE, SPIFFS_CHECK_PROGRESS, 256, 0); - return res; -} - -//--------------------------------------- -// Object index consistency - -// searches for given object id in temporary object id index, -// returns the index or -1 -static int spiffs_object_index_search(spiffs *fs, spiffs_obj_id obj_id) { - u32_t i; - spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; - obj_id &= ~SPIFFS_OBJ_ID_IX_FLAG; - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id); i++) { - if ((obj_table[i] & ~SPIFFS_OBJ_ID_IX_FLAG) == obj_id) { - return i; - } - } - return -1; -} - -static s32_t spiffs_object_index_consistency_check_v(spiffs *fs, spiffs_obj_id obj_id, spiffs_block_ix cur_block, - int cur_entry, const void *user_const_p, void *user_var_p) { - (void)user_const_p; - s32_t res_c = SPIFFS_VIS_COUNTINUE; - s32_t res = SPIFFS_OK; - u32_t *log_ix = (u32_t*)user_var_p; - spiffs_obj_id *obj_table = (spiffs_obj_id *)fs->work; - - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, - (cur_block * 256)/fs->block_count, 0); - - if (obj_id != SPIFFS_OBJ_ID_FREE && obj_id != SPIFFS_OBJ_ID_DELETED && (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_page_header p_hdr; - spiffs_page_ix cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, cur_block, cur_entry); - - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - - if (p_hdr.span_ix == 0 && - (p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET)) { - SPIFFS_CHECK_DBG("IX: pix %04x, obj id:%04x spix:%04x header not fully deleted - deleting\n", - cur_pix, obj_id, p_hdr.span_ix); - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_PAGE, cur_pix, obj_id); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - return res_c; - } - - if ((p_hdr.flags & (SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - return res_c; - } - - if (p_hdr.span_ix == 0) { - // objix header page, register objid as reachable - int r = spiffs_object_index_search(fs, obj_id); - if (r == -1) { - // not registered, do it - obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - (*log_ix)++; - if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { - *log_ix = 0; - } - } - } else { // span index - // objix page, see if header can be found - int r = spiffs_object_index_search(fs, obj_id); - u8_t delete = 0; - if (r == -1) { - // not in temporary index, try finding it - spiffs_page_ix objix_hdr_pix; - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &objix_hdr_pix); - res_c = SPIFFS_VIS_COUNTINUE_RELOAD; - if (res == SPIFFS_OK) { - // found, register as reachable - obj_table[*log_ix] = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - } else if (res == SPIFFS_ERR_NOT_FOUND) { - // not found, register as unreachable - delete = 1; - obj_table[*log_ix] = obj_id | SPIFFS_OBJ_ID_IX_FLAG; - } else { - SPIFFS_CHECK_RES(res); - } - (*log_ix)++; - if (*log_ix >= SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)) { - *log_ix = 0; - } - } else { - // in temporary index, check reachable flag - if ((obj_table[r] & SPIFFS_OBJ_ID_IX_FLAG)) { - // registered as unreachable - delete = 1; - } - } - - if (delete) { - SPIFFS_CHECK_DBG("IX: FIXUP: pix %04x, obj id:%04x spix:%04x is orphan index - deleting\n", - cur_pix, obj_id, p_hdr.span_ix); - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_DELETE_ORPHANED_INDEX, cur_pix, obj_id); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - } - } // span index - } // valid object index id - - return res_c; -} - -// Removes orphaned and partially deleted index pages. -// Scans for index pages. When an index page is found, corresponding index header is searched for. -// If no such page exists, the index page cannot be reached as no index header exists and must be -// deleted. -s32_t spiffs_object_index_consistency_check(spiffs *fs) { - s32_t res = SPIFFS_OK; - // impl note: - // fs->work is used for a temporary object index memory, listing found object ids and - // indicating whether they can be reached or not. Acting as a fifo if object ids cannot fit. - // In the temporary object index memory, SPIFFS_OBJ_ID_IX_FLAG bit is used to indicate - // a reachable/unreachable object id. - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - u32_t obj_id_log_ix = 0; - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 0, 0); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_object_index_consistency_check_v, &obj_id_log_ix, - 0, 0, 0); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } - if (res != SPIFFS_OK) { - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_ERROR, res, 0); - } - CHECK_CB(fs, SPIFFS_CHECK_INDEX, SPIFFS_CHECK_PROGRESS, 256, 0); - return res; -} - -#endif // !SPIFFS_READ_ONLY diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_config.h b/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_config.h deleted file mode 100644 index 2fe03b1fd..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_config.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * spiffs_config.h - * - * Created on: Jul 3, 2013 - * Author: petera - */ - -#ifndef SPIFFS_CONFIG_H_ -#define SPIFFS_CONFIG_H_ - -#include -#include -#include -#include - -#define c_memcpy memcpy -#define c_printf printf -#define c_memset memset - -typedef int16_t file_t; -typedef int32_t s32_t; -typedef uint32_t u32_t; -typedef int16_t s16_t; -typedef uint16_t u16_t; -typedef int8_t s8_t; -typedef uint8_t u8_t; - -#ifndef SEEK_SET -#define SEEK_SET 0 /* set file offset to offset */ -#endif - -#ifndef SEEK_CUR -#define SEEK_CUR 1 /* set file offset to current plus offset */ -#endif - -#ifndef SEEK_END -#define SEEK_END 2 /* set file offset to EOF plus offset */ -#endif - -#ifndef EOF -#define EOF (-1) -#endif - -// compile time switches - -// Set generic spiffs debug output call. -#ifndef SPIFFS_DBG -#define SPIFFS_DBG(...) //printf(__VA_ARGS__) -#endif -// Set spiffs debug output call for garbage collecting. -#ifndef SPIFFS_GC_DBG -#define SPIFFS_GC_DBG(...) //printf(__VA_ARGS__) -#endif -// Set spiffs debug output call for caching. -#ifndef SPIFFS_CACHE_DBG -#define SPIFFS_CACHE_DBG(...) //printf(__VA_ARGS__) -#endif -// Set spiffs debug output call for system consistency checks. -#ifndef SPIFFS_CHECK_DBG -#define SPIFFS_CHECK_DBG(...) //printf(__VA_ARGS__) -#endif - -// Enable/disable API functions to determine exact number of bytes -// for filedescriptor and cache buffers. Once decided for a configuration, -// this can be disabled to reduce flash. -#ifndef SPIFFS_BUFFER_HELP -#define SPIFFS_BUFFER_HELP 1 -#endif - -// Enables/disable memory read caching of nucleus file system operations. -// If enabled, memory area must be provided for cache in SPIFFS_mount. -#ifndef SPIFFS_CACHE -#define SPIFFS_CACHE 1 -#endif -#if SPIFFS_CACHE -// Enables memory write caching for file descriptors in hydrogen -#ifndef SPIFFS_CACHE_WR -#define SPIFFS_CACHE_WR 1 -#endif - -// Enable/disable statistics on caching. Debug/test purpose only. -#ifndef SPIFFS_CACHE_STATS -#define SPIFFS_CACHE_STATS 0 -#endif -#endif - -// Always check header of each accessed page to ensure consistent state. -// If enabled it will increase number of reads, will increase flash. -#ifndef SPIFFS_PAGE_CHECK -#define SPIFFS_PAGE_CHECK 1 -#endif - -// Define maximum number of gc runs to perform to reach desired free pages. -#ifndef SPIFFS_GC_MAX_RUNS -#define SPIFFS_GC_MAX_RUNS 5 -#endif - -// Enable/disable statistics on gc. Debug/test purpose only. -#ifndef SPIFFS_GC_STATS -#define SPIFFS_GC_STATS 0 -#endif - -// Garbage collecting examines all pages in a block which and sums up -// to a block score. Deleted pages normally gives positive score and -// used pages normally gives a negative score (as these must be moved). -// To have a fair wear-leveling, the erase age is also included in score, -// whose factor normally is the most positive. -// The larger the score, the more likely it is that the block will -// picked for garbage collection. - -// Garbage collecting heuristics - weight used for deleted pages. -#ifndef SPIFFS_GC_HEUR_W_DELET -#define SPIFFS_GC_HEUR_W_DELET (5) -#endif -// Garbage collecting heuristics - weight used for used pages. -#ifndef SPIFFS_GC_HEUR_W_USED -#define SPIFFS_GC_HEUR_W_USED (-1) -#endif -// Garbage collecting heuristics - weight used for time between -// last erased and erase of this block. -#ifndef SPIFFS_GC_HEUR_W_ERASE_AGE -#define SPIFFS_GC_HEUR_W_ERASE_AGE (50) -#endif - -// Object name maximum length. -#ifndef SPIFFS_OBJ_NAME_LEN -#define SPIFFS_OBJ_NAME_LEN (32) -#endif - -// Size of buffer allocated on stack used when copying data. -// Lower value generates more read/writes. No meaning having it bigger -// than logical page size. -#ifndef SPIFFS_COPY_BUFFER_STACK -#define SPIFFS_COPY_BUFFER_STACK (64) -#endif - -// Enable this to have an identifiable spiffs filesystem. This will look for -// a magic in all sectors to determine if this is a valid spiffs system or -// not on mount point. If not, SPIFFS_format must be called prior to mounting -// again. -#ifndef SPIFFS_USE_MAGIC -#define SPIFFS_USE_MAGIC (1) -#endif - -// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level -// These should be defined on a multithreaded system - -// define this to enter a mutex if you're running on a multithreaded system -#ifndef SPIFFS_LOCK -#define SPIFFS_LOCK(fs) -#endif -// define this to exit a mutex if you're running on a multithreaded system -#ifndef SPIFFS_UNLOCK -#define SPIFFS_UNLOCK(fs) -#endif - - -// Enable if only one spiffs instance with constant configuration will exist -// on the target. This will reduce calculations, flash and memory accesses. -// Parts of configuration must be defined below instead of at time of mount. -#ifndef SPIFFS_SINGLETON -#define SPIFFS_SINGLETON 0 -#endif - -#if SPIFFS_SINGLETON -// Instead of giving parameters in config struct, singleton build must -// give parameters in defines below. -#ifndef SPIFFS_CFG_PHYS_SZ -#define SPIFFS_CFG_PHYS_SZ(ignore) (1024*1024*2) -#endif -#ifndef SPIFFS_CFG_PHYS_ERASE_SZ -#define SPIFFS_CFG_PHYS_ERASE_SZ(ignore) (65536) -#endif -#ifndef SPIFFS_CFG_PHYS_ADDR -#define SPIFFS_CFG_PHYS_ADDR(ignore) (0) -#endif -#ifndef SPIFFS_CFG_LOG_PAGE_SZ -#define SPIFFS_CFG_LOG_PAGE_SZ(ignore) (256) -#endif -#ifndef SPIFFS_CFG_LOG_BLOCK_SZ -#define SPIFFS_CFG_LOG_BLOCK_SZ(ignore) (65536) -#endif -#endif - -// Enable this if your target needs aligned data for index tables -#ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES -#define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 1 -#endif - -// Enable this if you want the HAL callbacks to be called with the spiffs struct -#ifndef SPIFFS_HAL_CALLBACK_EXTRA -#define SPIFFS_HAL_CALLBACK_EXTRA 0 -#endif - -// Enable this if you want to add an integer offset to all file handles -// (spiffs_file). This is useful if running multiple instances of spiffs on -// same target, in order to recognise to what spiffs instance a file handle -// belongs. -// NB: This adds config field fh_ix_offset in the configuration struct when -// mounting, which must be defined. -#ifndef SPIFFS_FILEHDL_OFFSET -#define SPIFFS_FILEHDL_OFFSET 0 -#endif - -// Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function -// in the api. This function will visualize all filesystem using given printf -// function. -#ifndef SPIFFS_TEST_VISUALISATION -#define SPIFFS_TEST_VISUALISATION 1 -#endif -#if SPIFFS_TEST_VISUALISATION -#ifndef spiffs_printf -#define spiffs_printf(...) c_printf(__VA_ARGS__) -#endif -// spiffs_printf argument for a free page -#ifndef SPIFFS_TEST_VIS_FREE_STR -#define SPIFFS_TEST_VIS_FREE_STR "_" -#endif -// spiffs_printf argument for a deleted page -#ifndef SPIFFS_TEST_VIS_DELE_STR -#define SPIFFS_TEST_VIS_DELE_STR "/" -#endif -// spiffs_printf argument for an index page for given object id -#ifndef SPIFFS_TEST_VIS_INDX_STR -#define SPIFFS_TEST_VIS_INDX_STR(id) "i" -#endif -// spiffs_printf argument for a data page for given object id -#ifndef SPIFFS_TEST_VIS_DATA_STR -#define SPIFFS_TEST_VIS_DATA_STR(id) "d" -#endif -#endif - -// Types depending on configuration such as the amount of flash bytes -// given to spiffs file system in total (spiffs_file_system_size), -// the logical block size (log_block_size), and the logical page size -// (log_page_size) - -// Block index type. Make sure the size of this type can hold -// the highest number of all blocks - i.e. spiffs_file_system_size / log_block_size -typedef u16_t spiffs_block_ix; -// Page index type. Make sure the size of this type can hold -// the highest page number of all pages - i.e. spiffs_file_system_size / log_page_size -typedef u16_t spiffs_page_ix; -// Object id type - most significant bit is reserved for index flag. Make sure the -// size of this type can hold the highest object id on a full system, -// i.e. 2 + (spiffs_file_system_size / (2*log_page_size))*2 -typedef u16_t spiffs_obj_id; -// Object span index type. Make sure the size of this type can -// hold the largest possible span index on the system - -// i.e. (spiffs_file_system_size / log_page_size) - 1 -typedef u16_t spiffs_span_ix; - -#endif /* SPIFFS_CONFIG_H_ */ diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_gc.c b/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_gc.c deleted file mode 100644 index 8abb8dfc3..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_gc.c +++ /dev/null @@ -1,576 +0,0 @@ -#include "spiffs.h" -#include "spiffs_nucleus.h" - -#if !SPIFFS_READ_ONLY - -// Erases a logical block and updates the erase counter. -// If cache is enabled, all pages that might be cached in this block -// is dropped. -static s32_t spiffs_gc_erase_block( - spiffs *fs, - spiffs_block_ix bix) { - s32_t res; - - SPIFFS_GC_DBG("gc: erase block %i\n", bix); - res = spiffs_erase_block(fs, bix); - SPIFFS_CHECK_RES(res); - -#if SPIFFS_CACHE - { - u32_t i; - for (i = 0; i < SPIFFS_PAGES_PER_BLOCK(fs); i++) { - spiffs_cache_drop_page(fs, SPIFFS_PAGE_FOR_BLOCK(fs, bix) + i); - } - } -#endif - return res; -} - -// Searches for blocks where all entries are deleted - if one is found, -// the block is erased. Compared to the non-quick gc, the quick one ensures -// that no updates are needed on existing objects on pages that are erased. -s32_t spiffs_gc_quick( - spiffs *fs, u16_t max_free_pages) { - s32_t res = SPIFFS_OK; - u32_t blocks = fs->block_count; - spiffs_block_ix cur_block = 0; - u32_t cur_block_addr = 0; - int cur_entry = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - - SPIFFS_GC_DBG("gc_quick: running\n"); -#if SPIFFS_GC_STATS - fs->stats_gc_runs++; -#endif - - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - - // find fully deleted blocks - // check each block - while (res == SPIFFS_OK && blocks--) { - u16_t deleted_pages_in_block = 0; - u16_t free_pages_in_block = 0; - - int obj_lookup_page = 0; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && - cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_DELETED) { - deleted_pages_in_block++; - } else if (obj_id == SPIFFS_OBJ_ID_FREE) { - // kill scan, go for next block - free_pages_in_block++; - if (free_pages_in_block > max_free_pages) { - obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); - res = 1; // kill object lu loop - break; - } - } else { - // kill scan, go for next block - obj_lookup_page = SPIFFS_OBJ_LOOKUP_PAGES(fs); - res = 1; // kill object lu loop - break; - } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - if (res == 1) res = SPIFFS_OK; - - if (res == SPIFFS_OK && - deleted_pages_in_block + free_pages_in_block == SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs) && - free_pages_in_block <= max_free_pages) { - // found a fully deleted block - fs->stats_p_deleted -= deleted_pages_in_block; - res = spiffs_gc_erase_block(fs, cur_block); - return res; - } - - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - } // per block - - if (res == SPIFFS_OK) { - res = SPIFFS_ERR_NO_DELETED_BLOCKS; - } - return res; -} - -// Checks if garbage collecting is necessary. If so a candidate block is found, -// cleansed and erased -s32_t spiffs_gc_check( - spiffs *fs, - u32_t len) { - s32_t res; - s32_t free_pages = - (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count-2) - - fs->stats_p_allocated - fs->stats_p_deleted; - int tries = 0; - - if (fs->free_blocks > 3 && - (s32_t)len < free_pages * (s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { - return SPIFFS_OK; - } - - u32_t needed_pages = (len + SPIFFS_DATA_PAGE_SIZE(fs) - 1) / SPIFFS_DATA_PAGE_SIZE(fs); -// if (fs->free_blocks <= 2 && (s32_t)needed_pages > free_pages) { -// SPIFFS_GC_DBG("gc: full freeblk:%i needed:%i free:%i dele:%i\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); -// return SPIFFS_ERR_FULL; -// } - if ((s32_t)needed_pages > (s32_t)(free_pages + fs->stats_p_deleted)) { - SPIFFS_GC_DBG("gc_check: full freeblk:%i needed:%i free:%i dele:%i\n", fs->free_blocks, needed_pages, free_pages, fs->stats_p_deleted); - return SPIFFS_ERR_FULL; - } - - do { - SPIFFS_GC_DBG("\ngc_check #%i: run gc free_blocks:%i pfree:%i pallo:%i pdele:%i [%i] len:%i of %i\n", - tries, - fs->free_blocks, free_pages, fs->stats_p_allocated, fs->stats_p_deleted, (free_pages+fs->stats_p_allocated+fs->stats_p_deleted), - len, free_pages*SPIFFS_DATA_PAGE_SIZE(fs)); - - spiffs_block_ix *cands; - int count; - spiffs_block_ix cand; - s32_t prev_free_pages = free_pages; - // if the fs is crammed, ignore block age when selecting candidate - kind of a bad state - res = spiffs_gc_find_candidate(fs, &cands, &count, free_pages <= 0); - SPIFFS_CHECK_RES(res); - if (count == 0) { - SPIFFS_GC_DBG("gc_check: no candidates, return\n"); - return (s32_t)needed_pages < free_pages ? SPIFFS_OK : SPIFFS_ERR_FULL; - } -#if SPIFFS_GC_STATS - fs->stats_gc_runs++; -#endif - cand = cands[0]; - fs->cleaning = 1; - //printf("gcing: cleaning block %i\n", cand); - res = spiffs_gc_clean(fs, cand); - fs->cleaning = 0; - if (res < 0) { - SPIFFS_GC_DBG("gc_check: cleaning block %i, result %i\n", cand, res); - } else { - SPIFFS_GC_DBG("gc_check: cleaning block %i, result %i\n", cand, res); - } - SPIFFS_CHECK_RES(res); - - res = spiffs_gc_erase_page_stats(fs, cand); - SPIFFS_CHECK_RES(res); - - res = spiffs_gc_erase_block(fs, cand); - SPIFFS_CHECK_RES(res); - - free_pages = - (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - - fs->stats_p_allocated - fs->stats_p_deleted; - - if (prev_free_pages <= 0 && prev_free_pages == free_pages) { - // abort early to reduce wear, at least tried once - SPIFFS_GC_DBG("gc_check: early abort, no result on gc when fs crammed\n"); - break; - } - - } while (++tries < SPIFFS_GC_MAX_RUNS && (fs->free_blocks <= 2 || - (s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs))); - - free_pages = - (SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs)) * (fs->block_count - 2) - - fs->stats_p_allocated - fs->stats_p_deleted; - if ((s32_t)len > free_pages*(s32_t)SPIFFS_DATA_PAGE_SIZE(fs)) { - res = SPIFFS_ERR_FULL; - } - - SPIFFS_GC_DBG("gc_check: finished, %i dirty, blocks %i free, %i pages free, %i tries, res %i\n", - fs->stats_p_allocated + fs->stats_p_deleted, - fs->free_blocks, free_pages, tries, res); - - return res; -} - -// Updates page statistics for a block that is about to be erased -s32_t spiffs_gc_erase_page_stats( - spiffs *fs, - spiffs_block_ix bix) { - s32_t res = SPIFFS_OK; - int obj_lookup_page = 0; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = 0; - u32_t dele = 0; - u32_t allo = 0; - - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - dele++; - } else { - allo++; - } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - SPIFFS_GC_DBG("gc_check: wipe pallo:%i pdele:%i\n", allo, dele); - fs->stats_p_allocated -= allo; - fs->stats_p_deleted -= dele; - return res; -} - -// Finds block candidates to erase -s32_t spiffs_gc_find_candidate( - spiffs *fs, - spiffs_block_ix **block_candidates, - int *candidate_count, - char fs_crammed) { - s32_t res = SPIFFS_OK; - u32_t blocks = fs->block_count; - spiffs_block_ix cur_block = 0; - u32_t cur_block_addr = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = 0; - - // using fs->work area as sorted candidate memory, (spiffs_block_ix)cand_bix/(s32_t)score - int max_candidates = MIN(fs->block_count, (SPIFFS_CFG_LOG_PAGE_SZ(fs)-8)/(sizeof(spiffs_block_ix) + sizeof(s32_t))); - *candidate_count = 0; - memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - - // divide up work area into block indices and scores - spiffs_block_ix *cand_blocks = (spiffs_block_ix *)fs->work; - s32_t *cand_scores = (s32_t *)(fs->work + max_candidates * sizeof(spiffs_block_ix)); - - // align cand_scores on s32_t boundary -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" - cand_scores = (s32_t*)(((ptrdiff_t)cand_scores + sizeof(ptrdiff_t) - 1) & ~(sizeof(ptrdiff_t) - 1)); -#pragma GCC diagnostic pop - - *block_candidates = cand_blocks; - - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - - // check each block - while (res == SPIFFS_OK && blocks--) { - u16_t deleted_pages_in_block = 0; - u16_t used_pages_in_block = 0; - - int obj_lookup_page = 0; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && - cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - // when a free entry is encountered, scan logic ensures that all following entries are free also - res = 1; // kill object lu loop - break; - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - deleted_pages_in_block++; - } else { - used_pages_in_block++; - } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - if (res == 1) res = SPIFFS_OK; - - // calculate score and insert into candidate table - // stoneage sort, but probably not so many blocks - if (res == SPIFFS_OK && deleted_pages_in_block > 0) { - // read erase count - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, cur_block), - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); - - spiffs_obj_id erase_age; - if (fs->max_erase_count > erase_count) { - erase_age = fs->max_erase_count - erase_count; - } else { - erase_age = SPIFFS_OBJ_ID_FREE - (erase_count - fs->max_erase_count); - } - - s32_t score = - deleted_pages_in_block * SPIFFS_GC_HEUR_W_DELET + - used_pages_in_block * SPIFFS_GC_HEUR_W_USED + - erase_age * (fs_crammed ? 0 : SPIFFS_GC_HEUR_W_ERASE_AGE); - int cand_ix = 0; - SPIFFS_GC_DBG("gc_check: bix:%i del:%i use:%i score:%i\n", cur_block, deleted_pages_in_block, used_pages_in_block, score); - while (cand_ix < max_candidates) { - if (cand_blocks[cand_ix] == (spiffs_block_ix)-1) { - cand_blocks[cand_ix] = cur_block; - cand_scores[cand_ix] = score; - break; - } else if (cand_scores[cand_ix] < score) { - int reorder_cand_ix = max_candidates - 2; - while (reorder_cand_ix >= cand_ix) { - cand_blocks[reorder_cand_ix + 1] = cand_blocks[reorder_cand_ix]; - cand_scores[reorder_cand_ix + 1] = cand_scores[reorder_cand_ix]; - reorder_cand_ix--; - } - cand_blocks[cand_ix] = cur_block; - cand_scores[cand_ix] = score; - break; - } - cand_ix++; - } - (*candidate_count)++; - } - - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - } // per block - - return res; -} - -typedef enum { - FIND_OBJ_DATA, - MOVE_OBJ_DATA, - MOVE_OBJ_IX, - FINISHED -} spiffs_gc_clean_state; - -typedef struct { - spiffs_gc_clean_state state; - spiffs_obj_id cur_obj_id; - spiffs_span_ix cur_objix_spix; - spiffs_page_ix cur_objix_pix; - int stored_scan_entry_index; - u8_t obj_id_found; -} spiffs_gc; - -// Empties given block by moving all data into free pages of another block -// Strategy: -// loop: -// scan object lookup for object data pages -// for first found id, check spix and load corresponding object index page to memory -// push object scan lookup entry index -// rescan object lookup, find data pages with same id and referenced by same object index -// move data page, update object index in memory -// when reached end of lookup, store updated object index -// pop object scan lookup entry index -// repeat loop until end of object lookup -// scan object lookup again for remaining object index pages, move to new page in other block -// -s32_t spiffs_gc_clean(spiffs *fs, spiffs_block_ix bix) { - s32_t res = SPIFFS_OK; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - int cur_entry = 0; - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - spiffs_gc gc; - spiffs_page_ix cur_pix = 0; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - - SPIFFS_GC_DBG("gc_clean: cleaning block %i\n", bix); - - memset(&gc, 0, sizeof(spiffs_gc)); - gc.state = FIND_OBJ_DATA; - - if (fs->free_cursor_block_ix == bix) { - // move free cursor to next block, cannot use free pages from the block we want to clean - fs->free_cursor_block_ix = (bix+1)%fs->block_count; - fs->free_cursor_obj_lu_entry = 0; - SPIFFS_GC_DBG("gc_clean: move free cursor to block %i\n", fs->free_cursor_block_ix); - } - - while (res == SPIFFS_OK && gc.state != FINISHED) { - SPIFFS_GC_DBG("gc_clean: state = %i entry:%i\n", gc.state, cur_entry); - gc.obj_id_found = 0; - - // scan through lookup pages - int obj_lookup_page = cur_entry / entries_per_page; - u8_t scan = 1; - // check each object lookup page - while (scan && res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (scan && res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - cur_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, cur_entry); - - // act upon object id depending on gc state - switch (gc.state) { - case FIND_OBJ_DATA: - if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && - ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0)) { - SPIFFS_GC_DBG("gc_clean: FIND_DATA state:%i - found obj id %04x\n", gc.state, obj_id); - gc.obj_id_found = 1; - gc.cur_obj_id = obj_id; - scan = 0; - } - break; - case MOVE_OBJ_DATA: - if (obj_id == gc.cur_obj_id) { - spiffs_page_header p_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA found data page %04x:%04x @ %04x\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix); - if (SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix) != gc.cur_objix_spix) { - SPIFFS_GC_DBG("gc_clean: MOVE_DATA no objix spix match, take in another run\n"); - } else { - spiffs_page_ix new_data_pix; - if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { - // move page - res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_data_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA move objix %04x:%04x page %04x to %04x\n", gc.cur_obj_id, p_hdr.span_ix, cur_pix, new_data_pix); - SPIFFS_CHECK_RES(res); - // move wipes obj_lu, reload it - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } else { - // page is deleted but not deleted in lookup, scrap it - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wipe objix %04x:%04x page %04x\n", obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_page_delete(fs, cur_pix); - SPIFFS_CHECK_RES(res); - new_data_pix = SPIFFS_OBJ_ID_FREE; - } - // update memory representation of object index page with new data page - if (gc.cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[p_hdr.span_ix] = new_data_pix; - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page %04x to objix_hdr entry %02x in mem\n", new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)] = new_data_pix; - SPIFFS_GC_DBG("gc_clean: MOVE_DATA wrote page %04x to objix entry %02x in mem\n", new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, p_hdr.span_ix)); - } - } - } - break; - case MOVE_OBJ_IX: - if (obj_id != SPIFFS_OBJ_ID_DELETED && obj_id != SPIFFS_OBJ_ID_FREE && - (obj_id & SPIFFS_OBJ_ID_IX_FLAG)) { - // found an index object id - spiffs_page_header p_hdr; - spiffs_page_ix new_pix; - // load header - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - if (p_hdr.flags & SPIFFS_PH_FLAG_DELET) { - // move page - res = spiffs_page_move(fs, 0, 0, obj_id, &p_hdr, cur_pix, &new_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX move objix %04x:%04x page %04x to %04x\n", obj_id, p_hdr.span_ix, cur_pix, new_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_UPD, obj_id, p_hdr.span_ix, new_pix, 0); - // move wipes obj_lu, reload it - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), - SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } else { - // page is deleted but not deleted in lookup, scrap it - SPIFFS_GC_DBG("gc_clean: MOVE_OBJIX wipe objix %04x:%04x page %04x\n", obj_id, p_hdr.span_ix, cur_pix); - res = spiffs_page_delete(fs, cur_pix); - if (res == SPIFFS_OK) { - spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_DEL, obj_id, p_hdr.span_ix, cur_pix, 0); - } - } - SPIFFS_CHECK_RES(res); - } - break; - default: - scan = 0; - break; - } - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - - if (res != SPIFFS_OK) break; - - // state finalization and switch - switch (gc.state) { - case FIND_OBJ_DATA: - if (gc.obj_id_found) { - // find out corresponding obj ix page and load it to memory - spiffs_page_header p_hdr; - spiffs_page_ix objix_pix; - gc.stored_scan_entry_index = cur_entry; - cur_entry = 0; - gc.state = MOVE_OBJ_DATA; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, cur_pix), sizeof(spiffs_page_header), (u8_t*)&p_hdr); - SPIFFS_CHECK_RES(res); - gc.cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, p_hdr.span_ix); - SPIFFS_GC_DBG("gc_clean: FIND_DATA find objix span_ix:%04x\n", gc.cur_objix_spix); - res = spiffs_obj_lu_find_id_and_span(fs, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix, 0, &objix_pix); - SPIFFS_CHECK_RES(res); - SPIFFS_GC_DBG("gc_clean: FIND_DATA found object index at page %04x\n", objix_pix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix->p_hdr, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_spix); - gc.cur_objix_pix = objix_pix; - } else { - gc.state = MOVE_OBJ_IX; - cur_entry = 0; // restart entry scan index - } - break; - case MOVE_OBJ_DATA: { - // store modified objix (hdr) page - spiffs_page_ix new_objix_pix; - gc.state = FIND_OBJ_DATA; - cur_entry = gc.stored_scan_entry_index; - if (gc.cur_objix_spix == 0) { - // store object index header page - res = spiffs_object_update_index_hdr(fs, 0, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, gc.cur_objix_pix, fs->work, 0, 0, &new_objix_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix_hdr page, %04x:%04x\n", new_objix_pix, 0); - SPIFFS_CHECK_RES(res); - } else { - // store object index page - res = spiffs_page_move(fs, 0, fs->work, gc.cur_obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, gc.cur_objix_pix, &new_objix_pix); - SPIFFS_GC_DBG("gc_clean: MOVE_DATA store modified objix page, %04x:%04x\n", new_objix_pix, objix->p_hdr.span_ix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_UPD, gc.cur_obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - } - } - break; - case MOVE_OBJ_IX: - gc.state = FINISHED; - break; - default: - cur_entry = 0; - break; - } - SPIFFS_GC_DBG("gc_clean: state-> %i\n", gc.state); - } // while state != FINISHED - - - return res; -} - -#endif // !SPIFFS_READ_ONLY diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_hydrogen.c b/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_hydrogen.c deleted file mode 100644 index c43ddcdc3..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_hydrogen.c +++ /dev/null @@ -1,1170 +0,0 @@ -/* - * spiffs_hydrogen.c - * - * Created on: Jun 16, 2013 - * Author: petera - */ - -#include "spiffs.h" -#include "spiffs_nucleus.h" - -#if SPIFFS_FILEHDL_OFFSET -#define SPIFFS_FH_OFFS(fs, fh) ((fh) != 0 ? ((fh) + (fs)->cfg.fh_ix_offset) : 0) -#define SPIFFS_FH_UNOFFS(fs, fh) ((fh) != 0 ? ((fh) - (fs)->cfg.fh_ix_offset) : 0) -#else -#define SPIFFS_FH_OFFS(fs, fh) (fh) -#define SPIFFS_FH_UNOFFS(fs, fh) (fh) -#endif - -#if SPIFFS_CACHE == 1 -static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh); -#endif - -#if SPIFFS_BUFFER_HELP -u32_t SPIFFS_buffer_bytes_for_filedescs(spiffs *fs, u32_t num_descs) { - return num_descs * sizeof(spiffs_fd); -} -#if SPIFFS_CACHE -u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) { - return sizeof(spiffs_cache) + num_pages * (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)); -} -#endif -#endif - -u8_t SPIFFS_mounted(spiffs *fs) { - return SPIFFS_CHECK_MOUNT(fs); -} - -s32_t SPIFFS_format(spiffs *fs) { -#if SPIFFS_READ_ONLY - (void)fs; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - SPIFFS_API_CHECK_CFG(fs); - if (SPIFFS_CHECK_MOUNT(fs)) { - fs->err_code = SPIFFS_ERR_MOUNTED; - return -1; - } - - s32_t res; - SPIFFS_LOCK(fs); - - spiffs_block_ix bix = 0; - while (bix < fs->block_count) { - fs->max_erase_count = 0; - res = spiffs_erase_block(fs, bix); - if (res != SPIFFS_OK) { - res = SPIFFS_ERR_ERASE_FAIL; - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - bix++; - } - - SPIFFS_UNLOCK(fs); - - return 0; -#endif // SPIFFS_READ_ONLY -} - -#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 - -s32_t SPIFFS_probe_fs(spiffs_config *config) { - s32_t res = spiffs_probe(config); - return res; -} - -#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 - -s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work, - u8_t *fd_space, u32_t fd_space_size, - void *cache, u32_t cache_size, - spiffs_check_callback check_cb_f) { - void *user_data; - SPIFFS_LOCK(fs); - user_data = fs->user_data; - memset(fs, 0, sizeof(spiffs)); - memcpy(&fs->cfg, config, sizeof(spiffs_config)); - fs->user_data = user_data; - fs->block_count = SPIFFS_CFG_PHYS_SZ(fs) / SPIFFS_CFG_LOG_BLOCK_SZ(fs); - fs->work = &work[0]; - fs->lu_work = &work[SPIFFS_CFG_LOG_PAGE_SZ(fs)]; - memset(fd_space, 0, fd_space_size); - // align fd_space pointer to pointer size byte boundary, below is safe - u8_t ptr_size = sizeof(void*); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" - u8_t addr_lsb = ((u8_t)fd_space) & (ptr_size-1); -#pragma GCC diagnostic pop - if (addr_lsb) { - fd_space += (ptr_size-addr_lsb); - fd_space_size -= (ptr_size-addr_lsb); - } - fs->fd_space = fd_space; - fs->fd_count = (fd_space_size/sizeof(spiffs_fd)); - - // align cache pointer to 4 byte boundary, below is safe -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wpointer-to-int-cast" - addr_lsb = ((u8_t)cache) & (ptr_size-1); -#pragma GCC diagnostic pop - if (addr_lsb) { - u8_t *cache_8 = (u8_t *)cache; - cache_8 += (ptr_size-addr_lsb); - cache = cache_8; - cache_size -= (ptr_size-addr_lsb); - } - if (cache_size & (ptr_size-1)) { - cache_size -= (cache_size & (ptr_size-1)); - } - -#if SPIFFS_CACHE - fs->cache = cache; - fs->cache_size = (cache_size > (SPIFFS_CFG_LOG_PAGE_SZ(fs)*32)) ? SPIFFS_CFG_LOG_PAGE_SZ(fs)*32 : cache_size; - spiffs_cache_init(fs); -#endif - - s32_t res; - -#if SPIFFS_USE_MAGIC - res = SPIFFS_CHECK_MAGIC_POSSIBLE(fs) ? SPIFFS_OK : SPIFFS_ERR_MAGIC_NOT_POSSIBLE; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); -#endif - - fs->config_magic = SPIFFS_CONFIG_MAGIC; - - res = spiffs_obj_lu_scan(fs); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - SPIFFS_DBG("page index byte len: %i\n", SPIFFS_CFG_LOG_PAGE_SZ(fs)); - SPIFFS_DBG("object lookup pages: %i\n", SPIFFS_OBJ_LOOKUP_PAGES(fs)); - SPIFFS_DBG("page pages per block: %i\n", SPIFFS_PAGES_PER_BLOCK(fs)); - SPIFFS_DBG("page header length: %i\n", sizeof(spiffs_page_header)); - SPIFFS_DBG("object header index entries: %i\n", SPIFFS_OBJ_HDR_IX_LEN(fs)); - SPIFFS_DBG("object index entries: %i\n", SPIFFS_OBJ_IX_LEN(fs)); - SPIFFS_DBG("available file descriptors: %i\n", fs->fd_count); - SPIFFS_DBG("free blocks: %i\n", fs->free_blocks); - - fs->check_cb_f = check_cb_f; - - fs->mounted = 1; - - SPIFFS_UNLOCK(fs); - - return 0; -} - -void SPIFFS_unmount(spiffs *fs) { - if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) return; - SPIFFS_LOCK(fs); - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr != 0) { -#if SPIFFS_CACHE - (void)spiffs_fflush_cache(fs, cur_fd->file_nbr); -#endif - spiffs_fd_return(fs, cur_fd->file_nbr); - } - } - fs->mounted = 0; - - SPIFFS_UNLOCK(fs); -} - -s32_t SPIFFS_errno(spiffs *fs) { - return fs->err_code; -} - -void SPIFFS_clearerr(spiffs *fs) { - fs->err_code = SPIFFS_OK; -} - -s32_t SPIFFS_creat(spiffs *fs, const char *path, spiffs_mode mode) { -#if SPIFFS_READ_ONLY - (void)fs; (void)path; (void)mode; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - (void)mode; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - spiffs_obj_id obj_id; - s32_t res; - - res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, (const u8_t*)path); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_create(fs, obj_id, (const u8_t*)path, SPIFFS_TYPE_FILE, 0); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY -} - -spiffs_file SPIFFS_open(spiffs *fs, const char *path, spiffs_flags flags, spiffs_mode mode) { - (void)mode; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - spiffs_page_ix pix; - -#if SPIFFS_READ_ONLY - // not valid flags in read only mode - flags &= ~SPIFFS_WRONLY | SPIFFS_CREAT | SPIFFS_TRUNC; -#endif // SPIFFS_READ_ONLY - - s32_t res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - if ((flags & SPIFFS_CREAT) == 0) { - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - - if (res == SPIFFS_OK && - (flags & (SPIFFS_CREAT | SPIFFS_EXCL)) == (SPIFFS_CREAT | SPIFFS_EXCL)) { - // creat and excl and file exists - fail - res = SPIFFS_ERR_FILE_EXISTS; - spiffs_fd_return(fs, fd->file_nbr); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - - if ((flags & SPIFFS_CREAT) && res == SPIFFS_ERR_NOT_FOUND) { -#if !SPIFFS_READ_ONLY - spiffs_obj_id obj_id; - // no need to enter conflicting name here, already looked for it above - res = spiffs_obj_lu_find_free_obj_id(fs, &obj_id, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - res = spiffs_object_create(fs, obj_id, (const u8_t*)path, SPIFFS_TYPE_FILE, &pix); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - flags &= ~SPIFFS_TRUNC; -#endif // !SPIFFS_READ_ONLY - } else { - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); -#if !SPIFFS_READ_ONLY - if (flags & SPIFFS_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } -#endif // !SPIFFS_READ_ONLY - - fd->fdoffset = 0; - - SPIFFS_UNLOCK(fs); - - return SPIFFS_FH_OFFS(fs, fd->file_nbr); -} - -spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - - s32_t res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_open_by_page(fs, e->pix, fd, flags, mode); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); -#if !SPIFFS_READ_ONLY - if (flags & SPIFFS_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } -#endif // !SPIFFS_READ_ONLY - - fd->fdoffset = 0; - - SPIFFS_UNLOCK(fs); - - return SPIFFS_FH_OFFS(fs, fd->file_nbr); -} - -spiffs_file SPIFFS_open_by_page(spiffs *fs, spiffs_page_ix page_ix, spiffs_flags flags, spiffs_mode mode) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - - s32_t res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if (SPIFFS_IS_LOOKUP_PAGE(fs, page_ix)) { - res = SPIFFS_ERR_NOT_A_FILE; - spiffs_fd_return(fs, fd->file_nbr); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - - res = spiffs_object_open_by_page(fs, page_ix, fd, flags, mode); - if (res == SPIFFS_ERR_IS_FREE || - res == SPIFFS_ERR_DELETED || - res == SPIFFS_ERR_NOT_FINALIZED || - res == SPIFFS_ERR_NOT_INDEX || - res == SPIFFS_ERR_INDEX_SPAN_MISMATCH) { - res = SPIFFS_ERR_NOT_A_FILE; - } - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - -#if !SPIFFS_READ_ONLY - if (flags & SPIFFS_TRUNC) { - res = spiffs_object_truncate(fd, 0, 0); - if (res < SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } -#endif // !SPIFFS_READ_ONLY - - fd->fdoffset = 0; - - SPIFFS_UNLOCK(fs); - - return SPIFFS_FH_OFFS(fs, fd->file_nbr); -} - -s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - s32_t res; - - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_RDONLY) == 0) { - res = SPIFFS_ERR_NOT_READABLE; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - - if (fd->size == SPIFFS_UNDEFINED_LEN && len > 0) { - // special case for zero sized files - res = SPIFFS_ERR_END_OF_OBJECT; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - -#if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); -#endif - - if (fd->fdoffset + len >= fd->size) { - // reading beyond file size - s32_t avail = fd->size - fd->fdoffset; - if (avail <= 0) { - SPIFFS_API_CHECK_RES_UNLOCK(fs, SPIFFS_ERR_END_OF_OBJECT); - } - res = spiffs_object_read(fd, fd->fdoffset, avail, (u8_t*)buf); - if (res == SPIFFS_ERR_END_OF_OBJECT) { - fd->fdoffset += avail; - SPIFFS_UNLOCK(fs); - return avail; - } else { - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - len = avail; - } - } else { - // reading within file size - res = spiffs_object_read(fd, fd->fdoffset, len, (u8_t*)buf); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - fd->fdoffset += len; - - SPIFFS_UNLOCK(fs); - - return len; -} - -#if !SPIFFS_READ_ONLY -static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offset, s32_t len) { - (void)fs; - s32_t res = SPIFFS_OK; - s32_t remaining = len; - if (fd->size != SPIFFS_UNDEFINED_LEN && offset < fd->size) { - s32_t m_len = MIN((s32_t)(fd->size - offset), len); - res = spiffs_object_modify(fd, offset, (u8_t *)buf, m_len); - SPIFFS_CHECK_RES(res); - remaining -= m_len; - u8_t *buf_8 = (u8_t *)buf; - buf_8 += m_len; - buf = buf_8; - offset += m_len; - } - if (remaining > 0) { - res = spiffs_object_append(fd, offset, (u8_t *)buf, remaining); - SPIFFS_CHECK_RES(res); - } - return len; - -} -#endif // !SPIFFS_READ_ONLY - -s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, s32_t len) { -#if SPIFFS_READ_ONLY - (void)fs; (void)fh; (void)buf; (void)len; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - s32_t res; - u32_t offset; - - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_WRONLY) == 0) { - res = SPIFFS_ERR_NOT_WRITABLE; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - - if ((fd->flags & SPIFFS_APPEND)) { - fd->fdoffset = fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size; - } - - offset = fd->fdoffset; - -#if SPIFFS_CACHE_WR - if (fd->cache_page == 0) { - // see if object id is associated with cache already - fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); - } -#endif - if (fd->flags & SPIFFS_APPEND) { - if (fd->size == SPIFFS_UNDEFINED_LEN) { - offset = 0; - } else { - offset = fd->size; - } -#if SPIFFS_CACHE_WR - if (fd->cache_page) { - offset = MAX(offset, fd->cache_page->offset + fd->cache_page->size); - } -#endif - } - -#if SPIFFS_CACHE_WR - if ((fd->flags & SPIFFS_DIRECT) == 0) { - if (len < (s32_t)SPIFFS_CFG_LOG_PAGE_SZ(fs)) { - // small write, try to cache it - u8_t alloc_cpage = 1; - if (fd->cache_page) { - // have a cached page for this fd already, check cache page boundaries - if (offset < fd->cache_page->offset || // writing before cache - offset > fd->cache_page->offset + fd->cache_page->size || // writing after cache - offset + len > fd->cache_page->offset + SPIFFS_CFG_LOG_PAGE_SZ(fs)) // writing beyond cache page - { - // boundary violation, write back cache first and allocate new - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, boundary viol, offs:%i size:%i\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->offset, fd->cache_page->size); - spiffs_cache_fd_release(fs, fd->cache_page); - SPIFFS_API_CHECK_RES(fs, res); - } else { - // writing within cache - alloc_cpage = 0; - } - } - - if (alloc_cpage) { - fd->cache_page = spiffs_cache_page_allocate_by_fd(fs, fd); - if (fd->cache_page) { - fd->cache_page->offset = offset; - fd->cache_page->size = 0; - SPIFFS_CACHE_DBG("CACHE_WR_ALLO: allocating cache page %i for fd %i:%04x\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id); - } - } - - if (fd->cache_page) { - u32_t offset_in_cpage = offset - fd->cache_page->offset; - SPIFFS_CACHE_DBG("CACHE_WR_WRITE: storing to cache page %i for fd %i:%04x, offs %i:%i len %i\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, - offset, offset_in_cpage, len); - spiffs_cache *cache = spiffs_get_cache(fs); - u8_t *cpage_data = spiffs_get_cache_page(fs, cache, fd->cache_page->ix); - memcpy(&cpage_data[offset_in_cpage], buf, len); - fd->cache_page->size = MAX(fd->cache_page->size, offset_in_cpage + len); - fd->fdoffset += len; - SPIFFS_UNLOCK(fs); - return len; - } else { - res = spiffs_hydro_write(fs, fd, buf, offset, len); - SPIFFS_API_CHECK_RES(fs, res); - fd->fdoffset += len; - SPIFFS_UNLOCK(fs); - return res; - } - } else { - // big write, no need to cache it - but first check if there is a cached write already - if (fd->cache_page) { - // write back cache first - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, big write, offs:%i size:%i\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->offset, fd->cache_page->size); - spiffs_cache_fd_release(fs, fd->cache_page); - SPIFFS_API_CHECK_RES(fs, res); - res = spiffs_hydro_write(fs, fd, buf, offset, len); - SPIFFS_API_CHECK_RES(fs, res); - } - } - } -#endif - - res = spiffs_hydro_write(fs, fd, buf, offset, len); - SPIFFS_API_CHECK_RES(fs, res); - fd->fdoffset += len; - - SPIFFS_UNLOCK(fs); - - return res; -#endif // SPIFFS_READ_ONLY -} - -s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES(fs, res); - -#if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); -#endif - - switch (whence) { - case SPIFFS_SEEK_CUR: - offs = fd->fdoffset+offs; - break; - case SPIFFS_SEEK_END: - offs = (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size) + offs; - break; - } - - if ((offs > (s32_t)fd->size) && (SPIFFS_UNDEFINED_LEN != fd->size)) { - res = SPIFFS_ERR_END_OF_OBJECT; - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - spiffs_span_ix data_spix = offs / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_span_ix objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (fd->cursor_objix_spix != objix_spix) { - spiffs_page_ix pix; - res = spiffs_obj_lu_find_id_and_span( - fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, objix_spix, 0, &pix); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - fd->cursor_objix_spix = objix_spix; - fd->cursor_objix_pix = pix; - } - fd->fdoffset = offs; - - SPIFFS_UNLOCK(fs); - - return offs; -} - -s32_t SPIFFS_remove(spiffs *fs, const char *path) { -#if SPIFFS_READ_ONLY - (void)fs; (void)path; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - spiffs_page_ix pix; - s32_t res; - - res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_open_by_page(fs, pix, fd, 0,0); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_truncate(fd, 0, 1); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY -} - -s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) { -#if SPIFFS_READ_ONLY - (void)fs; (void)fh; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - s32_t res; - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - if ((fd->flags & SPIFFS_WRONLY) == 0) { - res = SPIFFS_ERR_NOT_WRITABLE; - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - } - -#if SPIFFS_CACHE_WR - spiffs_cache_fd_release(fs, fd->cache_page); -#endif - - res = spiffs_object_truncate(fd, 0, 1); - - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - SPIFFS_UNLOCK(fs); - - return 0; -#endif // SPIFFS_READ_ONLY -} - -static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spiffs_stat *s) { - (void)fh; - spiffs_page_object_ix_header objix_hdr; - spiffs_obj_id obj_id; - s32_t res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, fh, - SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_API_CHECK_RES(fs, res); - - u32_t obj_id_addr = SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs , pix)) + - SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_obj_id); - res =_spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, fh, - obj_id_addr, sizeof(spiffs_obj_id), (u8_t *)&obj_id); - SPIFFS_API_CHECK_RES(fs, res); - - s->obj_id = obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - s->type = objix_hdr.type; - s->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; - s->pix = pix; - strncpy((char *)s->name, (char *)objix_hdr.name, SPIFFS_OBJ_NAME_LEN); - - return res; -} - -s32_t SPIFFS_stat(spiffs *fs, const char *path, spiffs_stat *s) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - s32_t res; - spiffs_page_ix pix; - - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)path, &pix); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_stat_pix(fs, pix, 0, s); - - SPIFFS_UNLOCK(fs); - - return res; -} - -s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_fd *fd; - s32_t res; - - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - -#if SPIFFS_CACHE_WR - spiffs_fflush_cache(fs, fh); -#endif - - res = spiffs_stat_pix(fs, fd->objix_hdr_pix, fh, s); - - SPIFFS_UNLOCK(fs); - - return res; -} - -// Checks if there are any cached writes for the object id associated with -// given filehandle. If so, these writes are flushed. -#if SPIFFS_CACHE == 1 -static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) { - (void)fs; - (void)fh; - s32_t res = SPIFFS_OK; -#if !SPIFFS_READ_ONLY && SPIFFS_CACHE_WR - - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES(fs, res); - - if ((fd->flags & SPIFFS_DIRECT) == 0) { - if (fd->cache_page == 0) { - // see if object id is associated with cache already - fd->cache_page = spiffs_cache_page_get_by_fd(fs, fd); - } - if (fd->cache_page) { - SPIFFS_CACHE_DBG("CACHE_WR_DUMP: dumping cache page %i for fd %i:%04x, flush, offs:%i size:%i\n", - fd->cache_page->ix, fd->file_nbr, fd->obj_id, fd->cache_page->offset, fd->cache_page->size); - res = spiffs_hydro_write(fs, fd, - spiffs_get_cache_page(fs, spiffs_get_cache(fs), fd->cache_page->ix), - fd->cache_page->offset, fd->cache_page->size); - if (res < SPIFFS_OK) { - fs->err_code = res; - } - spiffs_cache_fd_release(fs, fd->cache_page); - } - } -#endif - - return res; -} -#endif - -s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) { - (void)fh; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - s32_t res = SPIFFS_OK; -#if !SPIFFS_READ_ONLY && SPIFFS_CACHE_WR - SPIFFS_LOCK(fs); - fh = SPIFFS_FH_UNOFFS(fs, fh); - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs,res); - SPIFFS_UNLOCK(fs); -#endif - - return res; -} - -s32_t SPIFFS_close(spiffs *fs, spiffs_file fh) { - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - - s32_t res = SPIFFS_OK; - SPIFFS_LOCK(fs); - - fh = SPIFFS_FH_UNOFFS(fs, fh); -#if SPIFFS_CACHE - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); -#endif - res = spiffs_fd_return(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - SPIFFS_UNLOCK(fs); - - return res; -} - -s32_t SPIFFS_rename(spiffs *fs, const char *old, const char *new) { -#if SPIFFS_READ_ONLY - (void)fs; (void)old; (void)new; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - spiffs_page_ix pix_old, pix_dummy; - spiffs_fd *fd; - - s32_t res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)old, &pix_old); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_find_object_index_header_by_name(fs, (const u8_t*)new, &pix_dummy); - if (res == SPIFFS_ERR_NOT_FOUND) { - res = SPIFFS_OK; - } else if (res == SPIFFS_OK) { - res = SPIFFS_ERR_CONFLICTING_NAME; - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_fd_find_new(fs, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_open_by_page(fs, pix_old, fd, 0, 0); - if (res != SPIFFS_OK) { - spiffs_fd_return(fs, fd->file_nbr); - } - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, fd->objix_hdr_pix, 0, (const u8_t*)new, - 0, &pix_dummy); - - spiffs_fd_return(fs, fd->file_nbr); - - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - - SPIFFS_UNLOCK(fs); - - return res; -#endif // SPIFFS_READ_ONLY -} - -spiffs_DIR *SPIFFS_opendir(spiffs *fs, const char *name, spiffs_DIR *d) { - (void)name; - - if (!SPIFFS_CHECK_CFG((fs))) { - (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; - return 0; - } - - if (!SPIFFS_CHECK_MOUNT(fs)) { - fs->err_code = SPIFFS_ERR_NOT_MOUNTED; - return 0; - } - - d->fs = fs; - d->block = 0; - d->entry = 0; - return d; -} - -static s32_t spiffs_read_dir_v( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_block_ix bix, - int ix_entry, - const void *user_const_p, - void *user_var_p) { - (void)user_const_p; - s32_t res; - spiffs_page_object_ix_header objix_hdr; - if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || - (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { - return SPIFFS_VIS_COUNTINUE; - } - - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - if (res != SPIFFS_OK) return res; - if ((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && - objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags& (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - struct spiffs_dirent *e = (struct spiffs_dirent*)user_var_p; - e->obj_id = obj_id; - strcpy((char *)e->name, (char *)objix_hdr.name); - e->type = objix_hdr.type; - e->size = objix_hdr.size == SPIFFS_UNDEFINED_LEN ? 0 : objix_hdr.size; - e->pix = pix; - return SPIFFS_OK; - } - - return SPIFFS_VIS_COUNTINUE; -} - -struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) { - if (!SPIFFS_CHECK_MOUNT(d->fs)) { - d->fs->err_code = SPIFFS_ERR_NOT_MOUNTED; - return 0; - } - SPIFFS_LOCK(d->fs); - - spiffs_block_ix bix; - int entry; - s32_t res; - struct spiffs_dirent *ret = 0; - - res = spiffs_obj_lu_find_entry_visitor(d->fs, - d->block, - d->entry, - SPIFFS_VIS_NO_WRAP, - 0, - spiffs_read_dir_v, - 0, - e, - &bix, - &entry); - if (res == SPIFFS_OK) { - d->block = bix; - d->entry = entry + 1; - ret = e; - } else { - d->fs->err_code = res; - } - SPIFFS_UNLOCK(d->fs); - return ret; -} - -s32_t SPIFFS_closedir(spiffs_DIR *d) { - SPIFFS_API_CHECK_CFG(d->fs); - SPIFFS_API_CHECK_MOUNT(d->fs); - return 0; -} - -s32_t SPIFFS_check(spiffs *fs) { -#if SPIFFS_READ_ONLY - (void)fs; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - res = spiffs_lookup_consistency_check(fs, 0); - - res = spiffs_object_index_consistency_check(fs); - - res = spiffs_page_consistency_check(fs); - - res = spiffs_obj_lu_scan(fs); - - SPIFFS_UNLOCK(fs); - return res; -#endif // SPIFFS_READ_ONLY -} - -s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) { - s32_t res = SPIFFS_OK; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - u32_t pages_per_block = SPIFFS_PAGES_PER_BLOCK(fs); - u32_t blocks = fs->block_count; - u32_t obj_lu_pages = SPIFFS_OBJ_LOOKUP_PAGES(fs); - u32_t data_page_size = SPIFFS_DATA_PAGE_SIZE(fs); - u32_t total_data_pages = (blocks - 2) * (pages_per_block - obj_lu_pages) + 1; // -2 for spare blocks, +1 for emergency page - - if (total) { - *total = total_data_pages * data_page_size; - } - - if (used) { - *used = fs->stats_p_allocated * data_page_size; - } - - SPIFFS_UNLOCK(fs); - return res; -} - -s32_t SPIFFS_gc_quick(spiffs *fs, u16_t max_free_pages) { -#if SPIFFS_READ_ONLY - (void)fs; (void)max_free_pages; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - res = spiffs_gc_quick(fs, max_free_pages); - - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY -} - - -s32_t SPIFFS_gc(spiffs *fs, u32_t size) { -#if SPIFFS_READ_ONLY - (void)fs; (void)size; - return SPIFFS_ERR_RO_NOT_IMPL; -#else - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - res = spiffs_gc_check(fs, size); - - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - SPIFFS_UNLOCK(fs); - return 0; -#endif // SPIFFS_READ_ONLY -} - -s32_t SPIFFS_eof(spiffs *fs, spiffs_file fh) { - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - fh = SPIFFS_FH_UNOFFS(fs, fh); - - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - -#if SPIFFS_CACHE_WR - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); -#endif - - res = (fd->fdoffset >= (fd->size == SPIFFS_UNDEFINED_LEN ? 0 : fd->size)); - - SPIFFS_UNLOCK(fs); - return res; -} - -s32_t SPIFFS_tell(spiffs *fs, spiffs_file fh) { - s32_t res; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - fh = SPIFFS_FH_UNOFFS(fs, fh); - - spiffs_fd *fd; - res = spiffs_fd_get(fs, fh, &fd); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); - -#if SPIFFS_CACHE_WR - res = spiffs_fflush_cache(fs, fh); - SPIFFS_API_CHECK_RES_UNLOCK(fs, res); -#endif - - res = fd->fdoffset; - - SPIFFS_UNLOCK(fs); - return res; -} - -s32_t SPIFFS_set_file_callback_func(spiffs *fs, spiffs_file_callback cb_func) { - SPIFFS_LOCK(fs); - fs->file_cb_f = cb_func; - SPIFFS_UNLOCK(fs); - return 0; -} - -#if SPIFFS_TEST_VISUALISATION -s32_t SPIFFS_vis(spiffs *fs) { - s32_t res = SPIFFS_OK; - SPIFFS_API_CHECK_CFG(fs); - SPIFFS_API_CHECK_MOUNT(fs); - SPIFFS_LOCK(fs); - - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - spiffs_block_ix bix = 0; - - while (bix < fs->block_count) { - // check each object lookup page - int obj_lookup_page = 0; - int cur_entry = 0; - - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, bix * SPIFFS_CFG_LOG_BLOCK_SZ(fs) + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && cur_entry < (int)(SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs))) { - spiffs_obj_id obj_id = obj_lu_buf[cur_entry-entry_offset]; - if (cur_entry == 0) { - spiffs_printf("%4i ", bix); - } else if ((cur_entry & 0x3f) == 0) { - spiffs_printf(" "); - } - if (obj_id == SPIFFS_OBJ_ID_FREE) { - spiffs_printf(SPIFFS_TEST_VIS_FREE_STR); - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - spiffs_printf(SPIFFS_TEST_VIS_DELE_STR); - } else if (obj_id & SPIFFS_OBJ_ID_IX_FLAG){ - spiffs_printf(SPIFFS_TEST_VIS_INDX_STR(obj_id)); - } else { - spiffs_printf(SPIFFS_TEST_VIS_DATA_STR(obj_id)); - } - cur_entry++; - if ((cur_entry & 0x3f) == 0) { - spiffs_printf("\n"); - } - } // per entry - obj_lookup_page++; - } // per object lookup page - - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, SPIFFS_OP_C_READ | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); - - if (erase_count != (spiffs_obj_id)-1) { - spiffs_printf("\tera_cnt: %i\n", erase_count); - } else { - spiffs_printf("\tera_cnt: N/A\n"); - } - - bix++; - } // per block - - spiffs_printf("era_cnt_max: %i\n", fs->max_erase_count); - spiffs_printf("last_errno: %i\n", fs->err_code); - spiffs_printf("blocks: %i\n", fs->block_count); - spiffs_printf("free_blocks: %i\n", fs->free_blocks); - spiffs_printf("page_alloc: %i\n", fs->stats_p_allocated); - spiffs_printf("page_delet: %i\n", fs->stats_p_deleted); - u32_t total, used; - SPIFFS_info(fs, &total, &used); - spiffs_printf("used: %i of %i\n", used, total); - - SPIFFS_UNLOCK(fs); - return res; -} -#endif diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_nucleus.c b/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_nucleus.c deleted file mode 100644 index 8a3c72530..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_nucleus.c +++ /dev/null @@ -1,2005 +0,0 @@ -#include "spiffs.h" -#include "spiffs_nucleus.h" - -static s32_t spiffs_page_data_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) { - s32_t res = SPIFFS_OK; - if (pix == (spiffs_page_ix)-1) { - // referring to page 0xffff...., bad object index - return SPIFFS_ERR_INDEX_REF_FREE; - } - if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - // referring to an object lookup page, bad object index - return SPIFFS_ERR_INDEX_REF_LU; - } - if (pix > SPIFFS_MAX_PAGES(fs)) { - // referring to a bad page - return SPIFFS_ERR_INDEX_REF_INVALID; - } -#if SPIFFS_PAGE_CHECK - spiffs_page_header ph; - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, pix), - sizeof(spiffs_page_header), - (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_DATA(ph, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, spix); -#endif - return res; -} - -#if !SPIFFS_READ_ONLY -static s32_t spiffs_page_index_check(spiffs *fs, spiffs_fd *fd, spiffs_page_ix pix, spiffs_span_ix spix) { - s32_t res = SPIFFS_OK; - if (pix == (spiffs_page_ix)-1) { - // referring to page 0xffff...., bad object index - return SPIFFS_ERR_INDEX_FREE; - } - if (pix % SPIFFS_PAGES_PER_BLOCK(fs) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - // referring to an object lookup page, bad object index - return SPIFFS_ERR_INDEX_LU; - } - if (pix > SPIFFS_MAX_PAGES(fs)) { - // referring to a bad page - return SPIFFS_ERR_INDEX_INVALID; - } -#if SPIFFS_PAGE_CHECK - spiffs_page_header ph; - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, pix), - sizeof(spiffs_page_header), - (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(ph, fd->obj_id, spix); -#endif - return res; -} -#endif // !SPIFFS_READ_ONLY - -#if !SPIFFS_CACHE - -s32_t spiffs_phys_rd( - spiffs *fs, - u32_t addr, - u32_t len, - u8_t *dst) { - return SPIFFS_HAL_READ(fs, addr, len, dst); -} - -s32_t spiffs_phys_wr( - spiffs *fs, - u32_t addr, - u32_t len, - u8_t *src) { - return SPIFFS_HAL_WRITE(fs, addr, len, src); -} - -#endif - -#if !SPIFFS_READ_ONLY -s32_t spiffs_phys_cpy( - spiffs *fs, - spiffs_file fh, - u32_t dst, - u32_t src, - u32_t len) { - (void)fh; - s32_t res; - u8_t b[SPIFFS_COPY_BUFFER_STACK]; - while (len > 0) { - u32_t chunk_size = MIN(SPIFFS_COPY_BUFFER_STACK, len); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVS, fh, src, chunk_size, b); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_MOVD, fh, dst, chunk_size, b); - SPIFFS_CHECK_RES(res); - len -= chunk_size; - src += chunk_size; - dst += chunk_size; - } - return SPIFFS_OK; -} -#endif // !SPIFFS_READ_ONLY - -// Find object lookup entry containing given id with visitor. -// Iterate over object lookup pages in each block until a given object id entry is found. -// When found, the visitor function is called with block index, entry index and user data. -// If visitor returns SPIFFS_VIS_CONTINUE, the search goes on. Otherwise, the search will be -// ended and visitor's return code is returned to caller. -// If no visitor is given (0) the search returns on first entry with matching object id. -// If no match is found in all look up, SPIFFS_VIS_END is returned. -// @param fs the file system -// @param starting_block the starting block to start search in -// @param starting_lu_entry the look up index entry to start search in -// @param flags ored combination of SPIFFS_VIS_CHECK_ID, SPIFFS_VIS_CHECK_PH, -// SPIFFS_VIS_NO_WRAP -// @param obj_id argument object id -// @param v visitor callback function -// @param user_const_p any const pointer, passed to the callback visitor function -// @param user_var_p any pointer, passed to the callback visitor function -// @param block_ix reported block index where match was found -// @param lu_entry reported look up index where match was found -s32_t spiffs_obj_lu_find_entry_visitor( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - u8_t flags, - spiffs_obj_id obj_id, - spiffs_visitor_f v, - const void *user_const_p, - void *user_var_p, - spiffs_block_ix *block_ix, - int *lu_entry) { - s32_t res = SPIFFS_OK; - s32_t entry_count = fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs); - spiffs_block_ix cur_block = starting_block; - u32_t cur_block_addr = starting_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); - - spiffs_obj_id *obj_lu_buf = (spiffs_obj_id *)fs->lu_work; - int cur_entry = starting_lu_entry; - int entries_per_page = (SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(spiffs_obj_id)); - - // wrap initial - if (cur_entry >= (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) - 1) { - cur_entry = 0; - cur_block++; - cur_block_addr = cur_block * SPIFFS_CFG_LOG_BLOCK_SZ(fs); - if (cur_block >= fs->block_count) { - if (flags & SPIFFS_VIS_NO_WRAP) { - return SPIFFS_VIS_END; - } else { - // block wrap - cur_block = 0; - cur_block_addr = 0; - } - } - } - - // check each block - while (res == SPIFFS_OK && entry_count > 0) { - int obj_lookup_page = cur_entry / entries_per_page; - // check each object lookup page - while (res == SPIFFS_OK && obj_lookup_page < (int)SPIFFS_OBJ_LOOKUP_PAGES(fs)) { - int entry_offset = obj_lookup_page * entries_per_page; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - // check each entry - while (res == SPIFFS_OK && - cur_entry - entry_offset < entries_per_page && // for non-last obj lookup pages - cur_entry < (int)SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) // for last obj lookup page - { - if ((flags & SPIFFS_VIS_CHECK_ID) == 0 || obj_lu_buf[cur_entry-entry_offset] == obj_id) { - if (block_ix) *block_ix = cur_block; - if (lu_entry) *lu_entry = cur_entry; - if (v) { - res = v( - fs, - (flags & SPIFFS_VIS_CHECK_PH) ? obj_id : obj_lu_buf[cur_entry-entry_offset], - cur_block, - cur_entry, - user_const_p, - user_var_p); - if (res == SPIFFS_VIS_COUNTINUE || res == SPIFFS_VIS_COUNTINUE_RELOAD) { - if (res == SPIFFS_VIS_COUNTINUE_RELOAD) { - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, cur_block_addr + SPIFFS_PAGE_TO_PADDR(fs, obj_lookup_page), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->lu_work); - SPIFFS_CHECK_RES(res); - } - res = SPIFFS_OK; - cur_entry++; - entry_count--; - continue; - } else { - return res; - } - } else { - return SPIFFS_OK; - } - } - entry_count--; - cur_entry++; - } // per entry - obj_lookup_page++; - } // per object lookup page - cur_entry = 0; - cur_block++; - cur_block_addr += SPIFFS_CFG_LOG_BLOCK_SZ(fs); - if (cur_block >= fs->block_count) { - if (flags & SPIFFS_VIS_NO_WRAP) { - return SPIFFS_VIS_END; - } else { - // block wrap - cur_block = 0; - cur_block_addr = 0; - } - } - } // per block - - SPIFFS_CHECK_RES(res); - - return SPIFFS_VIS_END; -} - -#if !SPIFFS_READ_ONLY -s32_t spiffs_erase_block( - spiffs *fs, - spiffs_block_ix bix) { - s32_t res; - u32_t addr = SPIFFS_BLOCK_TO_PADDR(fs, bix); - s32_t size = SPIFFS_CFG_LOG_BLOCK_SZ(fs); - - // here we ignore res, just try erasing the block - while (size > 0) { - SPIFFS_DBG("erase %08x:%08x\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); - SPIFFS_HAL_ERASE(fs, addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs)); - - addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs); - size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs); - } - fs->free_blocks++; - - // register erase count for this block - res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_ERASE_COUNT_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&fs->max_erase_count); - SPIFFS_CHECK_RES(res); - -#if SPIFFS_USE_MAGIC - // finally, write magic - spiffs_obj_id magic = SPIFFS_MAGIC(fs, bix); - res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0, - SPIFFS_MAGIC_PADDR(fs, bix), - sizeof(spiffs_obj_id), (u8_t *)&magic); - SPIFFS_CHECK_RES(res); -#endif - - fs->max_erase_count++; - if (fs->max_erase_count == SPIFFS_OBJ_ID_IX_FLAG) { - fs->max_erase_count = 0; - } - - return res; -} -#endif // !SPIFFS_READ_ONLY - -#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 -s32_t spiffs_probe( - spiffs_config *cfg) { - s32_t res; - u32_t paddr; - spiffs dummy_fs; // create a dummy fs struct just to be able to use macros - memcpy(&dummy_fs.cfg, cfg, sizeof(spiffs_config)); - dummy_fs.block_count = 0; - - // Read three magics, as one block may be in an aborted erase state. - // At least two of these must contain magic and be in decreasing order. - spiffs_obj_id magic[3]; - spiffs_obj_id bix_count[3]; - - spiffs_block_ix bix; - for (bix = 0; bix < 3; bix++) { - paddr = SPIFFS_MAGIC_PADDR(&dummy_fs, bix); -#if SPIFFS_HAL_CALLBACK_EXTRA - // not any proper fs to report here, so callback with null - // (cross fingers that no-one gets angry) - res = cfg->hal_read_f((void *)0, paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); -#else - res = cfg->hal_read_f(paddr, sizeof(spiffs_obj_id), (u8_t *)&magic[bix]); -#endif - bix_count[bix] = magic[bix] ^ SPIFFS_MAGIC(&dummy_fs, 0); - SPIFFS_CHECK_RES(res); - } - - // check that we have sane number of blocks - if (bix_count[0] < 3) return SPIFFS_ERR_PROBE_TOO_FEW_BLOCKS; - // check that the order is correct, take aborted erases in calculation - // first block aborted erase - if (magic[0] == (spiffs_obj_id)(-1) && bix_count[1] - bix_count[2] == 1) { - return (bix_count[1]+1) * cfg->log_block_size; - } - // second block aborted erase - if (magic[1] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[2] == 2) { - return bix_count[0] * cfg->log_block_size; - } - // third block aborted erase - if (magic[2] == (spiffs_obj_id)(-1) && bix_count[0] - bix_count[1] == 1) { - return bix_count[0] * cfg->log_block_size; - } - // no block has aborted erase - if (bix_count[0] - bix_count[1] == 1 && bix_count[1] - bix_count[2] == 1) { - return bix_count[0] * cfg->log_block_size; - } - - return SPIFFS_ERR_PROBE_NOT_A_FS; -} -#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH && SPIFFS_SINGLETON==0 - - -static s32_t spiffs_obj_lu_scan_v( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_block_ix bix, - int ix_entry, - const void *user_const_p, - void *user_var_p) { - (void)bix; - (void)user_const_p; - (void)user_var_p; - if (obj_id == SPIFFS_OBJ_ID_FREE) { - if (ix_entry == 0) { - fs->free_blocks++; - // todo optimize further, return SPIFFS_NEXT_BLOCK - } - } else if (obj_id == SPIFFS_OBJ_ID_DELETED) { - fs->stats_p_deleted++; - } else { - fs->stats_p_allocated++; - } - - return SPIFFS_VIS_COUNTINUE; -} - - -// Scans thru all obj lu and counts free, deleted and used pages -// Find the maximum block erase count -// Checks magic if enabled -s32_t spiffs_obj_lu_scan( - spiffs *fs) { - s32_t res; - spiffs_block_ix bix; - int entry; -#if SPIFFS_USE_MAGIC - spiffs_block_ix unerased_bix = (spiffs_block_ix)-1; -#endif - - // find out erase count - // if enabled, check magic - bix = 0; - spiffs_obj_id erase_count_final; - spiffs_obj_id erase_count_min = SPIFFS_OBJ_ID_FREE; - spiffs_obj_id erase_count_max = 0; - while (bix < fs->block_count) { -#if SPIFFS_USE_MAGIC - spiffs_obj_id magic; - res = _spiffs_rd(fs, - SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_MAGIC_PADDR(fs, bix) , - sizeof(spiffs_obj_id), (u8_t *)&magic); - - SPIFFS_CHECK_RES(res); - if (magic != SPIFFS_MAGIC(fs, bix)) { - if (unerased_bix == (spiffs_block_ix)-1) { - // allow one unerased block as it might be powered down during an erase - unerased_bix = bix; - } else { - // more than one unerased block, bail out - SPIFFS_CHECK_RES(SPIFFS_ERR_NOT_A_FS); - } - } -#endif - spiffs_obj_id erase_count; - res = _spiffs_rd(fs, - SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_ERASE_COUNT_PADDR(fs, bix) , - sizeof(spiffs_obj_id), (u8_t *)&erase_count); - SPIFFS_CHECK_RES(res); - if (erase_count != SPIFFS_OBJ_ID_FREE) { - erase_count_min = MIN(erase_count_min, erase_count); - erase_count_max = MAX(erase_count_max, erase_count); - } - bix++; - } - - if (erase_count_min == 0 && erase_count_max == SPIFFS_OBJ_ID_FREE) { - // clean system, set counter to zero - erase_count_final = 0; - } else if (erase_count_max - erase_count_min > (SPIFFS_OBJ_ID_FREE)/2) { - // wrap, take min - erase_count_final = erase_count_min+1; - } else { - erase_count_final = erase_count_max+1; - } - - fs->max_erase_count = erase_count_final; - -#if SPIFFS_USE_MAGIC - if (unerased_bix != (spiffs_block_ix)-1) { - // found one unerased block, remedy - SPIFFS_DBG("mount: erase block %i\n", bix); -#if SPIFFS_READ_ONLY - res = SPIFFS_ERR_RO_ABORTED_OPERATION; -#else - res = spiffs_erase_block(fs, unerased_bix); -#endif // SPIFFS_READ_ONLY - SPIFFS_CHECK_RES(res); - } -#endif - - // count blocks - - fs->free_blocks = 0; - fs->stats_p_allocated = 0; - fs->stats_p_deleted = 0; - - res = spiffs_obj_lu_find_entry_visitor(fs, - 0, - 0, - 0, - 0, - spiffs_obj_lu_scan_v, - 0, - 0, - &bix, - &entry); - - if (res == SPIFFS_VIS_END) { - res = SPIFFS_OK; - } - - SPIFFS_CHECK_RES(res); - - return res; -} - -#if !SPIFFS_READ_ONLY -// Find free object lookup entry -// Iterate over object lookup pages in each block until a free object id entry is found -s32_t spiffs_obj_lu_find_free( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - spiffs_block_ix *block_ix, - int *lu_entry) { - s32_t res; - if (!fs->cleaning && fs->free_blocks < 2) { - res = spiffs_gc_quick(fs, 0); - if (res == SPIFFS_ERR_NO_DELETED_BLOCKS) { - res = SPIFFS_OK; - } - SPIFFS_CHECK_RES(res); - if (fs->free_blocks < 2) { - return SPIFFS_ERR_FULL; - } - } - res = spiffs_obj_lu_find_id(fs, starting_block, starting_lu_entry, - SPIFFS_OBJ_ID_FREE, block_ix, lu_entry); - if (res == SPIFFS_OK) { - fs->free_cursor_block_ix = *block_ix; - fs->free_cursor_obj_lu_entry = *lu_entry; - if (*lu_entry == 0) { - fs->free_blocks--; - } - } - if (res == SPIFFS_ERR_FULL) { - SPIFFS_DBG("fs full\n"); - } - - return res; -} -#endif // !SPIFFS_READ_ONLY - -// Find object lookup entry containing given id -// Iterate over object lookup pages in each block until a given object id entry is found -s32_t spiffs_obj_lu_find_id( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - spiffs_obj_id obj_id, - spiffs_block_ix *block_ix, - int *lu_entry) { - s32_t res = spiffs_obj_lu_find_entry_visitor( - fs, starting_block, starting_lu_entry, SPIFFS_VIS_CHECK_ID, obj_id, 0, 0, 0, block_ix, lu_entry); - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - return res; -} - - -static s32_t spiffs_obj_lu_find_id_and_span_v( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_block_ix bix, - int ix_entry, - const void *user_const_p, - void *user_var_p) { - s32_t res; - spiffs_page_header ph; - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - res = _spiffs_rd(fs, 0, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_header), (u8_t *)&ph); - SPIFFS_CHECK_RES(res); - if (ph.obj_id == obj_id && - ph.span_ix == *((spiffs_span_ix*)user_var_p) && - (ph.flags & (SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED)) == SPIFFS_PH_FLAG_DELET && - !((obj_id & SPIFFS_OBJ_ID_IX_FLAG) && (ph.flags & SPIFFS_PH_FLAG_IXDELE) == 0 && ph.span_ix == 0) && - (user_const_p == 0 || *((const spiffs_page_ix*)user_const_p) != pix)) { - return SPIFFS_OK; - } else { - return SPIFFS_VIS_COUNTINUE; - } -} - -// Find object lookup entry containing given id and span index -// Iterate over object lookup pages in each block until a given object id entry is found -s32_t spiffs_obj_lu_find_id_and_span( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix spix, - spiffs_page_ix exclusion_pix, - spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - SPIFFS_VIS_CHECK_ID, - obj_id, - spiffs_obj_lu_find_id_and_span_v, - exclusion_pix ? &exclusion_pix : 0, - &spix, - &bix, - &entry); - - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - - SPIFFS_CHECK_RES(res); - - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; - - return res; -} - -// Find object lookup entry containing given id and span index in page headers only -// Iterate over object lookup pages in each block until a given object id entry is found -s32_t spiffs_obj_lu_find_id_and_span_by_phdr( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix spix, - spiffs_page_ix exclusion_pix, - spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - SPIFFS_VIS_CHECK_PH, - obj_id, - spiffs_obj_lu_find_id_and_span_v, - exclusion_pix ? &exclusion_pix : 0, - &spix, - &bix, - &entry); - - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - - SPIFFS_CHECK_RES(res); - - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; - - return res; -} - -#if !SPIFFS_READ_ONLY -// Allocates a free defined page with given obj_id -// Occupies object lookup entry and page -// data may be NULL; where only page header is stored, len and page_offs is ignored -s32_t spiffs_page_allocate_data( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_page_header *ph, - u8_t *data, - u32_t len, - u32_t page_offs, - u8_t finalize, - spiffs_page_ix *pix) { - s32_t res = SPIFFS_OK; - spiffs_block_ix bix; - int entry; - - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - - // occupy page in object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t*)&obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_allocated++; - - // write page header - ph->flags &= ~SPIFFS_PH_FLAG_USED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_header), (u8_t*)ph); - SPIFFS_CHECK_RES(res); - - // write page data - if (data) { - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0,SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + sizeof(spiffs_page_header) + page_offs, len, data); - SPIFFS_CHECK_RES(res); - } - - // finalize header if necessary - if (finalize && (ph->flags & SPIFFS_PH_FLAG_FINAL)) { - ph->flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&ph->flags); - SPIFFS_CHECK_RES(res); - } - - // return written page - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - return res; -} -#endif // !SPIFFS_READ_ONLY - -#if !SPIFFS_READ_ONLY -// Moves a page from src to a free page and finalizes it. Updates page index. Page data is given in param page. -// If page data is null, provided header is used for metainfo and page data is physically copied. -s32_t spiffs_page_move( - spiffs *fs, - spiffs_file fh, - u8_t *page_data, - spiffs_obj_id obj_id, - spiffs_page_header *page_hdr, - spiffs_page_ix src_pix, - spiffs_page_ix *dst_pix) { - s32_t res; - u8_t was_final = 0; - spiffs_page_header *p_hdr; - spiffs_block_ix bix; - int entry; - spiffs_page_ix free_pix; - - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - free_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - - if (dst_pix) *dst_pix = free_pix; - - p_hdr = page_data ? (spiffs_page_header *)page_data : page_hdr; - if (page_data) { - // got page data - was_final = (p_hdr->flags & SPIFFS_PH_FLAG_FINAL) == 0; - // write unfinalized page - p_hdr->flags |= SPIFFS_PH_FLAG_FINAL; - p_hdr->flags &= ~SPIFFS_PH_FLAG_USED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), page_data); - } else { - // copy page data - res = spiffs_phys_cpy(fs, fh, SPIFFS_PAGE_TO_PADDR(fs, free_pix), SPIFFS_PAGE_TO_PADDR(fs, src_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs)); - } - SPIFFS_CHECK_RES(res); - - // mark entry in destination object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, free_pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, free_pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_allocated++; - - if (was_final) { - // mark finalized in destination page - p_hdr->flags &= ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_USED); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fh, - SPIFFS_PAGE_TO_PADDR(fs, free_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr->flags); - SPIFFS_CHECK_RES(res); - } - // mark source deleted - res = spiffs_page_delete(fs, src_pix); - return res; -} -#endif // !SPIFFS_READ_ONLY - -#if !SPIFFS_READ_ONLY -// Deletes a page and removes it from object lookup. -s32_t spiffs_page_delete( - spiffs *fs, - spiffs_page_ix pix) { - s32_t res; - spiffs_page_header hdr; - hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_USED); - // mark deleted entry in source object lookup - spiffs_obj_id d_obj_id = SPIFFS_OBJ_ID_DELETED; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_DELE, - 0, - SPIFFS_BLOCK_TO_PADDR(fs, SPIFFS_BLOCK_FOR_PAGE(fs, pix)) + SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix) * sizeof(spiffs_page_ix), - sizeof(spiffs_obj_id), - (u8_t *)&d_obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_deleted++; - fs->stats_p_allocated--; - - // mark deleted in source page - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_DELE, - 0, - SPIFFS_PAGE_TO_PADDR(fs, pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&hdr.flags); - - return res; -} -#endif // !SPIFFS_READ_ONLY - -#if !SPIFFS_READ_ONLY -// Create an object index header page with empty index and undefined length -s32_t spiffs_object_create( - spiffs *fs, - spiffs_obj_id obj_id, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - spiffs_obj_type type, - spiffs_page_ix *objix_hdr_pix) { - s32_t res = SPIFFS_OK; - spiffs_block_ix bix; - spiffs_page_object_ix_header oix_hdr; - int entry; - - res = spiffs_gc_check(fs, SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); - - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - - // find free entry - res = spiffs_obj_lu_find_free(fs, fs->free_cursor_block_ix, fs->free_cursor_obj_lu_entry, &bix, &entry); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("create: found free page @ %04x bix:%i entry:%i\n", SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), bix, entry); - - // occupy page in object lookup - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_UPDT, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t*)&obj_id); - SPIFFS_CHECK_RES(res); - - fs->stats_p_allocated++; - - // write empty object index page - oix_hdr.p_hdr.obj_id = obj_id; - oix_hdr.p_hdr.span_ix = 0; - oix_hdr.p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_USED); - oix_hdr.type = type; - oix_hdr.size = SPIFFS_UNDEFINED_LEN; // keep ones so we can update later without wasting this page - strncpy((char*)&oix_hdr.name, (const char*)name, SPIFFS_OBJ_NAME_LEN); - - - // update page - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, bix, entry), sizeof(spiffs_page_object_ix_header), (u8_t*)&oix_hdr); - - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, 0, SPIFFS_EV_IX_NEW, obj_id, 0, SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry), SPIFFS_UNDEFINED_LEN); - - if (objix_hdr_pix) { - *objix_hdr_pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - return res; -} -#endif // !SPIFFS_READ_ONLY - -#if !SPIFFS_READ_ONLY -// update object index header with any combination of name/size/index -// new_objix_hdr_data may be null, if so the object index header page is loaded -// name may be null, if so name is not changed -// size may be null, if so size is not changed -s32_t spiffs_object_update_index_hdr( - spiffs *fs, - spiffs_fd *fd, - spiffs_obj_id obj_id, - spiffs_page_ix objix_hdr_pix, - u8_t *new_objix_hdr_data, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - u32_t size, - spiffs_page_ix *new_pix) { - s32_t res = SPIFFS_OK; - spiffs_page_object_ix_header *objix_hdr; - spiffs_page_ix new_objix_hdr_pix; - - obj_id |= SPIFFS_OBJ_ID_IX_FLAG; - - if (new_objix_hdr_data) { - // object index header page already given to us, no need to load it - objix_hdr = (spiffs_page_object_ix_header *)new_objix_hdr_data; - } else { - // read object index header page - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_hdr_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - objix_hdr = (spiffs_page_object_ix_header *)fs->work; - } - - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, obj_id, 0); - - // change name - if (name) { - strncpy((char*)objix_hdr->name, (const char*)name, SPIFFS_OBJ_NAME_LEN); - } - if (size) { - objix_hdr->size = size; - } - - // move and update page - res = spiffs_page_move(fs, fd == 0 ? 0 : fd->file_nbr, (u8_t*)objix_hdr, obj_id, 0, objix_hdr_pix, &new_objix_hdr_pix); - - if (res == SPIFFS_OK) { - if (new_pix) { - *new_pix = new_objix_hdr_pix; - } - // callback on object index update - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, obj_id, objix_hdr->p_hdr.span_ix, new_objix_hdr_pix, objix_hdr->size); - if (fd) fd->objix_hdr_pix = new_objix_hdr_pix; // if this is not in the registered cluster - } - - return res; -} -#endif // !SPIFFS_READ_ONLY - -void spiffs_cb_object_event( - spiffs *fs, - spiffs_fd *fd, - int ev, - spiffs_obj_id obj_id_raw, - spiffs_span_ix spix, - spiffs_page_ix new_pix, - u32_t new_size) { - (void)fd; - // update index caches in all file descriptors - spiffs_obj_id obj_id = obj_id_raw & ~SPIFFS_OBJ_ID_IX_FLAG; - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr == 0 || (cur_fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG) != obj_id) continue; - if (spix == 0) { - if (ev == SPIFFS_EV_IX_NEW || ev == SPIFFS_EV_IX_UPD) { - SPIFFS_DBG(" callback: setting fd %i:%04x objix_hdr_pix to %04x, size:%i\n", cur_fd->file_nbr, cur_fd->obj_id, new_pix, new_size); - cur_fd->objix_hdr_pix = new_pix; - if (new_size != 0) { - cur_fd->size = new_size; - } - } else if (ev == SPIFFS_EV_IX_DEL) { - cur_fd->file_nbr = 0; - cur_fd->obj_id = SPIFFS_OBJ_ID_DELETED; - } - } - if (cur_fd->cursor_objix_spix == spix) { - if (ev == SPIFFS_EV_IX_NEW || ev == SPIFFS_EV_IX_UPD) { - SPIFFS_DBG(" callback: setting fd %i:%04x span:%04x objix_pix to %04x\n", cur_fd->file_nbr, cur_fd->obj_id, spix, new_pix); - cur_fd->cursor_objix_pix = new_pix; - } else { - cur_fd->cursor_objix_pix = 0; - } - } - } - - // callback to user if object index header - if (fs->file_cb_f && spix == 0 && (obj_id_raw & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_fileop_type op; - if (ev == SPIFFS_EV_IX_NEW) { - op = SPIFFS_CB_CREATED; - } else if (ev == SPIFFS_EV_IX_UPD) { - op = SPIFFS_CB_UPDATED; - } else if (ev == SPIFFS_EV_IX_DEL) { - op = SPIFFS_CB_DELETED; - } else { - SPIFFS_DBG(" callback: WARNING unknown callback event %02x\n", ev); - return; // bail out - } - fs->file_cb_f(fs, op, obj_id, new_pix); - } -} - -// Open object by id -s32_t spiffs_object_open_by_id( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_fd *fd, - spiffs_flags flags, - spiffs_mode mode) { - s32_t res = SPIFFS_OK; - spiffs_page_ix pix; - - res = spiffs_obj_lu_find_id_and_span(fs, obj_id | SPIFFS_OBJ_ID_IX_FLAG, 0, 0, &pix); - SPIFFS_CHECK_RES(res); - - res = spiffs_object_open_by_page(fs, pix, fd, flags, mode); - - return res; -} - -// Open object by page index -s32_t spiffs_object_open_by_page( - spiffs *fs, - spiffs_page_ix pix, - spiffs_fd *fd, - spiffs_flags flags, - spiffs_mode mode) { - (void)mode; - s32_t res = SPIFFS_OK; - spiffs_page_object_ix_header oix_hdr; - spiffs_obj_id obj_id; - - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&oix_hdr); - SPIFFS_CHECK_RES(res); - - spiffs_block_ix bix = SPIFFS_BLOCK_FOR_PAGE(fs, pix); - int entry = SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, pix); - - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU | SPIFFS_OP_C_READ, - 0, SPIFFS_BLOCK_TO_PADDR(fs, bix) + entry * sizeof(spiffs_obj_id), sizeof(spiffs_obj_id), (u8_t *)&obj_id); - - fd->fs = fs; - fd->objix_hdr_pix = pix; - fd->size = oix_hdr.size; - fd->offset = 0; - fd->cursor_objix_pix = pix; - fd->cursor_objix_spix = 0; - fd->obj_id = obj_id; - fd->flags = flags; - - SPIFFS_VALIDATE_OBJIX(oix_hdr.p_hdr, fd->obj_id, 0); - - SPIFFS_DBG("open: fd %i is obj id %04x\n", fd->file_nbr, fd->obj_id); - - return res; -} - -#if !SPIFFS_READ_ONLY -// Append to object -// keep current object index (header) page in fs->work buffer -s32_t spiffs_object_append(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { - spiffs *fs = fd->fs; - s32_t res = SPIFFS_OK; - u32_t written = 0; - - SPIFFS_DBG("append: %i bytes @ offs %i of size %i\n", len, offset, fd->size); - - if (offset > fd->size) { - SPIFFS_DBG("append: offset reversed to size\n"); - offset = fd->size; - } - - res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); // add an extra page of data worth for meta - if (res != SPIFFS_OK) { - SPIFFS_DBG("append: gc check fail %i\n", res); - } - SPIFFS_CHECK_RES(res); - - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_header p_hdr; - - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; - spiffs_page_ix new_objix_hdr_page; - - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_page_ix data_page; - u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); - - // write all data - while (res == SPIFFS_OK && written < len) { - // calculate object index page span index - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - - // handle storing and loading of object indices - if (cur_objix_spix != prev_objix_spix) { - // new object index page - // within this clause we return directly if something fails, object index mess-up - if (written > 0) { - // store previous object index page, unless first pass - SPIFFS_DBG("append: %04x store objix %04x:%04x, written %i\n", fd->obj_id, - cur_objix_pix, prev_objix_spix, written); - if (prev_objix_spix == 0) { - // this is an update to object index header page - objix_hdr->size = offset+written; - if (offset == 0) { - // was an empty object, update same page (size was 0xffffffff) - res = spiffs_page_index_check(fs, fd, cur_objix_pix, 0); - SPIFFS_CHECK_RES(res); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - } else { - // was a nonempty object, update to new page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, offset+written, &new_objix_hdr_page); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("append: %04x store new objix_hdr, %04x:%04x, written %i\n", fd->obj_id, - new_objix_hdr_page, 0, written); - } - } else { - // this is an update to an object index page - res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); - SPIFFS_CHECK_RES(res); - - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD,fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); - // update length in object index header page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_CHECK_RES(res); - SPIFFS_DBG("append: %04x store new size I %i in objix_hdr, %04x:%04x, written %i\n", fd->obj_id, - offset+written, new_objix_hdr_page, 0, written); - } - fd->size = offset+written; - fd->offset = offset+written; - } - - // create or load new object index page - if (cur_objix_spix == 0) { - // load object index header page, must always exist - SPIFFS_DBG("append: %04x load objixhdr page %04x:%04x\n", fd->obj_id, cur_objix_pix, cur_objix_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - } else { - spiffs_span_ix len_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, (fd->size-1)/SPIFFS_DATA_PAGE_SIZE(fs)); - // on subsequent passes, create a new object index page - if (written > 0 || cur_objix_spix > len_objix_spix) { - p_hdr.obj_id = fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = cur_objix_spix; - p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_INDEX); - res = spiffs_page_allocate_data(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 1, &cur_objix_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_NEW, fd->obj_id, cur_objix_spix, cur_objix_pix, 0); - // quick "load" of new object index page - memset(fs->work, 0xff, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - memcpy(fs->work, &p_hdr, sizeof(spiffs_page_header)); - SPIFFS_DBG("append: %04x create objix page, %04x:%04x, written %i\n", fd->obj_id - , cur_objix_pix, cur_objix_spix, written); - } else { - // on first pass, we load existing object index page - spiffs_page_ix pix; - SPIFFS_DBG("append: %04x find objix span_ix:%04x\n", fd->obj_id, cur_objix_spix); - if (fd->cursor_objix_spix == cur_objix_spix) { - pix = fd->cursor_objix_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); - SPIFFS_CHECK_RES(res); - } - SPIFFS_DBG("append: %04x found object index at page %04x [fd size %i]\n", fd->obj_id, pix, fd->size); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - cur_objix_pix = pix; - } - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = offset+written; - fd->size = offset+written; - } - prev_objix_spix = cur_objix_spix; - } - - // write data - u32_t to_write = MIN(len-written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); - if (page_offs == 0) { - // at beginning of a page, allocate and write a new page of data - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff & ~(SPIFFS_PH_FLAG_FINAL); // finalize immediately - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, &data[written], to_write, page_offs, 1, &data_page); - SPIFFS_DBG("append: %04x store new data page, %04x:%04x offset:%i, len %i, written %i\n", fd->obj_id, - data_page, data_spix, page_offs, to_write, written); - } else { - // append to existing page, fill out free data in existing page - if (cur_objix_spix == 0) { - // get data page from object index header page - data_page = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - data_page = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } - - res = spiffs_page_data_check(fs, fd, data_page, data_spix); - SPIFFS_CHECK_RES(res); - - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, data_page) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); - SPIFFS_DBG("append: %04x store to existing data page, %04x:%04x offset:%i, len %i, written %i\n", fd->obj_id - , data_page, data_spix, page_offs, to_write, written); - } - - if (res != SPIFFS_OK) break; - - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_page; - SPIFFS_DBG("append: %04x wrote page %04x to objix_hdr entry %02x in mem\n", fd->obj_id - , data_page, data_spix); - objix_hdr->size = offset+written; - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_page; - SPIFFS_DBG("append: %04x wrote page %04x to objix entry %02x in mem\n", fd->obj_id - , data_page, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - - // update internals - page_offs = 0; - data_spix++; - written += to_write; - } // while all data - - fd->size = offset+written; - fd->offset = offset+written; - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - // finalize updated object indices - s32_t res2 = SPIFFS_OK; - if (cur_objix_spix != 0) { - // wrote beyond object index header page - // write last modified object index page, unless object header index page - SPIFFS_DBG("append: %04x store objix page, %04x:%04x, written %i\n", fd->obj_id, - cur_objix_pix, cur_objix_spix, written); - - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); - - res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res2); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, cur_objix_pix, 0); - - // update size in object header index page - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, offset+written, &new_objix_hdr_page); - SPIFFS_DBG("append: %04x store new size II %i in objix_hdr, %04x:%04x, written %i, res %i\n", fd->obj_id - , offset+written, new_objix_hdr_page, 0, written, res2); - SPIFFS_CHECK_RES(res2); - } else { - // wrote within object index header page - if (offset == 0) { - // wrote to empty object - simply update size and write whole page - objix_hdr->size = offset+written; - SPIFFS_DBG("append: %04x store fresh objix_hdr page, %04x:%04x, written %i\n", fd->obj_id - , cur_objix_pix, cur_objix_spix, written); - - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); - - res2 = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res2); - // callback on object index update - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix_hdr->p_hdr.span_ix, cur_objix_pix, objix_hdr->size); - } else { - // modifying object index header page, update size and make new copy - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, offset+written, &new_objix_hdr_page); - SPIFFS_DBG("append: %04x store modified objix_hdr page, %04x:%04x, written %i\n", fd->obj_id - , new_objix_hdr_page, 0, written); - SPIFFS_CHECK_RES(res2); - } - } - - return res; -} // spiffs_object_append -#endif // !SPIFFS_READ_ONLY - -#if !SPIFFS_READ_ONLY -// Modify object -// keep current object index (header) page in fs->work buffer -s32_t spiffs_object_modify(spiffs_fd *fd, u32_t offset, u8_t *data, u32_t len) { - spiffs *fs = fd->fs; - s32_t res = SPIFFS_OK; - u32_t written = 0; - - res = spiffs_gc_check(fs, len + SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_CHECK_RES(res); - - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_header p_hdr; - - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_ix cur_objix_pix = fd->objix_hdr_pix; - spiffs_page_ix new_objix_hdr_pix; - - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - spiffs_page_ix data_pix; - u32_t page_offs = offset % SPIFFS_DATA_PAGE_SIZE(fs); - - - // write all data - while (res == SPIFFS_OK && written < len) { - // calculate object index page span index - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - - // handle storing and loading of object indices - if (cur_objix_spix != prev_objix_spix) { - // new object index page - // within this clause we return directly if something fails, object index mess-up - if (written > 0) { - // store previous object index (header) page, unless first pass - if (prev_objix_spix == 0) { - // store previous object index header page - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, 0, &new_objix_hdr_pix); - SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %i\n", new_objix_hdr_pix, 0, written); - SPIFFS_CHECK_RES(res); - } else { - // store new version of previous object index page - spiffs_page_ix new_objix_pix; - - res = spiffs_page_index_check(fs, fd, cur_objix_pix, prev_objix_spix); - SPIFFS_CHECK_RES(res); - - res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); - SPIFFS_DBG("modify: store previous modified objix page, %04x:%04x, written %i\n", new_objix_pix, objix->p_hdr.span_ix, written); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - } - } - - // load next object index page - if (cur_objix_spix == 0) { - // load object index header page, must exist - SPIFFS_DBG("modify: load objixhdr page %04x:%04x\n", cur_objix_pix, cur_objix_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, cur_objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - } else { - // load existing object index page on first pass - spiffs_page_ix pix; - SPIFFS_DBG("modify: find objix span_ix:%04x\n", cur_objix_spix); - if (fd->cursor_objix_spix == cur_objix_spix) { - pix = fd->cursor_objix_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &pix); - SPIFFS_CHECK_RES(res); - } - SPIFFS_DBG("modify: found object index at page %04x\n", pix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - cur_objix_pix = pix; - } - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = offset+written; - prev_objix_spix = cur_objix_spix; - } - - // write partial data - u32_t to_write = MIN(len-written, SPIFFS_DATA_PAGE_SIZE(fs) - page_offs); - spiffs_page_ix orig_data_pix; - if (cur_objix_spix == 0) { - // get data page from object index header page - orig_data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - orig_data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } - - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff; - if (page_offs == 0 && to_write == SPIFFS_DATA_PAGE_SIZE(fs)) { - // a full page, allocate and write a new page of data - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, &data[written], to_write, page_offs, 1, &data_pix); - SPIFFS_DBG("modify: store new data page, %04x:%04x offset:%i, len %i, written %i\n", data_pix, data_spix, page_offs, to_write, written); - } else { - // write to existing page, allocate new and copy unmodified data - - res = spiffs_page_data_check(fs, fd, orig_data_pix, data_spix); - SPIFFS_CHECK_RES(res); - - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 0, &data_pix); - if (res != SPIFFS_OK) break; - - // copy unmodified data - if (page_offs > 0) { - // before modification - res = spiffs_phys_cpy(fs, fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header), - page_offs); - if (res != SPIFFS_OK) break; - } - if (page_offs + to_write < SPIFFS_DATA_PAGE_SIZE(fs)) { - // after modification - res = spiffs_phys_cpy(fs, fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, - SPIFFS_PAGE_TO_PADDR(fs, orig_data_pix) + sizeof(spiffs_page_header) + page_offs + to_write, - SPIFFS_DATA_PAGE_SIZE(fs) - (page_offs + to_write)); - if (res != SPIFFS_OK) break; - } - - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + page_offs, to_write, &data[written]); - if (res != SPIFFS_OK) break; - p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr.flags); - if (res != SPIFFS_OK) break; - - SPIFFS_DBG("modify: store to existing data page, src:%04x, dst:%04x:%04x offset:%i, len %i, written %i\n", orig_data_pix, data_pix, data_spix, page_offs, to_write, written); - } - - // delete original data page - res = spiffs_page_delete(fs, orig_data_pix); - if (res != SPIFFS_OK) break; - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = data_pix; - SPIFFS_DBG("modify: wrote page %04x to objix_hdr entry %02x in mem\n", data_pix, data_spix); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = data_pix; - SPIFFS_DBG("modify: wrote page %04x to objix entry %02x in mem\n", data_pix, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - - // update internals - page_offs = 0; - data_spix++; - written += to_write; - } // while all data - - fd->offset = offset+written; - fd->cursor_objix_pix = cur_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - // finalize updated object indices - s32_t res2 = SPIFFS_OK; - if (cur_objix_spix != 0) { - // wrote beyond object index header page - // write last modified object index page - // move and update page - spiffs_page_ix new_objix_pix; - - res2 = spiffs_page_index_check(fs, fd, cur_objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res2); - - res2 = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix, fd->obj_id, 0, cur_objix_pix, &new_objix_pix); - SPIFFS_DBG("modify: store modified objix page, %04x:%04x, written %i\n", new_objix_pix, cur_objix_spix, written); - fd->cursor_objix_pix = new_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - SPIFFS_CHECK_RES(res2); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - - } else { - // wrote within object index header page - res2 = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, fs->work, 0, 0, &new_objix_hdr_pix); - SPIFFS_DBG("modify: store modified objix_hdr page, %04x:%04x, written %i\n", new_objix_hdr_pix, 0, written); - SPIFFS_CHECK_RES(res2); - } - - return res; -} // spiffs_object_modify -#endif // !SPIFFS_READ_ONLY - -static s32_t spiffs_object_find_object_index_header_by_name_v( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_block_ix bix, - int ix_entry, - const void *user_const_p, - void *user_var_p) { - (void)user_var_p; - s32_t res; - spiffs_page_object_ix_header objix_hdr; - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - if (obj_id == SPIFFS_OBJ_ID_FREE || obj_id == SPIFFS_OBJ_ID_DELETED || - (obj_id & SPIFFS_OBJ_ID_IX_FLAG) == 0) { - return SPIFFS_VIS_COUNTINUE; - } - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_CHECK_RES(res); - if (objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - if (strcmp((const char*)user_const_p, (char*)objix_hdr.name) == 0) { - return SPIFFS_OK; - } - } - - return SPIFFS_VIS_COUNTINUE; -} - -// Finds object index header page by name -s32_t spiffs_object_find_object_index_header_by_name( - spiffs *fs, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - spiffs_page_ix *pix) { - s32_t res; - spiffs_block_ix bix; - int entry; - - res = spiffs_obj_lu_find_entry_visitor(fs, - fs->cursor_block_ix, - fs->cursor_obj_lu_entry, - 0, - 0, - spiffs_object_find_object_index_header_by_name_v, - name, - 0, - &bix, - &entry); - - if (res == SPIFFS_VIS_END) { - res = SPIFFS_ERR_NOT_FOUND; - } - SPIFFS_CHECK_RES(res); - - if (pix) { - *pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, entry); - } - - fs->cursor_block_ix = bix; - fs->cursor_obj_lu_entry = entry; - - return res; -} - -#if !SPIFFS_READ_ONLY -// Truncates object to new size. If new size is null, object may be removed totally -s32_t spiffs_object_truncate( - spiffs_fd *fd, - u32_t new_size, - u8_t remove) { - s32_t res = SPIFFS_OK; - spiffs *fs = fd->fs; - - if ((fd->size == SPIFFS_UNDEFINED_LEN || fd->size == 0) && !remove) { - // no op - return res; - } - - // need 2 pages if not removing: object index page + possibly chopped data page - res = spiffs_gc_check(fs, remove ? 0 : SPIFFS_DATA_PAGE_SIZE(fs) * 2); - SPIFFS_CHECK_RES(res); - - spiffs_page_ix objix_pix = fd->objix_hdr_pix; - spiffs_span_ix data_spix = (fd->size > 0 ? fd->size-1 : 0) / SPIFFS_DATA_PAGE_SIZE(fs); - u32_t cur_size = fd->size == (u32_t)SPIFFS_UNDEFINED_LEN ? 0 : fd->size ; - spiffs_span_ix cur_objix_spix = 0; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - spiffs_page_ix data_pix; - spiffs_page_ix new_objix_hdr_pix; - - // before truncating, check if object is to be fully removed and mark this - if (remove && new_size == 0) { - u8_t flags = ~( SPIFFS_PH_FLAG_USED | SPIFFS_PH_FLAG_INDEX | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE); - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_UPDT, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, fd->objix_hdr_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&flags); - SPIFFS_CHECK_RES(res); - } - - // delete from end of object until desired len is reached - while (cur_size > new_size) { - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - - // put object index for current data span index in work buffer - if (prev_objix_spix != cur_objix_spix) { - if (prev_objix_spix != (spiffs_span_ix)-1) { - // remove previous object index page - SPIFFS_DBG("truncate: delete objix page %04x:%04x\n", objix_pix, prev_objix_spix); - - res = spiffs_page_index_check(fs, fd, objix_pix, prev_objix_spix); - SPIFFS_CHECK_RES(res); - - res = spiffs_page_delete(fs, objix_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_DEL, fd->obj_id, objix->p_hdr.span_ix, objix_pix, 0); - if (prev_objix_spix > 0) { - // update object index header page - SPIFFS_DBG("truncate: update objix hdr page %04x:%04x to size %i\n", fd->objix_hdr_pix, prev_objix_spix, cur_size); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, cur_size, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); - fd->size = cur_size; - } - } - // load current object index (header) page - if (cur_objix_spix == 0) { - objix_pix = fd->objix_hdr_pix; - } else { - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); - SPIFFS_CHECK_RES(res); - } - - SPIFFS_DBG("truncate: load objix page %04x:%04x for data spix:%04x\n", objix_pix, cur_objix_spix, data_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix_hdr->p_hdr, fd->obj_id, cur_objix_spix); - fd->cursor_objix_pix = objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = cur_size; - - prev_objix_spix = cur_objix_spix; - } - - if (cur_objix_spix == 0) { - // get data page from object index header page - data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = SPIFFS_OBJ_ID_FREE; - } else { - // get data page from object index page - data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = SPIFFS_OBJ_ID_FREE; - } - - SPIFFS_DBG("truncate: got data pix %04x\n", data_pix); - - if (new_size == 0 || remove || cur_size - new_size >= SPIFFS_DATA_PAGE_SIZE(fs)) { - // delete full data page - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - if (res != SPIFFS_ERR_DELETED && res != SPIFFS_OK && res != SPIFFS_ERR_INDEX_REF_FREE) { - SPIFFS_DBG("truncate: err validating data pix %i\n", res); - break; - } - - if (res == SPIFFS_OK) { - res = spiffs_page_delete(fs, data_pix); - if (res != SPIFFS_OK) { - SPIFFS_DBG("truncate: err deleting data pix %i\n", res); - break; - } - } else if (res == SPIFFS_ERR_DELETED || res == SPIFFS_ERR_INDEX_REF_FREE) { - res = SPIFFS_OK; - } - - // update current size - if (cur_size % SPIFFS_DATA_PAGE_SIZE(fs) == 0) { - cur_size -= SPIFFS_DATA_PAGE_SIZE(fs); - } else { - cur_size -= cur_size % SPIFFS_DATA_PAGE_SIZE(fs); - } - fd->size = cur_size; - fd->offset = cur_size; - SPIFFS_DBG("truncate: delete data page %04x for data spix:%04x, cur_size:%i\n", data_pix, data_spix, cur_size); - } else { - // delete last page, partially - spiffs_page_header p_hdr; - spiffs_page_ix new_data_pix; - u32_t bytes_to_remove = SPIFFS_DATA_PAGE_SIZE(fs) - (new_size % SPIFFS_DATA_PAGE_SIZE(fs)); - SPIFFS_DBG("truncate: delete %i bytes from data page %04x for data spix:%04x, cur_size:%i\n", bytes_to_remove, data_pix, data_spix, cur_size); - - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - if (res != SPIFFS_OK) break; - - p_hdr.obj_id = fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG; - p_hdr.span_ix = data_spix; - p_hdr.flags = 0xff; - // allocate new page and copy unmodified data - res = spiffs_page_allocate_data(fs, fd->obj_id & ~SPIFFS_OBJ_ID_IX_FLAG, - &p_hdr, 0, 0, 0, 0, &new_data_pix); - if (res != SPIFFS_OK) break; - res = spiffs_phys_cpy(fs, 0, - SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + sizeof(spiffs_page_header), - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header), - SPIFFS_DATA_PAGE_SIZE(fs) - bytes_to_remove); - if (res != SPIFFS_OK) break; - // delete original data page - res = spiffs_page_delete(fs, data_pix); - if (res != SPIFFS_OK) break; - p_hdr.flags &= ~SPIFFS_PH_FLAG_FINAL; - res = _spiffs_wr(fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_UPDT, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, new_data_pix) + offsetof(spiffs_page_header, flags), - sizeof(u8_t), - (u8_t *)&p_hdr.flags); - if (res != SPIFFS_OK) break; - - // update memory representation of object index page with new data page - if (cur_objix_spix == 0) { - // update object index header page - ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix] = new_data_pix; - SPIFFS_DBG("truncate: wrote page %04x to objix_hdr entry %02x in mem\n", new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } else { - // update object index page - ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)] = new_data_pix; - SPIFFS_DBG("truncate: wrote page %04x to objix entry %02x in mem\n", new_data_pix, SPIFFS_OBJ_IX_ENTRY(fs, data_spix)); - } - cur_size = new_size; - fd->size = new_size; - fd->offset = cur_size; - break; - } - data_spix--; - } // while all data - - // update object indices - if (cur_objix_spix == 0) { - // update object index header page - if (cur_size == 0) { - if (remove) { - // remove object altogether - SPIFFS_DBG("truncate: remove object index header page %04x\n", objix_pix); - - res = spiffs_page_index_check(fs, fd, objix_pix, 0); - SPIFFS_CHECK_RES(res); - - res = spiffs_page_delete(fs, objix_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_DEL, fd->obj_id, 0, objix_pix, 0); - } else { - // make uninitialized object - SPIFFS_DBG("truncate: reset objix_hdr page %04x\n", objix_pix); - memset(fs->work + sizeof(spiffs_page_object_ix_header), 0xff, - SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header)); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - objix_pix, fs->work, 0, SPIFFS_UNDEFINED_LEN, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); - } - } else { - // update object index header page - SPIFFS_DBG("truncate: update object index header page with indices and size\n"); - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - objix_pix, fs->work, 0, cur_size, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); - } - } else { - // update both current object index page and object index header page - spiffs_page_ix new_objix_pix; - - res = spiffs_page_index_check(fs, fd, objix_pix, cur_objix_spix); - SPIFFS_CHECK_RES(res); - - // move and update object index page - res = spiffs_page_move(fs, fd->file_nbr, (u8_t*)objix_hdr, fd->obj_id, 0, objix_pix, &new_objix_pix); - SPIFFS_CHECK_RES(res); - spiffs_cb_object_event(fs, fd, SPIFFS_EV_IX_UPD, fd->obj_id, objix->p_hdr.span_ix, new_objix_pix, 0); - SPIFFS_DBG("truncate: store modified objix page, %04x:%04x\n", new_objix_pix, cur_objix_spix); - fd->cursor_objix_pix = new_objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - fd->offset = cur_size; - // update object index header page with new size - res = spiffs_object_update_index_hdr(fs, fd, fd->obj_id, - fd->objix_hdr_pix, 0, 0, cur_size, &new_objix_hdr_pix); - SPIFFS_CHECK_RES(res); - } - fd->size = cur_size; - - return res; -} // spiffs_object_truncate -#endif // !SPIFFS_READ_ONLY - -s32_t spiffs_object_read( - spiffs_fd *fd, - u32_t offset, - u32_t len, - u8_t *dst) { - s32_t res = SPIFFS_OK; - spiffs *fs = fd->fs; - spiffs_page_ix objix_pix; - spiffs_page_ix data_pix; - spiffs_span_ix data_spix = offset / SPIFFS_DATA_PAGE_SIZE(fs); - u32_t cur_offset = offset; - spiffs_span_ix cur_objix_spix; - spiffs_span_ix prev_objix_spix = (spiffs_span_ix)-1; - spiffs_page_object_ix_header *objix_hdr = (spiffs_page_object_ix_header *)fs->work; - spiffs_page_object_ix *objix = (spiffs_page_object_ix *)fs->work; - - while (cur_offset < offset + len) { - cur_objix_spix = SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, data_spix); - if (prev_objix_spix != cur_objix_spix) { - // load current object index (header) page - if (cur_objix_spix == 0) { - objix_pix = fd->objix_hdr_pix; - } else { - SPIFFS_DBG("read: find objix %04x:%04x\n", fd->obj_id, cur_objix_spix); - res = spiffs_obj_lu_find_id_and_span(fs, fd->obj_id | SPIFFS_OBJ_ID_IX_FLAG, cur_objix_spix, 0, &objix_pix); - SPIFFS_CHECK_RES(res); - } - SPIFFS_DBG("read: load objix page %04x:%04x for data spix:%04x\n", objix_pix, cur_objix_spix, data_spix); - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_IX | SPIFFS_OP_C_READ, - fd->file_nbr, SPIFFS_PAGE_TO_PADDR(fs, objix_pix), SPIFFS_CFG_LOG_PAGE_SZ(fs), fs->work); - SPIFFS_CHECK_RES(res); - SPIFFS_VALIDATE_OBJIX(objix->p_hdr, fd->obj_id, cur_objix_spix); - - fd->offset = cur_offset; - fd->cursor_objix_pix = objix_pix; - fd->cursor_objix_spix = cur_objix_spix; - - prev_objix_spix = cur_objix_spix; - } - - if (cur_objix_spix == 0) { - // get data page from object index header page - data_pix = ((spiffs_page_ix*)((u8_t *)objix_hdr + sizeof(spiffs_page_object_ix_header)))[data_spix]; - } else { - // get data page from object index page - data_pix = ((spiffs_page_ix*)((u8_t *)objix + sizeof(spiffs_page_object_ix)))[SPIFFS_OBJ_IX_ENTRY(fs, data_spix)]; - } - - // all remaining data - u32_t len_to_read = offset + len - cur_offset; - // remaining data in page - len_to_read = MIN(len_to_read, SPIFFS_DATA_PAGE_SIZE(fs) - (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); - // remaining data in file - len_to_read = MIN(len_to_read, fd->size); - SPIFFS_DBG("read: offset:%i rd:%i data spix:%04x is data_pix:%04x addr:%08x\n", cur_offset, len_to_read, data_spix, data_pix, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs))); - if (len_to_read <= 0) { - res = SPIFFS_ERR_END_OF_OBJECT; - break; - } - res = spiffs_page_data_check(fs, fd, data_pix, data_spix); - SPIFFS_CHECK_RES(res); - res = _spiffs_rd( - fs, SPIFFS_OP_T_OBJ_DA | SPIFFS_OP_C_READ, - fd->file_nbr, - SPIFFS_PAGE_TO_PADDR(fs, data_pix) + sizeof(spiffs_page_header) + (cur_offset % SPIFFS_DATA_PAGE_SIZE(fs)), - len_to_read, - dst); - SPIFFS_CHECK_RES(res); - dst += len_to_read; - cur_offset += len_to_read; - fd->offset = cur_offset; - data_spix++; - } - - return res; -} - -#if !SPIFFS_READ_ONLY -typedef struct { - spiffs_obj_id min_obj_id; - spiffs_obj_id max_obj_id; - u32_t compaction; - const u8_t *conflicting_name; -} spiffs_free_obj_id_state; - -static s32_t spiffs_obj_lu_find_free_obj_id_bitmap_v(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, - const void *user_const_p, void *user_var_p) { - if (id != SPIFFS_OBJ_ID_FREE && id != SPIFFS_OBJ_ID_DELETED) { - spiffs_obj_id min_obj_id = *((spiffs_obj_id*)user_var_p); - const u8_t *conflicting_name = (const u8_t*)user_const_p; - - // if conflicting name parameter is given, also check if this name is found in object index hdrs - if (conflicting_name && (id & SPIFFS_OBJ_ID_IX_FLAG)) { - spiffs_page_ix pix = SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, bix, ix_entry); - int res; - spiffs_page_object_ix_header objix_hdr; - res = _spiffs_rd(fs, SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ, - 0, SPIFFS_PAGE_TO_PADDR(fs, pix), sizeof(spiffs_page_object_ix_header), (u8_t *)&objix_hdr); - SPIFFS_CHECK_RES(res); - if (objix_hdr.p_hdr.span_ix == 0 && - (objix_hdr.p_hdr.flags & (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_FINAL | SPIFFS_PH_FLAG_IXDELE)) == - (SPIFFS_PH_FLAG_DELET | SPIFFS_PH_FLAG_IXDELE)) { - if (strcmp((const char*)user_const_p, (char*)objix_hdr.name) == 0) { - return SPIFFS_ERR_CONFLICTING_NAME; - } - } - } - - id &= ~SPIFFS_OBJ_ID_IX_FLAG; - u32_t bit_ix = (id-min_obj_id) & 7; - int byte_ix = (id-min_obj_id) >> 3; - if (byte_ix >= 0 && (u32_t)byte_ix < SPIFFS_CFG_LOG_PAGE_SZ(fs)) { - fs->work[byte_ix] |= (1<conflicting_name && strcmp((const char *)state->conflicting_name, (char *)objix_hdr.name) == 0) { - return SPIFFS_ERR_CONFLICTING_NAME; - } - - id &= ~SPIFFS_OBJ_ID_IX_FLAG; - if (id >= state->min_obj_id && id <= state->max_obj_id) { - u8_t *map = (u8_t *)fs->work; - int ix = (id - state->min_obj_id) / state->compaction; - //SPIFFS_DBG("free_obj_id: add ix %i for id %04x min:%04x max%04x comp:%i\n", ix, id, state->min_obj_id, state->max_obj_id, state->compaction); - map[ix]++; - } - } - } - return SPIFFS_VIS_COUNTINUE; -} - -// Scans thru all object lookup for object index header pages. If total possible number of -// object ids cannot fit into a work buffer, these are grouped. When a group containing free -// object ids is found, the object lu is again scanned for object ids within group and bitmasked. -// Finally, the bitmask is searched for a free id -s32_t spiffs_obj_lu_find_free_obj_id(spiffs *fs, spiffs_obj_id *obj_id, const u8_t *conflicting_name) { - s32_t res = SPIFFS_OK; - u32_t max_objects = (fs->block_count * SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs)) / 2; - spiffs_free_obj_id_state state; - spiffs_obj_id free_obj_id = SPIFFS_OBJ_ID_FREE; - state.min_obj_id = 1; - state.max_obj_id = max_objects + 1; - if (state.max_obj_id & SPIFFS_OBJ_ID_IX_FLAG) { - state.max_obj_id = ((spiffs_obj_id)-1) & ~SPIFFS_OBJ_ID_IX_FLAG; - } - state.compaction = 0; - state.conflicting_name = conflicting_name; - while (res == SPIFFS_OK && free_obj_id == SPIFFS_OBJ_ID_FREE) { - if (state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8) { - // possible to represent in bitmap - u32_t i, j; - SPIFFS_DBG("free_obj_id: BITM min:%04x max:%04x\n", state.min_obj_id, state.max_obj_id); - - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_bitmap_v, - conflicting_name, &state.min_obj_id, 0, 0); - if (res == SPIFFS_VIS_END) res = SPIFFS_OK; - SPIFFS_CHECK_RES(res); - // traverse bitmask until found free obj_id - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs); i++) { - u8_t mask = fs->work[i]; - if (mask == 0xff) { - continue; - } - for (j = 0; j < 8; j++) { - if ((mask & (1<work; - u8_t min_count = 0xff; - - for (i = 0; i < SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(u8_t); i++) { - if (map[i] < min_count) { - min_count = map[i]; - min_i = i; - if (min_count == 0) { - break; - } - } - } - - if (min_count == state.compaction) { - // there are no free objids! - SPIFFS_DBG("free_obj_id: compacted table is full\n"); - return SPIFFS_ERR_FULL; - } - - SPIFFS_DBG("free_obj_id: COMP select index:%i min_count:%i min:%04x max:%04x compact:%i\n", min_i, min_count, state.min_obj_id, state.max_obj_id, state.compaction); - - if (min_count == 0) { - // no id in this range, skip compacting and use directly - *obj_id = min_i * state.compaction + state.min_obj_id; - return SPIFFS_OK; - } else { - SPIFFS_DBG("free_obj_id: COMP SEL chunk:%04x min:%04x -> %04x\n", state.compaction, state.min_obj_id, state.min_obj_id + min_i * state.compaction); - state.min_obj_id += min_i * state.compaction; - state.max_obj_id = state.min_obj_id + state.compaction; - // decrease compaction - } - if ((state.max_obj_id - state.min_obj_id <= (spiffs_obj_id)SPIFFS_CFG_LOG_PAGE_SZ(fs)*8)) { - // no need for compacting, use bitmap - continue; - } - } - // in a work memory of log_page_size bytes, we may fit in log_page_size ids - // todo what if compaction is > 255 - then we cannot fit it in a byte - state.compaction = (state.max_obj_id-state.min_obj_id) / ((SPIFFS_CFG_LOG_PAGE_SZ(fs) / sizeof(u8_t))); - SPIFFS_DBG("free_obj_id: COMP min:%04x max:%04x compact:%i\n", state.min_obj_id, state.max_obj_id, state.compaction); - - memset(fs->work, 0, SPIFFS_CFG_LOG_PAGE_SZ(fs)); - res = spiffs_obj_lu_find_entry_visitor(fs, 0, 0, 0, 0, spiffs_obj_lu_find_free_obj_id_compact_v, &state, 0, 0, 0); - if (res == SPIFFS_VIS_END) res = SPIFFS_OK; - SPIFFS_CHECK_RES(res); - state.conflicting_name = 0; // searched for conflicting name once, no need to do it again - } - } - - return res; -} -#endif // !SPIFFS_READ_ONLY - -s32_t spiffs_fd_find_new(spiffs *fs, spiffs_fd **fd) { - u32_t i; - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - for (i = 0; i < fs->fd_count; i++) { - spiffs_fd *cur_fd = &fds[i]; - if (cur_fd->file_nbr == 0) { - cur_fd->file_nbr = i+1; - *fd = cur_fd; - return SPIFFS_OK; - } - } - return SPIFFS_ERR_OUT_OF_FILE_DESCS; -} - -s32_t spiffs_fd_return(spiffs *fs, spiffs_file f) { - if (f <= 0 || f > (s16_t)fs->fd_count) { - return SPIFFS_ERR_BAD_DESCRIPTOR; - } - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - spiffs_fd *fd = &fds[f-1]; - if (fd->file_nbr == 0) { - return SPIFFS_ERR_FILE_CLOSED; - } - fd->file_nbr = 0; - return SPIFFS_OK; -} - -s32_t spiffs_fd_get(spiffs *fs, spiffs_file f, spiffs_fd **fd) { - if (f <= 0 || f > (s16_t)fs->fd_count) { - return SPIFFS_ERR_BAD_DESCRIPTOR; - } - spiffs_fd *fds = (spiffs_fd *)fs->fd_space; - *fd = &fds[f-1]; - if ((*fd)->file_nbr == 0) { - return SPIFFS_ERR_FILE_CLOSED; - } - return SPIFFS_OK; -} diff --git a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_nucleus.h b/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_nucleus.h deleted file mode 100644 index 6e4e8ac33..000000000 --- a/arduino/realtek-ambz/cores/arduino/spiffs/spiffs_nucleus.h +++ /dev/null @@ -1,751 +0,0 @@ -/* - * spiffs_nucleus.h - * - * Created on: Jun 15, 2013 - * Author: petera - */ - -/* SPIFFS layout - * - * spiffs is designed for following spi flash characteristics: - * - only big areas of data (blocks) can be erased - * - erasing resets all bits in a block to ones - * - writing pulls ones to zeroes - * - zeroes cannot be pulled to ones, without erase - * - wear leveling - * - * spiffs is also meant to be run on embedded, memory constraint devices. - * - * Entire area is divided in blocks. Entire area is also divided in pages. - * Each block contains same number of pages. A page cannot be erased, but a - * block can be erased. - * - * Entire area must be block_size * x - * page_size must be block_size / (2^y) where y > 2 - * - * ex: area = 1024*1024 bytes, block size = 65536 bytes, page size = 256 bytes - * - * BLOCK 0 PAGE 0 object lookup 1 - * PAGE 1 object lookup 2 - * ... - * PAGE n-1 object lookup n - * PAGE n object data 1 - * PAGE n+1 object data 2 - * ... - * PAGE n+m-1 object data m - * - * BLOCK 1 PAGE n+m object lookup 1 - * PAGE n+m+1 object lookup 2 - * ... - * PAGE 2n+m-1 object lookup n - * PAGE 2n+m object data 1 - * PAGE 2n+m object data 2 - * ... - * PAGE 2n+2m-1 object data m - * ... - * - * n is number of object lookup pages, which is number of pages needed to index all pages - * in a block by object id - * : block_size / page_size * sizeof(obj_id) / page_size - * m is number data pages, which is number of pages in block minus number of lookup pages - * : block_size / page_size - block_size / page_size * sizeof(obj_id) / page_size - * thus, n+m is total number of pages in a block - * : block_size / page_size - * - * ex: n = 65536/256*2/256 = 2, m = 65536/256 - 2 = 254 => n+m = 65536/256 = 256 - * - * Object lookup pages contain object id entries. Each entry represent the corresponding - * data page. - * Assuming a 16 bit object id, an object id being 0xffff represents a free page. - * An object id being 0x0000 represents a deleted page. - * - * ex: page 0 : lookup : 0008 0001 0aaa ffff ffff ffff ffff ffff .. - * page 1 : lookup : ffff ffff ffff ffff ffff ffff ffff ffff .. - * page 2 : data : data for object id 0008 - * page 3 : data : data for object id 0001 - * page 4 : data : data for object id 0aaa - * ... - * - * - * Object data pages can be either object index pages or object content. - * All object data pages contains a data page header, containing object id and span index. - * The span index denotes the object page ordering amongst data pages with same object id. - * This applies to both object index pages (when index spans more than one page of entries), - * and object data pages. - * An object index page contains page entries pointing to object content page. The entry index - * in a object index page correlates to the span index in the actual object data page. - * The first object index page (span index 0) is called object index header page, and also - * contains object flags (directory/file), size, object name etc. - * - * ex: - * BLOCK 1 - * PAGE 256: objectl lookup page 1 - * [*123] [ 123] [ 123] [ 123] - * [ 123] [*123] [ 123] [ 123] - * [free] [free] [free] [free] ... - * PAGE 257: objectl lookup page 2 - * [free] [free] [free] [free] ... - * PAGE 258: object index page (header) - * obj.id:0123 span.ix:0000 flags:INDEX - * size:1600 name:ex.txt type:file - * [259] [260] [261] [262] - * PAGE 259: object data page - * obj.id:0123 span.ix:0000 flags:DATA - * PAGE 260: object data page - * obj.id:0123 span.ix:0001 flags:DATA - * PAGE 261: object data page - * obj.id:0123 span.ix:0002 flags:DATA - * PAGE 262: object data page - * obj.id:0123 span.ix:0003 flags:DATA - * PAGE 263: object index page - * obj.id:0123 span.ix:0001 flags:INDEX - * [264] [265] [fre] [fre] - * [fre] [fre] [fre] [fre] - * PAGE 264: object data page - * obj.id:0123 span.ix:0004 flags:DATA - * PAGE 265: object data page - * obj.id:0123 span.ix:0005 flags:DATA - * - */ -#ifndef SPIFFS_NUCLEUS_H_ -#define SPIFFS_NUCLEUS_H_ - -#define _SPIFFS_ERR_CHECK_FIRST (SPIFFS_ERR_INTERNAL - 1) -#define SPIFFS_ERR_CHECK_OBJ_ID_MISM (SPIFFS_ERR_INTERNAL - 1) -#define SPIFFS_ERR_CHECK_SPIX_MISM (SPIFFS_ERR_INTERNAL - 2) -#define SPIFFS_ERR_CHECK_FLAGS_BAD (SPIFFS_ERR_INTERNAL - 3) -#define _SPIFFS_ERR_CHECK_LAST (SPIFFS_ERR_INTERNAL - 4) - -#define SPIFFS_VIS_COUNTINUE (SPIFFS_ERR_INTERNAL - 20) -#define SPIFFS_VIS_COUNTINUE_RELOAD (SPIFFS_ERR_INTERNAL - 21) -#define SPIFFS_VIS_END (SPIFFS_ERR_INTERNAL - 22) - -#define SPIFFS_EV_IX_UPD 0 -#define SPIFFS_EV_IX_NEW 1 -#define SPIFFS_EV_IX_DEL 2 - -#define SPIFFS_OBJ_ID_IX_FLAG ((spiffs_obj_id)(1<<(8*sizeof(spiffs_obj_id)-1))) - -#define SPIFFS_UNDEFINED_LEN (u32_t)(-1) - -#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0) -#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1) - -#if SPIFFS_USE_MAGIC -#if !SPIFFS_USE_MAGIC_LENGTH -#define SPIFFS_MAGIC(fs, bix) \ - ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs))) -#else // SPIFFS_USE_MAGIC_LENGTH -#define SPIFFS_MAGIC(fs, bix) \ - ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs) ^ ((fs)->block_count - (bix)))) -#endif // SPIFFS_USE_MAGIC_LENGTH -#endif // SPIFFS_USE_MAGIC - -#define SPIFFS_CONFIG_MAGIC (0x20090315) - -#if SPIFFS_SINGLETON == 0 -#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \ - ((fs)->cfg.log_page_size) -#define SPIFFS_CFG_LOG_BLOCK_SZ(fs) \ - ((fs)->cfg.log_block_size) -#define SPIFFS_CFG_PHYS_SZ(fs) \ - ((fs)->cfg.phys_size) -#define SPIFFS_CFG_PHYS_ERASE_SZ(fs) \ - ((fs)->cfg.phys_erase_block) -#define SPIFFS_CFG_PHYS_ADDR(fs) \ - ((fs)->cfg.phys_addr) -#endif - -// total number of pages -#define SPIFFS_MAX_PAGES(fs) \ - ( SPIFFS_CFG_PHYS_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) ) -// total number of pages per block, including object lookup pages -#define SPIFFS_PAGES_PER_BLOCK(fs) \ - ( SPIFFS_CFG_LOG_BLOCK_SZ(fs)/SPIFFS_CFG_LOG_PAGE_SZ(fs) ) -// number of object lookup pages per block -#define SPIFFS_OBJ_LOOKUP_PAGES(fs) \ - (MAX(1, (SPIFFS_PAGES_PER_BLOCK(fs) * sizeof(spiffs_obj_id)) / SPIFFS_CFG_LOG_PAGE_SZ(fs)) ) -// checks if page index belongs to object lookup -#define SPIFFS_IS_LOOKUP_PAGE(fs,pix) \ - (((pix) % SPIFFS_PAGES_PER_BLOCK(fs)) < SPIFFS_OBJ_LOOKUP_PAGES(fs)) -// number of object lookup entries in all object lookup pages -#define SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) \ - (SPIFFS_PAGES_PER_BLOCK(fs)-SPIFFS_OBJ_LOOKUP_PAGES(fs)) -// converts a block to physical address -#define SPIFFS_BLOCK_TO_PADDR(fs, block) \ - ( SPIFFS_CFG_PHYS_ADDR(fs) + (block)* SPIFFS_CFG_LOG_BLOCK_SZ(fs) ) -// converts a object lookup entry to page index -#define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PIX(fs, block, entry) \ - ((block)*SPIFFS_PAGES_PER_BLOCK(fs) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry)) -// converts a object lookup entry to physical address of corresponding page -#define SPIFFS_OBJ_LOOKUP_ENTRY_TO_PADDR(fs, block, entry) \ - (SPIFFS_BLOCK_TO_PADDR(fs, block) + (SPIFFS_OBJ_LOOKUP_PAGES(fs) + entry) * SPIFFS_CFG_LOG_PAGE_SZ(fs) ) -// converts a page to physical address -#define SPIFFS_PAGE_TO_PADDR(fs, page) \ - ( SPIFFS_CFG_PHYS_ADDR(fs) + (page) * SPIFFS_CFG_LOG_PAGE_SZ(fs) ) -// converts a physical address to page -#define SPIFFS_PADDR_TO_PAGE(fs, addr) \ - ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) / SPIFFS_CFG_LOG_PAGE_SZ(fs) ) -// gives index in page for a physical address -#define SPIFFS_PADDR_TO_PAGE_OFFSET(fs, addr) \ - ( ((addr) - SPIFFS_CFG_PHYS_ADDR(fs)) % SPIFFS_CFG_LOG_PAGE_SZ(fs) ) -// returns containing block for given page -#define SPIFFS_BLOCK_FOR_PAGE(fs, page) \ - ( (page) / SPIFFS_PAGES_PER_BLOCK(fs) ) -// returns starting page for block -#define SPIFFS_PAGE_FOR_BLOCK(fs, block) \ - ( (block) * SPIFFS_PAGES_PER_BLOCK(fs) ) -// converts page to entry in object lookup page -#define SPIFFS_OBJ_LOOKUP_ENTRY_FOR_PAGE(fs, page) \ - ( (page) % SPIFFS_PAGES_PER_BLOCK(fs) - SPIFFS_OBJ_LOOKUP_PAGES(fs) ) -// returns data size in a data page -#define SPIFFS_DATA_PAGE_SIZE(fs) \ - ( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) ) -// returns physical address for block's erase count, -// always in the physical last entry of the last object lookup page -#define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \ - ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) ) -// returns physical address for block's magic, -// always in the physical second last entry of the last object lookup page -#define SPIFFS_MAGIC_PADDR(fs, bix) \ - ( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 ) -// checks if there is any room for magic in the object luts -#define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \ - ( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \ - <= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) ) - -// define helpers object - -// entries in an object header page index -#define SPIFFS_OBJ_HDR_IX_LEN(fs) \ - ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix_header))/sizeof(spiffs_page_ix)) -// entries in an object page index -#define SPIFFS_OBJ_IX_LEN(fs) \ - ((SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_object_ix))/sizeof(spiffs_page_ix)) -// object index entry for given data span index -#define SPIFFS_OBJ_IX_ENTRY(fs, spix) \ - ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? (spix) : (((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))%SPIFFS_OBJ_IX_LEN(fs))) -// object index span index number for given data span index or entry -#define SPIFFS_OBJ_IX_ENTRY_SPAN_IX(fs, spix) \ - ((spix) < SPIFFS_OBJ_HDR_IX_LEN(fs) ? 0 : (1+((spix)-SPIFFS_OBJ_HDR_IX_LEN(fs))/SPIFFS_OBJ_IX_LEN(fs))) - - -#define SPIFFS_OP_T_OBJ_LU (0<<0) -#define SPIFFS_OP_T_OBJ_LU2 (1<<0) -#define SPIFFS_OP_T_OBJ_IX (2<<0) -#define SPIFFS_OP_T_OBJ_DA (3<<0) -#define SPIFFS_OP_C_DELE (0<<2) -#define SPIFFS_OP_C_UPDT (1<<2) -#define SPIFFS_OP_C_MOVS (2<<2) -#define SPIFFS_OP_C_MOVD (3<<2) -#define SPIFFS_OP_C_FLSH (4<<2) -#define SPIFFS_OP_C_READ (5<<2) -#define SPIFFS_OP_C_WRTHRU (6<<2) - -#define SPIFFS_OP_TYPE_MASK (3<<0) -#define SPIFFS_OP_COM_MASK (7<<2) - - -// if 0, this page is written to, else clean -#define SPIFFS_PH_FLAG_USED (1<<0) -// if 0, writing is finalized, else under modification -#define SPIFFS_PH_FLAG_FINAL (1<<1) -// if 0, this is an index page, else a data page -#define SPIFFS_PH_FLAG_INDEX (1<<2) -// if 0, page is deleted, else valid -#define SPIFFS_PH_FLAG_DELET (1<<7) -// if 0, this index header is being deleted -#define SPIFFS_PH_FLAG_IXDELE (1<<6) - - -#define SPIFFS_CHECK_MOUNT(fs) \ - ((fs)->mounted != 0) - -#define SPIFFS_CHECK_CFG(fs) \ - ((fs)->config_magic == SPIFFS_CONFIG_MAGIC) - -#define SPIFFS_CHECK_RES(res) \ - do { \ - if ((res) < SPIFFS_OK) return (res); \ - } while (0); - -#define SPIFFS_API_CHECK_MOUNT(fs) \ - if (!SPIFFS_CHECK_MOUNT((fs))) { \ - (fs)->err_code = SPIFFS_ERR_NOT_MOUNTED; \ - return -1; \ - } - -#define SPIFFS_API_CHECK_CFG(fs) \ - if (!SPIFFS_CHECK_CFG((fs))) { \ - (fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \ - return -1; \ - } - -#define SPIFFS_API_CHECK_RES(fs, res) \ - if ((res) < SPIFFS_OK) { \ - (fs)->err_code = (res); \ - return -1; \ - } - -#define SPIFFS_API_CHECK_RES_UNLOCK(fs, res) \ - if ((res) < SPIFFS_OK) { \ - (fs)->err_code = (res); \ - SPIFFS_UNLOCK(fs); \ - return -1; \ - } - -#define SPIFFS_VALIDATE_OBJIX(ph, objid, spix) \ - if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ - if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \ - if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \ - if (((ph).flags & SPIFFS_PH_FLAG_INDEX) != 0) return SPIFFS_ERR_NOT_INDEX; \ - if (((objid) & SPIFFS_OBJ_ID_IX_FLAG) == 0) return SPIFFS_ERR_NOT_INDEX; \ - if ((ph).span_ix != (spix)) return SPIFFS_ERR_INDEX_SPAN_MISMATCH; - //if ((spix) == 0 && ((ph).flags & SPIFFS_PH_FLAG_IXDELE) == 0) return SPIFFS_ERR_DELETED; - -#define SPIFFS_VALIDATE_DATA(ph, objid, spix) \ - if (((ph).flags & SPIFFS_PH_FLAG_USED) != 0) return SPIFFS_ERR_IS_FREE; \ - if (((ph).flags & SPIFFS_PH_FLAG_DELET) == 0) return SPIFFS_ERR_DELETED; \ - if (((ph).flags & SPIFFS_PH_FLAG_FINAL) != 0) return SPIFFS_ERR_NOT_FINALIZED; \ - if (((ph).flags & SPIFFS_PH_FLAG_INDEX) == 0) return SPIFFS_ERR_IS_INDEX; \ - if ((objid) & SPIFFS_OBJ_ID_IX_FLAG) return SPIFFS_ERR_IS_INDEX; \ - if ((ph).span_ix != (spix)) return SPIFFS_ERR_DATA_SPAN_MISMATCH; - - -// check id -#define SPIFFS_VIS_CHECK_ID (1<<0) -// report argument object id to visitor - else object lookup id is reported -#define SPIFFS_VIS_CHECK_PH (1<<1) -// stop searching at end of all look up pages -#define SPIFFS_VIS_NO_WRAP (1<<2) - -#if SPIFFS_HAL_CALLBACK_EXTRA - -#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \ - (_fs)->cfg.hal_write_f((_fs), (_paddr), (_len), (_src)) -#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \ - (_fs)->cfg.hal_read_f((_fs), (_paddr), (_len), (_dst)) -#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \ - (_fs)->cfg.hal_erase_f((_fs), (_paddr), (_len)) - -#else // SPIFFS_HAL_CALLBACK_EXTRA - -#define SPIFFS_HAL_WRITE(_fs, _paddr, _len, _src) \ - (_fs)->cfg.hal_write_f((_paddr), (_len), (_src)) -#define SPIFFS_HAL_READ(_fs, _paddr, _len, _dst) \ - (_fs)->cfg.hal_read_f((_paddr), (_len), (_dst)) -#define SPIFFS_HAL_ERASE(_fs, _paddr, _len) \ - (_fs)->cfg.hal_erase_f((_paddr), (_len)) - -#endif // SPIFFS_HAL_CALLBACK_EXTRA - -#if SPIFFS_CACHE - -#define SPIFFS_CACHE_FLAG_DIRTY (1<<0) -#define SPIFFS_CACHE_FLAG_WRTHRU (1<<1) -#define SPIFFS_CACHE_FLAG_OBJLU (1<<2) -#define SPIFFS_CACHE_FLAG_OBJIX (1<<3) -#define SPIFFS_CACHE_FLAG_DATA (1<<4) -#define SPIFFS_CACHE_FLAG_TYPE_WR (1<<7) - -#define SPIFFS_CACHE_PAGE_SIZE(fs) \ - (sizeof(spiffs_cache_page) + SPIFFS_CFG_LOG_PAGE_SZ(fs)) - -#define spiffs_get_cache(fs) \ - ((spiffs_cache *)((fs)->cache)) - -#define spiffs_get_cache_page_hdr(fs, c, ix) \ - ((spiffs_cache_page *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)]))) - -#define spiffs_get_cache_page(fs, c, ix) \ - ((u8_t *)(&((c)->cpages[(ix) * SPIFFS_CACHE_PAGE_SIZE(fs)])) + sizeof(spiffs_cache_page)) - -// cache page struct -typedef struct { - // cache flags - u8_t flags; - // cache page index - u8_t ix; - // last access of this cache page - u32_t last_access; - union { - // type read cache - struct { - // read cache page index - spiffs_page_ix pix; - }; -#if SPIFFS_CACHE_WR - // type write cache - struct { - // write cache - spiffs_obj_id obj_id; - // offset in cache page - u32_t offset; - // size of cache page - u16_t size; - }; -#endif - }; -} spiffs_cache_page; - -// cache struct -typedef struct { - u8_t cpage_count; - u32_t last_access; - u32_t cpage_use_map; - u32_t cpage_use_mask; - u8_t *cpages; -} spiffs_cache; - -#endif - - -// spiffs nucleus file descriptor -typedef struct { - // the filesystem of this descriptor - spiffs *fs; - // number of file descriptor - if 0, the file descriptor is closed - spiffs_file file_nbr; - // object id - if SPIFFS_OBJ_ID_ERASED, the file was deleted - spiffs_obj_id obj_id; - // size of the file - u32_t size; - // cached object index header page index - spiffs_page_ix objix_hdr_pix; - // cached offset object index page index - spiffs_page_ix cursor_objix_pix; - // cached offset object index span index - spiffs_span_ix cursor_objix_spix; - // current absolute offset - u32_t offset; - // current file descriptor offset - u32_t fdoffset; - // fd flags - spiffs_flags flags; -#if SPIFFS_CACHE_WR - spiffs_cache_page *cache_page; -#endif -} spiffs_fd; - - -// object structs - -// page header, part of each page except object lookup pages -// NB: this is always aligned when the data page is an object index, -// as in this case struct spiffs_page_object_ix is used -typedef struct __attribute(( packed )) { - // object id - spiffs_obj_id obj_id; - // object span index - spiffs_span_ix span_ix; - // flags - u8_t flags; -} spiffs_page_header; - -// object index header page header -typedef struct __attribute(( packed )) -#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES - __attribute(( aligned(sizeof(spiffs_page_ix)) )) -#endif -{ - // common page header - spiffs_page_header p_hdr; - // alignment - u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; - // size of object - u32_t size; - // type of object - spiffs_obj_type type; - // name of object - u8_t name[SPIFFS_OBJ_NAME_LEN]; -} spiffs_page_object_ix_header; - -// object index page header -typedef struct __attribute(( packed )) { - spiffs_page_header p_hdr; - u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))]; -} spiffs_page_object_ix; - -// callback func for object lookup visitor -typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry, - const void *user_const_p, void *user_var_p); - - -#if SPIFFS_CACHE -#define _spiffs_rd(fs, op, fh, addr, len, dst) \ - spiffs_phys_rd((fs), (op), (fh), (addr), (len), (dst)) -#define _spiffs_wr(fs, op, fh, addr, len, src) \ - spiffs_phys_wr((fs), (op), (fh), (addr), (len), (src)) -#else -#define _spiffs_rd(fs, op, fh, addr, len, dst) \ - spiffs_phys_rd((fs), (addr), (len), (dst)) -#define _spiffs_wr(fs, op, fh, addr, len, src) \ - spiffs_phys_wr((fs), (addr), (len), (src)) -#endif - -#ifndef MIN -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif -#ifndef MAX -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#endif - -// --------------- - -s32_t spiffs_phys_rd( - spiffs *fs, -#if SPIFFS_CACHE - u8_t op, - spiffs_file fh, -#endif - u32_t addr, - u32_t len, - u8_t *dst); - -s32_t spiffs_phys_wr( - spiffs *fs, -#if SPIFFS_CACHE - u8_t op, - spiffs_file fh, -#endif - u32_t addr, - u32_t len, - u8_t *src); - -s32_t spiffs_phys_cpy( - spiffs *fs, - spiffs_file fh, - u32_t dst, - u32_t src, - u32_t len); - -s32_t spiffs_phys_count_free_blocks( - spiffs *fs); - -s32_t spiffs_obj_lu_find_entry_visitor( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - u8_t flags, - spiffs_obj_id obj_id, - spiffs_visitor_f v, - const void *user_const_p, - void *user_var_p, - spiffs_block_ix *block_ix, - int *lu_entry); - -s32_t spiffs_erase_block( - spiffs *fs, - spiffs_block_ix bix); - -#if SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH -s32_t spiffs_probe( - spiffs_config *cfg); -#endif // SPIFFS_USE_MAGIC && SPIFFS_USE_MAGIC_LENGTH - -// --------------- - -s32_t spiffs_obj_lu_scan( - spiffs *fs); - -s32_t spiffs_obj_lu_find_free_obj_id( - spiffs *fs, - spiffs_obj_id *obj_id, - const u8_t *conflicting_name); - -s32_t spiffs_obj_lu_find_free( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - spiffs_block_ix *block_ix, - int *lu_entry); - -s32_t spiffs_obj_lu_find_id( - spiffs *fs, - spiffs_block_ix starting_block, - int starting_lu_entry, - spiffs_obj_id obj_id, - spiffs_block_ix *block_ix, - int *lu_entry); - -s32_t spiffs_obj_lu_find_id_and_span( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix spix, - spiffs_page_ix exclusion_pix, - spiffs_page_ix *pix); - -s32_t spiffs_obj_lu_find_id_and_span_by_phdr( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_span_ix spix, - spiffs_page_ix exclusion_pix, - spiffs_page_ix *pix); - -// --------------- - -s32_t spiffs_page_allocate_data( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_page_header *ph, - u8_t *data, - u32_t len, - u32_t page_offs, - u8_t finalize, - spiffs_page_ix *pix); - -s32_t spiffs_page_move( - spiffs *fs, - spiffs_file fh, - u8_t *page_data, - spiffs_obj_id obj_id, - spiffs_page_header *page_hdr, - spiffs_page_ix src_pix, - spiffs_page_ix *dst_pix); - -s32_t spiffs_page_delete( - spiffs *fs, - spiffs_page_ix pix); - -// --------------- - -s32_t spiffs_object_create( - spiffs *fs, - spiffs_obj_id obj_id, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - spiffs_obj_type type, - spiffs_page_ix *objix_hdr_pix); - -s32_t spiffs_object_update_index_hdr( - spiffs *fs, - spiffs_fd *fd, - spiffs_obj_id obj_id, - spiffs_page_ix objix_hdr_pix, - u8_t *new_objix_hdr_data, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - u32_t size, - spiffs_page_ix *new_pix); - -void spiffs_cb_object_event( - spiffs *fs, - spiffs_fd *fd, - int ev, - spiffs_obj_id obj_id, - spiffs_span_ix spix, - spiffs_page_ix new_pix, - u32_t new_size); - -s32_t spiffs_object_open_by_id( - spiffs *fs, - spiffs_obj_id obj_id, - spiffs_fd *f, - spiffs_flags flags, - spiffs_mode mode); - -s32_t spiffs_object_open_by_page( - spiffs *fs, - spiffs_page_ix pix, - spiffs_fd *f, - spiffs_flags flags, - spiffs_mode mode); - -s32_t spiffs_object_append( - spiffs_fd *fd, - u32_t offset, - u8_t *data, - u32_t len); - -s32_t spiffs_object_modify( - spiffs_fd *fd, - u32_t offset, - u8_t *data, - u32_t len); - -s32_t spiffs_object_read( - spiffs_fd *fd, - u32_t offset, - u32_t len, - u8_t *dst); - -s32_t spiffs_object_truncate( - spiffs_fd *fd, - u32_t new_len, - u8_t remove_object); - -s32_t spiffs_object_find_object_index_header_by_name( - spiffs *fs, - const u8_t name[SPIFFS_OBJ_NAME_LEN], - spiffs_page_ix *pix); - -// --------------- - -s32_t spiffs_gc_check( - spiffs *fs, - u32_t len); - -s32_t spiffs_gc_erase_page_stats( - spiffs *fs, - spiffs_block_ix bix); - -s32_t spiffs_gc_find_candidate( - spiffs *fs, - spiffs_block_ix **block_candidate, - int *candidate_count, - char fs_crammed); - -s32_t spiffs_gc_clean( - spiffs *fs, - spiffs_block_ix bix); - -s32_t spiffs_gc_quick( - spiffs *fs, u16_t max_free_pages); - -// --------------- - -s32_t spiffs_fd_find_new( - spiffs *fs, - spiffs_fd **fd); - -s32_t spiffs_fd_return( - spiffs *fs, - spiffs_file f); - -s32_t spiffs_fd_get( - spiffs *fs, - spiffs_file f, - spiffs_fd **fd); - -#if SPIFFS_CACHE -void spiffs_cache_init( - spiffs *fs); - -void spiffs_cache_drop_page( - spiffs *fs, - spiffs_page_ix pix); - -#if SPIFFS_CACHE_WR -spiffs_cache_page *spiffs_cache_page_allocate_by_fd( - spiffs *fs, - spiffs_fd *fd); - -void spiffs_cache_fd_release( - spiffs *fs, - spiffs_cache_page *cp); - -spiffs_cache_page *spiffs_cache_page_get_by_fd( - spiffs *fs, - spiffs_fd *fd); -#endif -#endif - -s32_t spiffs_lookup_consistency_check( - spiffs *fs, - u8_t check_all_objects); - -s32_t spiffs_page_consistency_check( - spiffs *fs); - -s32_t spiffs_object_index_consistency_check( - spiffs *fs); - -#endif /* SPIFFS_NUCLEUS_H_ */ diff --git a/arduino/realtek-ambz/cores/arduino/syscalls.h b/arduino/realtek-ambz/cores/arduino/syscalls.h deleted file mode 100644 index 845b4b5d3..000000000 --- a/arduino/realtek-ambz/cores/arduino/syscalls.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -/** - * \file syscalls.h - * - * Implementation of newlib syscall. - * - */ - -/*---------------------------------------------------------------------------- - * Headers - *----------------------------------------------------------------------------*/ -#include -#include -#include -#include - -/*---------------------------------------------------------------------------- - * Exported functions - *----------------------------------------------------------------------------*/ -#ifdef __cplusplus -extern "C" { -#endif - -extern caddr_t _sbrk( int incr ) ; - -extern int link( char *cOld, char *cNew ) ; - -extern int _close( int file ) ; - -extern int _fstat( int file, struct stat *st ) ; - -extern int _isatty( int file ) ; - -extern int _lseek( int file, int ptr, int dir ) ; - -extern int _read(int file, char *ptr, int len) ; - -extern int _write( int file, char *ptr, int len ) ; - -#ifdef __cplusplus -} -#endif - diff --git a/arduino/realtek-ambz/cores/arduino/wiring.c b/arduino/realtek-ambz/cores/arduino/wiring.c index 4131e128d..d5b12f875 100644 --- a/arduino/realtek-ambz/cores/arduino/wiring.c +++ b/arduino/realtek-ambz/cores/arduino/wiring.c @@ -16,107 +16,80 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "cmsis_os.h" +#include +#include #ifndef portNVIC_SYSTICK_CURRENT_VALUE_REG -#define portNVIC_SYSTICK_CURRENT_VALUE_REG ( * ( ( volatile uint32_t * ) 0xe000e018 ) ) +#define portNVIC_SYSTICK_CURRENT_VALUE_REG (*((volatile uint32_t *)0xe000e018)) #endif extern uint32_t xTaskGetTickCount(); extern uint32_t xTaskGetTickCountFromISR(); -static __inline uint32_t __get_ipsr__(void) -{ - volatile uint32_t __regIPSR __asm("ipsr"); - return(__regIPSR); +static __inline uint32_t __get_ipsr__(void) { + volatile uint32_t __regIPSR __asm("ipsr"); + return (__regIPSR); } -void init(void) -{ - // nop +void init(void) { + // nop } -void delay( uint32_t ms ) -{ - osStatus ret; +void delay(uint32_t ms) { + /* osStatus ret; */ - ret = osDelay(ms); - if ( (ret != osEventTimeout) && (ret != osOK) ) { - //printf("delay : ERROR : 0x%x \n", ret); - } + /* ret = */ osDelay(ms); + /* if ((ret != osEventTimeout) && (ret != osOK)) { + printf("delay : ERROR : 0x%x \n", ret); + } */ } -void delayMicroseconds(unsigned int us) -{ - int i; - uint32_t t0, tn; - int dfactor = 0; - -#if defined(BOARD_RTL8710) -// dfactor = 10 * us - 10 + (40 * us / 100); - dfactor = 20 * us - 10 + (81 * us / 100); -#elif defined(BOARD_RTL8195A) - dfactor = 20 * us - 10 + (81 * us / 100); -#else - dfactor = 20 * us - 10 + (81 * us / 100); -#endif - - if ( us > 100 ) { - t0 = micros(); - do { - tn = micros(); - } while ( tn >= t0 && tn < (t0 + us - 1) ); - } else { - for (i=0; i 100) { + t0 = micros(); + do { + tn = micros(); + } while (tn >= t0 && tn < (t0 + us - 1)); + } else { + for (i = 0; i < dfactor; i++) { + asm("nop"); + } + } } -uint32_t millis( void ) -{ - return (__get_ipsr__() == 0) ? xTaskGetTickCount() : xTaskGetTickCountFromISR(); +uint32_t millis(void) { + return (__get_ipsr__() == 0) ? xTaskGetTickCount() : xTaskGetTickCountFromISR(); } -uint32_t micros( void ) -{ - uint32_t tick1, tick2; - uint32_t us; - uint32_t tick_per_us; - -#if defined(BOARD_RTL8710) - tick_per_us = 166666; // 83333; -#elif defined(BOARD_RTL8195A) - tick_per_us = 166666; -#else - tick_per_us = 166666; -#endif +uint32_t micros(void) { + uint32_t tick1, tick2; + uint32_t us; + uint32_t tick_per_us = 166666; + + if (__get_ipsr__() == 0) { + tick1 = xTaskGetTickCount(); + us = portNVIC_SYSTICK_CURRENT_VALUE_REG; + tick2 = xTaskGetTickCount(); + } else { + tick1 = xTaskGetTickCountFromISR(); + us = portNVIC_SYSTICK_CURRENT_VALUE_REG; + tick2 = xTaskGetTickCountFromISR(); + } - if (__get_ipsr__() == 0) { - tick1 = xTaskGetTickCount(); - us = portNVIC_SYSTICK_CURRENT_VALUE_REG; - tick2 = xTaskGetTickCount(); - } else { - tick1 = xTaskGetTickCountFromISR(); - us = portNVIC_SYSTICK_CURRENT_VALUE_REG; - tick2 = xTaskGetTickCountFromISR(); - } - - if (tick1 == tick2) { - return tick1 * 1000 - us*1000 / tick_per_us; - } else if( (us*1000 / tick_per_us) < 500 ) { - return tick1 * 1000 - us*1000 / tick_per_us; - } else { - return tick1 * 1000; - } + if (tick1 == tick2) { + return tick1 * 1000 - us * 1000 / tick_per_us; + } else if ((us * 1000 / tick_per_us) < 500) { + return tick1 * 1000 - us * 1000 / tick_per_us; + } else { + return tick1 * 1000; + } } -#ifdef __cplusplus +void yield(void) { + vTaskDelay(1); + taskYIELD(); } -#endif diff --git a/arduino/realtek-ambz/cores/arduino/wiring_analog.c b/arduino/realtek-ambz/cores/arduino/wiring_analog.c index 86ecddb4d..9eb90f852 100644 --- a/arduino/realtek-ambz/cores/arduino/wiring_analog.c +++ b/arduino/realtek-ambz/cores/arduino/wiring_analog.c @@ -16,225 +16,190 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -// RTL8710 module do not support ADC/DAC -#if 1 // !defined(BOARD_RTL8710) - -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "analogin_api.h" -#include "analogout_api.h" -#include "pwmout_api.h" -#include "gpio_ex_api.h" - +#include +#include +#include +#include +#include /* ADC */ -analogin_t adc1; -analogin_t adc2; -analogin_t adc3; +analogin_t adc1; +analogin_t adc2; +analogin_t adc3; -static const float ADC_slope1 = (3.12)/(3410.0-674.0); -static const float ADC_slope2 = (3.3-3.12)/(3454.0-3410.0); +static const float ADC_slope1 = (3.12) / (3410.0 - 674.0); +static const float ADC_slope2 = (3.3 - 3.12) / (3454.0 - 3410.0); -bool g_adc_enabled[] = { - false, false, false -}; +bool g_adc_enabled[] = {false, false, false}; extern void *gpio_pin_struct[]; -// -// Arduino -// +extern void pinRemoveMode(pin_size_t pinNumber); -static int _readResolution = 10; +static int _readResolution = 10; static int _writeResolution = 8; -static int _writePeriod = 20000; +static int _writePeriod = 20000; void analogReadResolution(int res) { - _readResolution = res; + _readResolution = res; } void analogWriteResolution(int res) { - _writeResolution = res; + _writeResolution = res; } void analogWritePeriod(int us) { - _writePeriod = us; + _writePeriod = us; } static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) { - if (from == to) - return value; - if (from > to) - return value >> (from-to); - else - return value << (to-from); + if (from == to) + return value; + if (from > to) + return value >> (from - to); + else + return value << (to - from); } uint8_t analog_reference = AR_DEFAULT; -void analogReference(uint8_t mode) -{ - analog_reference = mode; +void analogReference(uint8_t mode) { + analog_reference = mode; } -int analogRead(pin_size_t pinNumber) -{ - uint32_t ulValue = 0; - uint32_t ulChannel; - uint16_t ret = 0; - float voltage; - float adc_value; - - switch ( pinNumber ) { - case PIN_A0: - if (g_adc_enabled[0] == false) - { - analogin_init(&adc1, AD_1); - g_adc_enabled[0] = true; - } - case PIN_A1: - if (g_adc_enabled[1] == false) - { - analogin_init(&adc2, AD_2); - g_adc_enabled[1] = true; - } - ret = analogin_read_u16(&adc2); - break; - case PIN_A2: - if (g_adc_enabled[2] == false) - { - analogin_init(&adc3, AD_3); - g_adc_enabled[2] = true; - } - ret = analogin_read_u16(&adc3); - break; - default: - printf("%s : pinNumber %d wrong\n", __FUNCTION__, pinNumber); - return 0; - } - - ret >>= 4; - if (ret < 674) { - voltage = 0; - } else if ( ret > 3410){ - voltage = (float)(ret - 3410)*ADC_slope2 + 3.12; - } else { - voltage = (float)(ret-674)*ADC_slope1; - } - - ret = round((1<<_readResolution)*voltage/3.3); - if ( ret >= (1<<_readResolution) ) ret = (1<<_readResolution) - 1; - return ret; - +int analogRead(pin_size_t pinNumber) { + uint32_t ulValue = 0; + uint32_t ulChannel; + uint16_t ret = 0; + float voltage; + float adc_value; + + switch (pinNumber) { + case PIN_A0: + if (g_adc_enabled[0] == false) { + analogin_init(&adc1, AD_1); + g_adc_enabled[0] = true; + } + case PIN_A1: + if (g_adc_enabled[1] == false) { + analogin_init(&adc2, AD_2); + g_adc_enabled[1] = true; + } + ret = analogin_read_u16(&adc2); + break; + case PIN_A2: + if (g_adc_enabled[2] == false) { + analogin_init(&adc3, AD_3); + g_adc_enabled[2] = true; + } + ret = analogin_read_u16(&adc3); + break; + default: + printf("%s : pinNumber %d wrong\n", __FUNCTION__, pinNumber); + return 0; + } + + ret >>= 4; + if (ret < 674) { + voltage = 0; + } else if (ret > 3410) { + voltage = (float)(ret - 3410) * ADC_slope2 + 3.12; + } else { + voltage = (float)(ret - 674) * ADC_slope1; + } + + ret = round((1 << _readResolution) * voltage / 3.3); + if (ret >= (1 << _readResolution)) + ret = (1 << _readResolution) - 1; + return ret; } void analogOutputInit(void) { - // nop + // nop } // Right now, PWM output only works on the pins with // hardware support. These are defined in the appropriate // pins_*.c file. For the rest of the pins, we default // to digital output. -void analogWrite(pin_size_t pinNumber, int value) -{ - pwmout_t *obj; - - if ((g_APinDescription[pinNumber].ulPinAttribute & PIO_PWM) == PIO_PWM) { - /* Handle */ - if ( g_APinDescription[pinNumber].ulPinType != PIO_PWM ) - { - if ( (g_APinDescription[pinNumber].ulPinType == PIO_GPIO) || (g_APinDescription[pinNumber].ulPinType == PIO_GPIO_IRQ) ) { - pinRemoveMode(pinNumber); - } - gpio_pin_struct[pinNumber] = malloc ( sizeof(pwmout_t) ); - pwmout_t *obj = (pwmout_t *)gpio_pin_struct[pinNumber]; - pwmout_init( obj, g_APinDescription[pinNumber].pinname ); - pwmout_period_us( obj, _writePeriod); - pwmout_write( obj, value * 1.0 / (1<<_writeResolution)); - g_APinDescription[pinNumber].ulPinType = PIO_PWM; - g_APinDescription[pinNumber].ulPinMode = PWM_MODE_ENABLED; - } else { - pwmout_t *obj = (pwmout_t *)gpio_pin_struct[pinNumber]; - pwmout_period_us( obj, _writePeriod); - pwmout_write( obj, value * 1.0 / (1<<_writeResolution)); - /* if ( g_APinDescription[pinNumber].ulPinMode == PWM_MODE_DISABLED ) { - HAL_Pwm_Enable( &obj->pwm_hal_adp ); - } */ - } - } +void analogWrite(pin_size_t pinNumber, int value) { + pwmout_t *obj; + + if ((g_APinDescription[pinNumber].ulPinAttribute & PIO_PWM) == PIO_PWM) { + /* Handle */ + if (g_APinDescription[pinNumber].ulPinType != PIO_PWM) { + if ((g_APinDescription[pinNumber].ulPinType == PIO_GPIO) || + (g_APinDescription[pinNumber].ulPinType == PIO_GPIO_IRQ)) { + pinRemoveMode(pinNumber); + } + gpio_pin_struct[pinNumber] = malloc(sizeof(pwmout_t)); + pwmout_t *obj = (pwmout_t *)gpio_pin_struct[pinNumber]; + pwmout_init(obj, g_APinDescription[pinNumber].pinname); + pwmout_period_us(obj, _writePeriod); + pwmout_write(obj, value * 1.0 / (1 << _writeResolution)); + g_APinDescription[pinNumber].ulPinType = PIO_PWM; + g_APinDescription[pinNumber].ulPinMode = PWM_MODE_ENABLED; + } else { + pwmout_t *obj = (pwmout_t *)gpio_pin_struct[pinNumber]; + pwmout_period_us(obj, _writePeriod); + pwmout_write(obj, value * 1.0 / (1 << _writeResolution)); + /* if ( g_APinDescription[pinNumber].ulPinMode == PWM_MODE_DISABLED ) { + HAL_Pwm_Enable( &obj->pwm_hal_adp ); + } */ + } + } } typedef struct _tone_argument { - uint32_t ulPin; - uint32_t timer_id; + uint32_t ulPin; + uint32_t timer_id; }; -void _tone_timer_handler(void const *argument) -{ - struct _tone_argument *arg = (struct _tone_argument *)argument; +void _tone_timer_handler(const void *argument) { + struct _tone_argument *arg = (struct _tone_argument *)argument; - uint32_t ulPin = (uint32_t) argument; + uint32_t ulPin = (uint32_t)argument; - noTone(arg->ulPin); + noTone(arg->ulPin); - os_timer_delete(arg->timer_id); + os_timer_delete(arg->timer_id); - free( (struct _tone_argument *) arg ); + free((struct _tone_argument *)arg); } -void _tone(uint32_t ulPin, unsigned int frequency, unsigned long duration) -{ - pwmout_t *obj; - - if ((g_APinDescription[ulPin].ulPinAttribute & PIO_PWM) != PIO_PWM) { - return; - } - - if ( g_APinDescription[ulPin].ulPinType != PIO_PWM ) - { - if ( (g_APinDescription[ulPin].ulPinType == PIO_GPIO) || (g_APinDescription[ulPin].ulPinType == PIO_GPIO_IRQ) ) { - pinRemoveMode(ulPin); - } - gpio_pin_struct[ulPin] = malloc ( sizeof(pwmout_t) ); - pwmout_t *obj = (pwmout_t *)gpio_pin_struct[ulPin]; - pwmout_init( obj, g_APinDescription[ulPin].pinname); - pwmout_period( obj, 1.0/frequency ); - pwmout_pulsewidth( obj, 1.0/(frequency * 2) ); - g_APinDescription[ulPin].ulPinType = PIO_PWM; - g_APinDescription[ulPin].ulPinMode = PWM_MODE_ENABLED; - - } else { - // There is already a PWM configured - pwmout_t *obj = (pwmout_t *)gpio_pin_struct[ulPin]; - pwmout_period( obj, 1.0/frequency ); - pwmout_pulsewidth( obj, 1.0/(frequency * 2)); - /* if (g_APinDescription[ulPin].ulPinMode == PWM_MODE_DISABLED) { - HAL_Pwm_Enable( &obj->pwm_hal_adp ); - } */ - } - - if (duration > 0) { - struct _tone_argument *arg = (struct _tone_argument *) malloc ( sizeof(struct _tone_argument) ); - arg->ulPin = ulPin; - arg->timer_id = os_timer_create(_tone_timer_handler, 0, arg); - os_timer_start(arg->timer_id, duration); - } +void _tone(uint32_t ulPin, unsigned int frequency, unsigned long duration) { + pwmout_t *obj; + + if ((g_APinDescription[ulPin].ulPinAttribute & PIO_PWM) != PIO_PWM) { + return; + } + + if (g_APinDescription[ulPin].ulPinType != PIO_PWM) { + if ((g_APinDescription[ulPin].ulPinType == PIO_GPIO) || (g_APinDescription[ulPin].ulPinType == PIO_GPIO_IRQ)) { + pinRemoveMode(ulPin); + } + gpio_pin_struct[ulPin] = malloc(sizeof(pwmout_t)); + pwmout_t *obj = (pwmout_t *)gpio_pin_struct[ulPin]; + pwmout_init(obj, g_APinDescription[ulPin].pinname); + pwmout_period(obj, 1.0 / frequency); + pwmout_pulsewidth(obj, 1.0 / (frequency * 2)); + g_APinDescription[ulPin].ulPinType = PIO_PWM; + g_APinDescription[ulPin].ulPinMode = PWM_MODE_ENABLED; + + } else { + // There is already a PWM configured + pwmout_t *obj = (pwmout_t *)gpio_pin_struct[ulPin]; + pwmout_period(obj, 1.0 / frequency); + pwmout_pulsewidth(obj, 1.0 / (frequency * 2)); + /* if (g_APinDescription[ulPin].ulPinMode == PWM_MODE_DISABLED) { + HAL_Pwm_Enable( &obj->pwm_hal_adp ); + } */ + } + + if (duration > 0) { + struct _tone_argument *arg = (struct _tone_argument *)malloc(sizeof(struct _tone_argument)); + arg->ulPin = ulPin; + arg->timer_id = os_timer_create(_tone_timer_handler, 0, arg); + os_timer_start(arg->timer_id, duration); + } } - -void noTone(uint32_t ulPin) -{ - pinRemoveMode(ulPin); -} - -#ifdef __cplusplus -} -#endif - -//#else // #if !defined(BOARD_RTL8710) - -#endif // #if !defined(BOARD_RTL8710) diff --git a/arduino/realtek-ambz/cores/arduino/wiring_digital.c b/arduino/realtek-ambz/cores/arduino/wiring_digital.c index 79d50797f..dcdf2ba0d 100644 --- a/arduino/realtek-ambz/cores/arduino/wiring_digital.c +++ b/arduino/realtek-ambz/cores/arduino/wiring_digital.c @@ -1,13 +1,8 @@ -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "gpio_api.h" -#include "gpio_irq_api.h" -#include "gpio_irq_ex_api.h" -#include "pwmout_api.h" +#include +#include +#include +#include +#include extern void *gpio_pin_struct[PINS_COUNT]; extern void *gpio_irq_handler_list[PINS_COUNT]; @@ -33,7 +28,7 @@ void pinRemoveMode(pin_size_t pinNumber) { gpio_irq_deinit(obj); free(obj); } - gpio_pin_struct[pinNumber] = NULL; + gpio_pin_struct[pinNumber] = NULL; g_APinDescription[pinNumber].ulPinType = NOT_INITIAL; g_APinDescription[pinNumber].ulPinMode = NOT_INITIAL; } @@ -59,7 +54,7 @@ void pinMode(pin_size_t pinNumber, PinModeArduino pinMode) { if (g_APinDescription[pinNumber].ulPinType == NOT_INITIAL) { // allocate memory if pin not used before - gpio = malloc(sizeof(gpio_t)); + gpio = malloc(sizeof(gpio_t)); gpio_pin_struct[pinNumber] = gpio; gpio_init(gpio, g_APinDescription[pinNumber].pinname); g_APinDescription[pinNumber].ulPinType = PIO_GPIO; @@ -74,23 +69,23 @@ void pinMode(pin_size_t pinNumber, PinModeArduino pinMode) { switch (pinMode) { case INPUT: - dir = PIN_INPUT; + dir = PIN_INPUT; mode = PullNone; break; case INPUT_PULLDOWN: - dir = PIN_INPUT; + dir = PIN_INPUT; mode = PullDown; break; case INPUT_PULLUP: - dir = PIN_INPUT; + dir = PIN_INPUT; mode = PullUp; break; case OUTPUT: - dir = PIN_OUTPUT; + dir = PIN_OUTPUT; mode = PullNone; break; case OUTPUT_OPENDRAIN: - dir = PIN_OUTPUT; + dir = PIN_OUTPUT; mode = OpenDrain; break; default: @@ -138,7 +133,3 @@ uint32_t digitalPinToBitMask(uint32_t pinNumber) { uint32_t pin_name = HAL_GPIO_GetPinName(g_APinDescription[pinNumber].pinname); return 1 << (HAL_GPIO_GET_PIN_BY_NAME(pin_name)); } - -#ifdef __cplusplus -} -#endif diff --git a/arduino/realtek-ambz/cores/arduino/wiring_os.c b/arduino/realtek-ambz/cores/arduino/wiring_os.c deleted file mode 100644 index dac33929e..000000000 --- a/arduino/realtek-ambz/cores/arduino/wiring_os.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "wiring_os.h" -#include "cmsis_os.h" - -uint32_t os_thread_create( void (*task)(const void *argument), void *argument, int priority, uint32_t stack_size ) { - - osThreadDef_t thread_def; - - thread_def.pthread = task; - thread_def.tpriority = (osPriority)priority; - // the underlying freertos implementation on cmsis os divide stack size by 4 - thread_def.stacksize = stack_size * 4; - thread_def.name = "ARDUINO"; - - return (uint32_t)osThreadCreate(&thread_def, argument); -} - -uint32_t os_thread_get_id( void ) { - return osThreadGetId(); -} - -uint32_t os_thread_terminate( uint32_t thread_id ) { - return (uint32_t)osThreadTerminate(thread_id); -} - -uint32_t os_thread_yield( void ) { - return (uint32_t)osThreadYield(); -} - -uint32_t os_thread_set_priority( uint32_t thread_id, int priority ) { - return (uint32_t)osThreadSetPriority(thread_id, (osPriority)priority); -} - -int os_thread_get_priority( uint32_t thread_id ) { - return (int)osThreadGetPriority(thread_id); -} - -int32_t os_signal_set( uint32_t thread_id, int32_t signals ) { - return osSignalSet(thread_id, signals); -} - -int32_t os_signal_clear( uint32_t thread_id, int32_t signals ) { - return osSignalClear(thread_id, signals); -} - -os_event_t os_signal_wait( int32_t signals, uint32_t millisec ) { - - osEvent evt; - os_event_t ret; - - evt = osSignalWait(signals, millisec); - ret.status = (uint32_t)evt.status; - ret.value.signals = evt.value.signals; - ret.def.message_id = evt.def.message_id; - - return ret; -} - -typedef void (*os_ptimer) (void const *argument); - -uint32_t os_timer_create(void (*callback)(void const *argument), uint8_t isPeriodic, void *argument) { - - osTimerDef_t *pTimerDef; - - pTimerDef = (osTimerDef_t *) malloc ( sizeof(osTimerDef_t) ); - pTimerDef->ptimer = callback; - pTimerDef->custom = (struct os_timer_custom *) malloc ( sizeof (struct os_timer_custom) ); - - return osTimerCreate(pTimerDef, (isPeriodic ? osTimerPeriodic : osTimerOnce), argument); -} - -uint32_t os_timer_start (uint32_t timer_id, uint32_t millisec) { - return osTimerStart (timer_id, millisec); -} - -uint32_t os_timer_stop (uint32_t timer_id) { - return osTimerStop(timer_id); -} - -uint32_t os_timer_delete(uint32_t timer_id) { - - osTimerDef_t *pTimerDef; - - pTimerDef = (osTimerDef_t *) pvTimerGetTimerID(timer_id); - free (pTimerDef->custom); - free (pTimerDef); - - return osTimerDelete(timer_id); -} - -uint32_t os_semaphore_create(int32_t count) { - return (uint32_t)osSemaphoreCreate(NULL, count); -} - -int32_t os_semaphore_wait(uint32_t semaphore_id, uint32_t millisec) { - if (osSemaphoreWait((osSemaphoreId)semaphore_id, millisec) == 0) { - return 1; - } else { - return 0; - } -} - -uint32_t os_semaphore_release(uint32_t semaphore_id) { - return (uint32_t)osSemaphoreRelease((osSemaphoreId)semaphore_id); -} - -uint32_t os_semaphore_delete(uint32_t semaphore_id) { - return (uint32_t)osSemaphoreDelete((osSemaphoreId)semaphore_id); -} - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/arduino/realtek-ambz/cores/arduino/wiring_pulse.cpp b/arduino/realtek-ambz/cores/arduino/wiring_pulse.c similarity index 78% rename from arduino/realtek-ambz/cores/arduino/wiring_pulse.cpp rename to arduino/realtek-ambz/cores/arduino/wiring_pulse.c index 65627cc48..ef7df1966 100644 --- a/arduino/realtek-ambz/cores/arduino/wiring_pulse.cpp +++ b/arduino/realtek-ambz/cores/arduino/wiring_pulse.c @@ -8,7 +8,7 @@ This library 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. + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public @@ -16,16 +16,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "PinNames.h" -#include "objects.h" -#include "gpio_api.h" -#include "us_ticker_api.h" +#include +#include +#include +#include +#include extern void *gpio_pin_struct[]; @@ -33,8 +28,7 @@ extern void *gpio_pin_struct[]; * or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds * to 3 minutes in length, but must be called at least a few dozen microseconds * before the start of the pulse. */ -extern unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) -{ +extern unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) { // cache the port and bit of the pin in order to speed up the // pulse width measuring loop and achieve finer resolution. calling // digitalRead() instead yields much coarser resolution. @@ -42,12 +36,12 @@ extern unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) uint32_t start_ticks, cur_ticks; - if ( pin < 0 || pin > PINS_COUNT || (g_APinDescription[pin].pinname == NC) ) return 0; + if (pin < 0 || pin > PINS_COUNT || (g_APinDescription[pin].pinname == NC)) + return 0; /* Handle */ - if ( g_APinDescription[pin].ulPinType != PIO_GPIO ) - { - return 0; + if (g_APinDescription[pin].ulPinType != PIO_GPIO) { + return 0; } pGpio_t = (gpio_t *)gpio_pin_struct[pin]; @@ -56,20 +50,23 @@ extern unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) start_ticks = us_ticker_read(); while (gpio_read(pGpio_t) == state) { cur_ticks = us_ticker_read(); - if ( cur_ticks - start_ticks > timeout ) return 0; + if (cur_ticks - start_ticks > timeout) + return 0; } // wait for the pulse to start while (gpio_read(pGpio_t) != state) { cur_ticks = us_ticker_read(); - if ( cur_ticks - start_ticks > timeout ) return 0; + if (cur_ticks - start_ticks > timeout) + return 0; } // wait for the pulse to stop start_ticks = us_ticker_read(); while (gpio_read(pGpio_t) == state) { cur_ticks = us_ticker_read(); - if ( cur_ticks - start_ticks > timeout ) return 0; + if (cur_ticks - start_ticks > timeout) + return 0; } cur_ticks = us_ticker_read(); @@ -80,7 +77,3 @@ extern unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout) // the interrupt handlers. return cur_ticks - start_ticks; } - -#ifdef __cplusplus -} -#endif diff --git a/arduino/realtek-ambz/cores/arduino/wiring_shift.c b/arduino/realtek-ambz/cores/arduino/wiring_shift.c deleted file mode 100644 index 76c0c8bd4..000000000 --- a/arduino/realtek-ambz/cores/arduino/wiring_shift.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -#include "Arduino.h" - -#ifdef __cplusplus -extern "C"{ -#endif - -uint8_t shiftIn(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder) -{ - uint8_t value = 0 ; - uint8_t i ; - - for ( i=0 ; i < 8 ; ++i ) - { - digitalWrite( dataPin, HIGH ) ; - - if ( bitOrder == LSBFIRST ) - { - value |= digitalRead( dataPin ) << i ; - } - else - { - value |= digitalRead( dataPin ) << (7 - i) ; - } - - digitalWrite( clockPin, LOW ) ; - } - - return value ; -} - -void shiftOut(pin_size_t dataPin, pin_size_t clockPin, BitOrder bitOrder, uint8_t val) -{ - uint8_t i ; - - for ( i=0 ; i < 8 ; i++ ) - { - if ( bitOrder == LSBFIRST ) - { - digitalWrite( dataPin, !!(val & (1 << i)) ) ; - } - else - { - digitalWrite( dataPin, !!(val & (1 << (7 - i))) ) ; - } - - digitalWrite( clockPin, HIGH ) ; - digitalWrite( clockPin, LOW ) ; - } -} - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/arduino/realtek-ambz/cores/arduino/wiring_watchdog.c b/arduino/realtek-ambz/cores/arduino/wiring_watchdog.c deleted file mode 100644 index 390545c4c..000000000 --- a/arduino/realtek-ambz/cores/arduino/wiring_watchdog.c +++ /dev/null @@ -1,37 +0,0 @@ -#include "Arduino.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "wdt_api.h" - -extern uint32_t ConfigDebugErr; - -void wdt_reset() { - watchdog_refresh(); -} - -void wdt_enable(uint32_t timeout_ms) { - - uint32_t backup_ConfigDebugErr; - - backup_ConfigDebugErr = ConfigDebugErr; - ConfigDebugErr = 0x00000000; - - if (timeout_ms > 8000) { - timeout_ms = 8000; - } - watchdog_init(timeout_ms); - watchdog_start(); - - ConfigDebugErr = backup_ConfigDebugErr; -} - -void wdt_disable() { - watchdog_stop(); -} - -#ifdef __cplusplus -} // extern "C" -#endif diff --git a/arduino/realtek-ambz/cores/arduino/wiring_watchdog.h b/arduino/realtek-ambz/cores/arduino/wiring_watchdog.h deleted file mode 100644 index 6e5cdaeb4..000000000 --- a/arduino/realtek-ambz/cores/arduino/wiring_watchdog.h +++ /dev/null @@ -1,46 +0,0 @@ -/** @file wiring_watchdog.h */ - -/** - * @defgroup wiring_watchdog wiring_watchdog - * watchdog is used for reboot system when device hang - * @{ - */ - -#ifndef _WIRING_WATCHDOG_H_ -#define _WIRING_WATCHDOG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/** @defgroup watchdog */ - -/** - * @ingroup watchdog - * Feed watchdog to avoid it barks - */ -extern void wdt_reset(); - -/** - * @ingroup watchdog - * @brief Enable watchdog - * - * After enbling watchdog, user defined code needs to reset it before watchdog barks. Otherwise it would make system reboot. - * - * @param[in] timeout_ms The timeout value that watchdog barks. The maximum value is 8 seconds. - */ -extern void wdt_enable(uint32_t timeout_ms); - -/** - * @ingroup watchdog - * Disable watchdog - */ -extern void wdt_disable(); - -#ifdef __cplusplus -} -#endif - -#endif /* _WIRING_WATCHDOG_H_ */ - -/** @} */ // end of group wiring_watchdog \ No newline at end of file diff --git a/arduino/realtek-ambz/cores/arduino/wl_definitions.h b/arduino/realtek-ambz/cores/arduino/wl_definitions.h deleted file mode 100644 index 0ef45a9e9..000000000 --- a/arduino/realtek-ambz/cores/arduino/wl_definitions.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - wl_definitions.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -/* - * wl_definitions.h - * - * Created on: Mar 6, 2011 - * Author: dlafauci - */ - -#ifndef WL_DEFINITIONS_H_ -#define WL_DEFINITIONS_H_ - -// Maximum size of a SSID -#define WL_SSID_MAX_LENGTH 32 -// Length of passphrase. Valid lengths are 8-63. -#define WL_WPA_KEY_MAX_LENGTH 63 -// Length of key in bytes. Valid values are 5 and 13. -#define WL_WEP_KEY_MAX_LENGTH 13 -// Size of a MAC-address or BSSID -#define WL_MAC_ADDR_LENGTH 6 -// Size of a MAC-address or BSSID -#define WL_IPV4_LENGTH 4 -// Maximum size of a SSID list -#define WL_NETWORKS_LIST_MAXNUM 50 -// Maxmium number of socket -#define MAX_SOCK_NUM 4 -// Socket not available constant -#define SOCK_NOT_AVAIL 255 -// Default state value for Wifi state field -#define NA_STATE -1 -//Maximum number of attempts to establish wifi connection -#define WL_MAX_ATTEMPT_CONNECTION 10 - -typedef enum { - WL_NO_SHIELD = 255, - WL_IDLE_STATUS = 0, - WL_NO_SSID_AVAIL, - WL_SCAN_COMPLETED, - WL_CONNECTED, - WL_CONNECT_FAILED, - WL_CONNECTION_LOST, - WL_DISCONNECTED -} wl_status_t; - -/* Encryption modes */ -enum wl_enc_type { /* Values map to 802.11 encryption suites... */ - ENC_TYPE_WEP = 5, - ENC_TYPE_TKIP = 2, - ENC_TYPE_CCMP = 4, - /* ... except these two, 7 and 8 are reserved in 802.11-2007 */ - ENC_TYPE_NONE = 7, - ENC_TYPE_AUTO = 8 -}; - -/* RTK added type */ -#ifndef WEP_ENABLED - -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 - -#define SHARED_ENABLED 0x00008000 -#define WPA_SECURITY 0x00200000 -#define WPA2_SECURITY 0x00400000 -#define WPS_ENABLED 0x10000000 - -#endif // #ifndef WEP_ENABLED - -/* redefined from enum rtw_security_t */ -#define SECURITY_OPEN ( 0 ) -#define SECURITY_WEP_PSK ( WEP_ENABLED ) -#define SECURITY_WEP_SHARED ( WEP_ENABLED | SHARED_ENABLED ) -#define SECURITY_WPA_TKIP_PSK ( WPA_SECURITY | TKIP_ENABLED ) -#define SECURITY_WPA_AES_PSK ( WPA_SECURITY | AES_ENABLED ) -#define SECURITY_WPA2_AES_PSK ( WPA2_SECURITY | AES_ENABLED ) -#define SECURITY_WPA2_TKIP_PSK ( WPA2_SECURITY | TKIP_ENABLED ) -#define SECURITY_WPA2_MIXED_PSK ( WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED ) -#define SECURITY_WPA_WPA2_MIXED ( WPA_SECURITY | WPA2_SECURITY ) - - -#endif /* WL_DEFINITIONS_H_ */ diff --git a/arduino/realtek-ambz/cores/arduino/wl_types.h b/arduino/realtek-ambz/cores/arduino/wl_types.h deleted file mode 100644 index cb73b6054..000000000 --- a/arduino/realtek-ambz/cores/arduino/wl_types.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - wl_types.h - Library for Arduino Wifi shield. - Copyright (c) 2011-2014 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -/* - * wl_types.h - * - * Created on: Jul 30, 2010 - * Author: dlafauci - */ - - -#ifndef _WL_TYPES_H_ -#define _WL_TYPES_H_ - -#include - -typedef enum { - WL_FAILURE = -1, - WL_SUCCESS = 1, -} wl_error_code_t; - -/* Authentication modes */ -enum wl_auth_mode { - AUTH_MODE_INVALID, - AUTH_MODE_AUTO, - AUTH_MODE_OPEN_SYSTEM, - AUTH_MODE_SHARED_KEY, - AUTH_MODE_WPA, - AUTH_MODE_WPA2, - AUTH_MODE_WPA_PSK, - AUTH_MODE_WPA2_PSK -}; - -#endif //_WL_TYPES_H_ diff --git a/arduino/realtek-ambz/cores/arduino/wsclient_api.h b/arduino/realtek-ambz/cores/arduino/wsclient_api.h deleted file mode 100644 index 0b5b42326..000000000 --- a/arduino/realtek-ambz/cores/arduino/wsclient_api.h +++ /dev/null @@ -1,108 +0,0 @@ -#ifndef WSCLIENT_H -#define WSCLIENT_H -#include - - -/******Define the maximum bytes of data send and receive********/ -#define MAX_DATA_LEN 1500 -/****************Define if using the polarssl*******************/ -#define USING_SSL - - -/******************Define the function used*********************/ -#ifdef USING_SSL -int wss_set_fun_ops(wsclient_context *wsclient); -#define wsclient_set_fun_ops(wsclient) wss_set_fun_ops(wsclient) -#else -int ws_set_fun_ops(wsclient_context *wsclient); -#define wsclient_set_fun_ops(wsclient) ws_set_fun_ops(wsclient) -#endif -/***************************************************************/ - - - - -/************************************************************************************************* -** Function Name : create_wsclient -** Description : Creating the websocket client context structure -** Input : url:websocket server's url -** port:websocket server's port, if not given, default 80 for "ws", 443 for "wss" -** origin: the address or url of your self -** Return : Created: websocket client context structure -** Failed: NULL -**************************************************************************************************/ -wsclient_context *create_wsclient(char *url, int port,char *path, char* origin); - -/************************************************************************************************* -** Function Name : ws_connect_url -** Description : Connecting to the websocket server -** Input : wsclient: the websocket client context created by create_wsclientfunction -** Return : Connected: the socket value -** Failed: -1 -**************************************************************************************************/ -int ws_connect_url(wsclient_context *wsclient); - -/************************************************************************************************* -** Function Name : ws_send -** Description : Create the sending string data and copy to tx_buf -** Input : message: the string that send to server(cannot exceeding the MAX_DATA_LEN -** message_len: the length of the string -** use_mask: 0/1; 1 means using mask for bynary -** wsclient: the websocket client context -** Return : None -**************************************************************************************************/ -void ws_send(char* message, int message_len, int use_mask, wsclient_context *wsclient); - -/************************************************************************************************* -** Function Name : ws_sendBinary -** Description : Create the sending binary data and copy to tx_buf -** Input : message: the binary that send to server(cannot exceeding the MAX_DATA_LEN -** message_len: the length of the binary -** use_mask: 0/1; 1 means using mask for bynary -** wsclient: the websocket client context -** Return : None -**************************************************************************************************/ -void ws_sendBinary(uint8_t* message, int message_len, int use_mask, wsclient_context *wsclient); - -/************************************************************************************************* -** Function Name : ws_sendPing -** Description : Sending Ping to websocket server -** Input : wsclient: the websocket client context -** Return : None -**************************************************************************************************/ -void ws_sendPing(wsclient_context *wsclient); - -/************************************************************************************************* -** Function Name : ws_poll -** Description : Receicing data from server and send the data in tx_buf -** Input : timeout(in milliseconds) - wsclient: the websocket client context -** Return : None -**************************************************************************************************/ -void ws_poll(int timeout, wsclient_context *wsclient); - -/************************************************************************************************* -** Function Name : ws_dispatch -** Description : callback function when getting message from server -** Input : function that resolve the message received and the message length -** Return : None -**************************************************************************************************/ -void ws_dispatch(void (*callback)(wsclient_context *, int)) ; - -/************************************************************************************************* -** Function Name : ws_getReadyState -** Description : Getting the connection status -** Input : wsclient: the websocket client context -** Return : readyStateValues(4 types:CLOSING, CLOSED, CONNECTING, OPEN) -**************************************************************************************************/ -readyStateValues ws_getReadyState(wsclient_context *wsclient); - -/************************************************************************************************* -** Function Name : ws_close -** Description : Closing the connection with websocket server -** Input : wsclient: the websocket client context -** Return : None -**************************************************************************************************/ -void ws_close(wsclient_context *wsclient); - -#endif \ No newline at end of file diff --git a/arduino/realtek-ambz/libraries/Flash/Flash.cpp b/arduino/realtek-ambz/libraries/Flash/Flash.cpp index d921d9efb..f0b745c80 100644 --- a/arduino/realtek-ambz/libraries/Flash/Flash.cpp +++ b/arduino/realtek-ambz/libraries/Flash/Flash.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */ + #include "Flash.h" #include diff --git a/arduino/realtek-ambz/libraries/Flash/Flash.h b/arduino/realtek-ambz/libraries/Flash/Flash.h index 25b5ec1ad..cf0072779 100644 --- a/arduino/realtek-ambz/libraries/Flash/Flash.h +++ b/arduino/realtek-ambz/libraries/Flash/Flash.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-24. */ + #pragma once #include "api/Flash.h" diff --git a/arduino/realtek-ambz/cores/arduino/PowerManagement.cpp b/arduino/realtek-ambz/libraries/PowerManagement/PowerManagement.cpp similarity index 55% rename from arduino/realtek-ambz/cores/arduino/PowerManagement.cpp rename to arduino/realtek-ambz/libraries/PowerManagement/PowerManagement.cpp index 7806ee801..978d4d628 100644 --- a/arduino/realtek-ambz/cores/arduino/PowerManagement.cpp +++ b/arduino/realtek-ambz/libraries/PowerManagement/PowerManagement.cpp @@ -1,16 +1,15 @@ #include "PowerManagement.h" -#include "Arduino.h" + +#include #ifdef __cplusplus extern "C" { -#include "freertos_pmu.h" -#include "sys_api.h" -#include "sleep_ex_api.h" +#include +#include +#include } #endif -#include "variant.h" - #if defined(BOARD_RTL8195A) #define SAVE_LOCK_PIN 18 #elif defined(BOARD_RTL8710) @@ -22,38 +21,38 @@ extern "C" { bool PowerManagementClass::reservePLL = true; void PowerManagementClass::sleep(uint32_t bitflg) { - if (!safeLock()) { - pmu_release_wakelock(bitflg); - } + if (!safeLock()) { + pmu_release_wakelock(bitflg); + } } void PowerManagementClass::sleep(void) { - if (!safeLock()) { - pmu_release_wakelock(BIT(PMU_OS)); - } + if (!safeLock()) { + pmu_release_wakelock(BIT(PMU_OS)); + } } void PowerManagementClass::active(uint32_t bitflg) { - pmu_acquire_wakelock(bitflg); + pmu_acquire_wakelock(bitflg); } void PowerManagementClass::active(void) { - pmu_acquire_wakelock(BIT(PMU_OS)); + pmu_acquire_wakelock(BIT(PMU_OS)); } void PowerManagementClass::deepsleep(uint32_t duration_ms) { - if (!safeLock()) { - deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, duration_ms); - } + if (!safeLock()) { + deepsleep_ex(DSLEEP_WAKEUP_BY_TIMER, duration_ms); + } } bool PowerManagementClass::safeLock() { - pinMode(SAVE_LOCK_PIN, INPUT_PULLUP); - return (digitalRead(SAVE_LOCK_PIN) == 1) ? false : true; + pinMode(SAVE_LOCK_PIN, INPUT_PULLUP); + return (digitalRead(SAVE_LOCK_PIN) == 1) ? false : true; } void PowerManagementClass::softReset() { - sys_reset(); + sys_reset(); } PowerManagementClass PowerManagement; diff --git a/arduino/realtek-ambz/libraries/PowerManagement/PowerManagement.h b/arduino/realtek-ambz/libraries/PowerManagement/PowerManagement.h new file mode 100644 index 000000000..c2551d74c --- /dev/null +++ b/arduino/realtek-ambz/libraries/PowerManagement/PowerManagement.h @@ -0,0 +1,73 @@ +#pragma once + +#include + +/** + * @class PowerManagementClass PowerManagement.h + * @brief Power management in Ameba + */ +class PowerManagementClass { + public: + /** + * @brief Allow OS automatically save power while idle + * + * As OS consider it would idle for more than 2s, it will invoke system suspend. + * If wlan is associated with AP, than it will under asslociated idle state. + */ + static void sleep(void); + static void sleep(uint32_t bitflg); + + /** + * @brief Disallow OS automatically save power while idle + */ + static void active(void); + static void active(uint32_t bitflg); + + /** + * @brief Reserved PLL while sleep + * + * Reserve PLL would keep FIFO of peripherals (Ex. UART) but cost more power (around 5mA). + * If we don't reserve PLL, it saves more power but we might missing data because FIFO is turned of this way. + * + * @param[in] reserve true for reserved, false for non-reserved + */ + static void setPllReserved(bool reserve); + + /** + * @brief Enter deepsleep immediately + * + * Invoke deepsleep would make system enter deepsleep state immediately. + * It's the state that saves most power. + * As it wakeup from deepsleep, the system would behave just like reboot. + * + * @param[in] duration_ms wakeup after specific time in unit of millisecond + */ + static void deepsleep(uint32_t duration_ms); + + /** + * @brief Check if system is allowed enter any power save state + * + * The pin 18 (GPIOE_5) is designed as safe lock. + * If pin 18 is HIGH, then we prevent Ameba enter any power save state.\n\n + * Under any power save state, we are not able to flash image to Ameba. + * Thus if user misuse deepsleep and make Ameba enter deepsleep immediately after boot up, + * then he would find it's hard to flash image. + * In this case, he can pull up pin 18. + * + * @return true if system not allowed enter any power save state, and false vise versa + */ + static bool safeLock(); + + /** + * @brief Reboot system + * + * Reboot system in soft way. Some registers is not powered off in this case, but mostly we could regard this as + * reboot. + */ + static void softReset(); + + private: + static bool reservePLL; +}; + +extern PowerManagementClass PowerManagement; diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFi.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFi.cpp index d00e23ed9..00a29b398 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFi.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFi.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + #include "WiFi.h" #include "WiFiPriv.h" diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFi.h b/arduino/realtek-ambz/libraries/WiFi/WiFi.h index 82bfa38d0..c43bc9c9b 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFi.h +++ b/arduino/realtek-ambz/libraries/WiFi/WiFi.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + #pragma once #include diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiAP.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiAP.cpp index 04636e5ad..8c82ec37a 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiAP.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiAP.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + #include "WiFi.h" #include "WiFiPriv.h" diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiClient.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiClient.cpp index e901a27b4..1dc5da1e1 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiClient.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiClient.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-26. */ + #include "WiFiClient.h" #include "WiFiPriv.h" diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiClient.h b/arduino/realtek-ambz/libraries/WiFi/WiFiClient.h index e1d264f29..6184bee04 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiClient.h +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiClient.h @@ -1,7 +1,9 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-26. */ + #pragma once -#include #include +#include #include class SocketHandle; diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiGeneric.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiGeneric.cpp index e6967340b..cf8779ce3 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiGeneric.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiGeneric.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + #include "WiFi.h" #include "WiFiPriv.h" diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiPriv.h b/arduino/realtek-ambz/libraries/WiFi/WiFiPriv.h index 22b3a82d8..1f0ed2eef 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiPriv.h +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiPriv.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + #pragma once #ifdef __cplusplus diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiSTA.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiSTA.cpp index 49624d2e4..038eb04d6 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiSTA.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiSTA.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + #include "WiFi.h" #include "WiFiPriv.h" diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiScan.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiScan.cpp index 3a3d58a27..c3fcf1e19 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiScan.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiScan.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-25. */ + #include "WiFi.h" #include "WiFiPriv.h" diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiServer.cpp b/arduino/realtek-ambz/libraries/WiFi/WiFiServer.cpp index 3232a64c5..8275d280b 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiServer.cpp +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiServer.cpp @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-26. */ + #include "WiFiServer.h" #include "WiFiPriv.h" diff --git a/arduino/realtek-ambz/libraries/WiFi/WiFiServer.h b/arduino/realtek-ambz/libraries/WiFi/WiFiServer.h index 8692a9e3a..293f09064 100644 --- a/arduino/realtek-ambz/libraries/WiFi/WiFiServer.h +++ b/arduino/realtek-ambz/libraries/WiFi/WiFiServer.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-26. */ + #pragma once #include diff --git a/boards/wr3/pins_arduino.h b/boards/wr3/pins_arduino.h index 1ca5600e7..1de3ade2e 100644 --- a/boards/wr3/pins_arduino.h +++ b/boards/wr3/pins_arduino.h @@ -1,20 +1 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - -// API compatibility #include "variant.h" diff --git a/boards/wr3/variant.cpp b/boards/wr3/variant.cpp index 4a9558a37..f60d62ce9 100644 --- a/boards/wr3/variant.cpp +++ b/boards/wr3/variant.cpp @@ -1,33 +1,13 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. +/* Copyright (c) Kuba Szczodrzyński 2022-04-22. */ - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include "Arduino.h" #include "variant.h" -#include "gpio_api.h" -#ifdef __cplusplus extern "C" { -#endif - -#include "PinNames.h" /* * Pins descriptions */ +// clang-format off PinDescription g_APinDescription[PINS_COUNT] = { // D0: UART0_RTS, SPI1_MISO, SPI0_MISO, I2C0_SCL, SD_D0, PWM5, I2S_WS, WAKEUP_2 {PA_22, NOT_INITIAL, PIO_GPIO | PIO_GPIO_IRQ | PIO_PWM, NOT_INITIAL}, @@ -48,31 +28,15 @@ PinDescription g_APinDescription[PINS_COUNT] = { // D8: SDIO_SIDEBAND_INT, PWM4, WAKEUP_1 {PA_5, NOT_INITIAL, PIO_GPIO | PIO_GPIO_IRQ | PIO_PWM, NOT_INITIAL}, // D9: PWM3 - {PA_12, NOT_INITIAL, PIO_GPIO | PIO_GPIO_IRQ | PIO_PWM, NOT_INITIAL}, + {PA_12, NOT_INITIAL, PIO_GPIO | PIO_GPIO_IRQ | PIO_PWM, NOT_INITIAL}, // D10: UART0_RXD, SPI1_CLK, SPI0_SCK, I2C1_SCL, SD_D2, TIMER4_TRIG, I2S_MCK, WAKEUP_0 {PA_18, NOT_INITIAL, PIO_GPIO | PIO_GPIO_IRQ, NOT_INITIAL}, // D11: UART0_TXD, SPI1_MOSI, SPI0_MOSI, I2C1_SDA, SD_D1, PWM0, WAKEUP_3 - {PA_23, NOT_INITIAL, PIO_GPIO | PIO_GPIO_IRQ | PIO_PWM, NOT_INITIAL}, + {PA_23, NOT_INITIAL, PIO_GPIO | PIO_GPIO_IRQ | PIO_PWM, NOT_INITIAL}, }; +// clang-format on -void *gpio_pin_struct[PINS_COUNT] = {NULL}; +void *gpio_pin_struct[PINS_COUNT] = {NULL}; void *gpio_irq_handler_list[PINS_COUNT] = {NULL}; -#ifdef __cplusplus } // extern C -#endif - -void serialEvent() __attribute__((weak)); -bool Serial_available() __attribute__((weak)); - -void serialEventRun(void) { - if (Serial_available && serialEvent && Serial_available()) - serialEvent(); -} - -void wait_for_debug() { - while (((CoreDebug->DHCSR) & CoreDebug_DHCSR_C_DEBUGEN_Msk) == 0) { - asm("nop"); - } - delay(1000); -} diff --git a/boards/wr3/variant.h b/boards/wr3/variant.h index 1bb360633..2a0c95bb4 100644 --- a/boards/wr3/variant.h +++ b/boards/wr3/variant.h @@ -1,20 +1,4 @@ -/* - Copyright (c) 2011 Arduino. All right reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ +/* Copyright (c) Kuba Szczodrzyński 2022-04-23. */ #pragma once @@ -24,10 +8,10 @@ // ---- // Number of pins defined in PinDescription array -#define PINS_COUNT (12u) -#define NUM_DIGITAL_PINS (12u) -#define NUM_ANALOG_INPUTS (2u) -#define NUM_ANALOG_OUTPUTS (0u) +#define PINS_COUNT (12u) +#define NUM_DIGITAL_PINS (12u) +#define NUM_ANALOG_INPUTS (2u) +#define NUM_ANALOG_OUTPUTS (0u) // Low-level pin register query macros // ----------------------------------- @@ -37,18 +21,18 @@ // LEDs // ---- -#define PIN_LED (4u) +#define PIN_LED (4u) #define LED_BUILTIN PIN_LED // Analog pins // ----------- -#define PIN_A0 (1u) // PA_19 -#define PIN_A1 (0u) // dummy, this is NOT usable -#define PIN_A2 (5u) // PA_20 +#define PIN_A0 (1u) // PA_19 +#define PIN_A1 (0u) // dummy, this is NOT usable +#define PIN_A2 (5u) // PA_20 -static const uint8_t A0 = PIN_A0; -static const uint8_t A1 = PIN_A1; -static const uint8_t A2 = PIN_A2; +static const uint8_t A0 = PIN_A0; +static const uint8_t A1 = PIN_A1; +static const uint8_t A2 = PIN_A2; // SPI Interfaces // -------------- @@ -64,30 +48,14 @@ static const uint8_t A2 = PIN_A2; #include "LOGUARTClass.h" extern LOGUARTClass Serial; // LOGUARTClass -#define PIN_SERIAL2_RX PA_29 -#define PIN_SERIAL2_TX PA_30 +#define PIN_SERIAL2_RX PA_29 +#define PIN_SERIAL2_TX PA_30 // UARTClassOne -#define PIN_SERIAL0_RX PA_18 -#define PIN_SERIAL0_TX PA_23 +#define PIN_SERIAL0_RX PA_18 +#define PIN_SERIAL0_TX PA_23 #endif // __cplusplus -#define SERIAL_PORT_USBVIRTUAL Serial -#define SERIAL_PORT_MONITOR Serial -#define SERIAL_PORT_HARDWARE Serial -#define SERIAL_PORT_HARDWARE_OPEN Serial - -// Misc -// ---- -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus -/* - * Wait until enter debug mode - * - * Check DHCSR(0xE000EDF0) register and hold until bit C_DEBUGEN is set. - * Use this function along with J-LINK or other debug tool - **/ -extern void wait_for_debug(); -#ifdef __cplusplus -} -#endif +#define SERIAL_PORT_USBVIRTUAL Serial +#define SERIAL_PORT_MONITOR Serial +#define SERIAL_PORT_HARDWARE Serial +#define SERIAL_PORT_HARDWARE_OPEN Serial diff --git a/builder/arduino-common.py b/builder/arduino-common.py index 4ef1f99bb..3085b2501 100644 --- a/builder/arduino-common.py +++ b/builder/arduino-common.py @@ -36,6 +36,7 @@ base_dir=LT_API_DIR, srcs=[ "+", + "+", "+", ], includes=[ diff --git a/builder/frameworks/realtek-ambz-arduino.py b/builder/frameworks/realtek-ambz-arduino.py index 2afdb8ade..190137cba 100644 --- a/builder/frameworks/realtek-ambz-arduino.py +++ b/builder/frameworks/realtek-ambz-arduino.py @@ -70,38 +70,12 @@ base_dir="$ARDUINO_DIR", srcs=[ # Wiring core - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", - "+", + "+", + "+", ], includes=[ # prepend these as the Arduino core is incorrectly picking some includes from SDK "!", - "!", - "!", # includes that are missing in the vanilla SDK makefiles "+<$SDK_DIR/component/common/drivers/sdio/realtek/sdio_host/inc>", "+<$SDK_DIR/component/common/file_system/fatfs>", diff --git a/platform/realtek-ambz/fixups/.clang-format b/platform/realtek-ambz/fixups/.clang-format new file mode 100644 index 000000000..47a38a93f --- /dev/null +++ b/platform/realtek-ambz/fixups/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: Never diff --git a/platform/realtek-ambz/fixups/WCharacterFixup.h b/platform/realtek-ambz/fixups/WCharacterFixup.h index 8d74b3902..e1333d4b8 100644 --- a/platform/realtek-ambz/fixups/WCharacterFixup.h +++ b/platform/realtek-ambz/fixups/WCharacterFixup.h @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-23. */ + /* WCharacter.h uses deprecated isascii() and toascii(), which are available in gnu++11 but not c++11 */ #include diff --git a/platform/realtek-ambz/fixups/cmsis_ipsr.c b/platform/realtek-ambz/fixups/cmsis_ipsr.c index a464e50f3..ca47a89c9 100644 --- a/platform/realtek-ambz/fixups/cmsis_ipsr.c +++ b/platform/realtek-ambz/fixups/cmsis_ipsr.c @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-22. */ + #include // for some reason, cmsis_os.c does not link properly when this method is inlined in core_cmFunc.h diff --git a/platform/realtek-ambz/fixups/log_uart.c b/platform/realtek-ambz/fixups/log_uart.c index 1bdf5bd69..ce85bc69f 100644 --- a/platform/realtek-ambz/fixups/log_uart.c +++ b/platform/realtek-ambz/fixups/log_uart.c @@ -1,5 +1,7 @@ -#include "ameba_soc.h" -#include "osdep_service.h" +/* Copyright (c) Kuba Szczodrzyński 2022-04-22. */ + +#include +#include // usage: // extern int LOGUART_SetBaud(uint32_t BaudRate); diff --git a/platform/realtek-ambz/fixups/wifi_mode.c b/platform/realtek-ambz/fixups/wifi_mode.c index 5427457fc..4d5dd1bb1 100644 --- a/platform/realtek-ambz/fixups/wifi_mode.c +++ b/platform/realtek-ambz/fixups/wifi_mode.c @@ -1,3 +1,5 @@ +/* Copyright (c) Kuba Szczodrzyński 2022-04-22. */ + #include // wifi_mode is declared in atcmd_wifi.c, which is a part of the built-in trash console