Skip to content

Commit 8ea8983

Browse files
authored
Merge branch 'main' into add-wifi-st-b-l4
2 parents 44746e9 + e9ba810 commit 8ea8983

53 files changed

Lines changed: 2132 additions & 799 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CMake/Modules/FindESP32_IDF.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ list(APPEND ESP32_IDF_INCLUDE_DIRS ${IDF_PATH_CMAKED}/components/esp_driver_dac/
3333
list(APPEND ESP32_IDF_INCLUDE_DIRS ${IDF_PATH_CMAKED}/components/esp_driver_ledc/include)
3434
list(APPEND ESP32_IDF_INCLUDE_DIRS ${IDF_PATH_CMAKED}/components/esp_driver_pcnt/include)
3535
list(APPEND ESP32_IDF_INCLUDE_DIRS ${IDF_PATH_CMAKED}/components/esp_driver_sdmmc/include)
36+
list(APPEND ESP32_IDF_INCLUDE_DIRS ${IDF_PATH_CMAKED}/components/esp_driver_rmt/include)
3637
list(APPEND ESP32_IDF_INCLUDE_DIRS ${IDF_PATH_CMAKED}/components/esp_driver_sdspi/include)
3738

38-
# Use depecated drivers for RMT, I2S etc
39+
# Use depecated drivers for I2S etc
3940
list(APPEND ESP32_IDF_INCLUDE_DIRS ${IDF_PATH_CMAKED}/components/driver/deprecated)
4041

4142
# includes specific to ESP32 or ESP32S2 or ESP32S3

CMake/Modules/FindnanoFramework.Hardware.Esp32.Rmt.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ set(nanoFramework.Hardware.Esp32.Rmt_SRCS
2222
nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_RmtChannel.cpp
2323
nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitterChannel.cpp
2424
nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_ReceiverChannel.cpp
25+
nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_TransmitSyncManager.cpp
26+
rmt_multi_stage_encoder.cpp
27+
nanoFramework_hardware_esp32_rmt_native_nanoFramework_Hardware_Esp32_Rmt_Utils.cpp
2528
)
2629

2730
foreach(SRC_FILE ${nanoFramework.Hardware.Esp32.Rmt_SRCS})

src/CLR/Core/Execution.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,9 +638,7 @@ HRESULT CLR_RT_ExecutionEngine::Execute(wchar_t *entryPointArgs, int maxContextS
638638

639639
NANOCLR_CHECK_HRESULT(WaitForDebugger());
640640

641-
#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)
642641
CLR_EE_DBG_SET_MASK(StateProgramRunning, StateMask);
643-
#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)
644642

645643
NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Delegate::CreateInstance(ref, g_CLR_RT_TypeSystem.m_entryPoint, NULL));
646644

src/CLR/Core/GarbageCollector.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,38 @@ void CLR_RT_ProtectFromGC::Initialize(void **data, Callback fpn)
4141
m_flags = c_Generic;
4242
}
4343

44+
void CLR_RT_ProtectFromGC::UnlinkOutOfOrder()
45+
{
46+
NATIVE_PROFILE_CLR_CORE();
47+
48+
for (CLR_RT_ProtectFromGC **slot = &s_first; *slot != NULL; slot = &(*slot)->m_next)
49+
{
50+
if (*slot == this)
51+
{
52+
*slot = m_next;
53+
break;
54+
}
55+
}
56+
}
57+
4458
void CLR_RT_ProtectFromGC::Cleanup()
4559
{
4660
NATIVE_PROFILE_CLR_CORE();
47-
s_first = m_next;
61+
62+
if (s_first == this)
63+
{
64+
// LIFO fast path: instances are stack scoped and nest, so this is a pop.
65+
s_first = m_next;
66+
}
67+
else
68+
{
69+
// Destroyed out of order. Popping here would drop every outer registration and let the GC
70+
// collect objects that are still live, so recover in all builds -- but this is a bug, not a
71+
// supported case: it means an instance escaped its scope.
72+
_ASSERTE(false);
73+
74+
UnlinkOutOfOrder();
75+
}
4876

4977
if (m_flags & c_ResetKeepAlive)
5078
{

src/CLR/Core/Hardware/Hardware.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ void CLR_HW_Hardware::ProcessActivity()
163163
eventsCLR |= Event_I2cSlave;
164164
}
165165

166+
if (events & SYSTEM_EVENT_FLAG_RMT_RX)
167+
{
168+
eventsCLR |= Event_RmtRx;
169+
}
170+
166171
if (events & SYSTEM_EVENT_FLAG_ONEWIRE_MASTER)
167172
{
168173
eventsCLR |= Event_OneWireHost;

src/CLR/Core/TypeSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2881,7 +2881,7 @@ static const TypeIndexLookup c_TypeIndexLookup[] = {
28812881

28822882
TIL("System.Device.I2c", "I2cTransferResult", m_I2cTransferResult),
28832883

2884-
TIL("nanoFramework.Hardware.Esp32.Rmt", "RmtCommand", m_RmtCommand),
2884+
TIL("nanoFramework.Hardware.Esp32.Rmt", "RmtSymbol", m_RmtSymbol),
28852885

28862886
#undef TIL
28872887
};

src/CLR/Include/nanoCLR_Hardware.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ struct CLR_HW_Hardware
2626
SYSTEM_EVENT_FLAG_SPI_MASTER | SYSTEM_EVENT_FLAG_I2C_MASTER | SYSTEM_EVENT_FLAG_I2C_SLAVE |
2727
SYSTEM_EVENT_HW_INTERRUPT | SYSTEM_EVENT_FLAG_SOCKET | SYSTEM_EVENT_FLAG_DEBUGGER_ACTIVITY |
2828
SYSTEM_EVENT_FLAG_MESSAGING_ACTIVITY | SYSTEM_EVENT_FLAG_ONEWIRE_MASTER | SYSTEM_EVENT_FLAG_RADIO |
29-
SYSTEM_EVENT_FLAG_WIFI_STATION | SYSTEM_EVENT_FLAG_BLUETOOTH;
30-
29+
SYSTEM_EVENT_FLAG_WIFI_STATION | SYSTEM_EVENT_FLAG_BLUETOOTH | SYSTEM_EVENT_FLAG_RMT_RX;
3130
//--//
3231

3332
struct HalInterruptRecord

src/CLR/Include/nanoCLR_PlatformDef.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,16 @@
201201
#define ULONGLONGCONSTANT(v) (v##ull)
202202
#endif
203203

204+
// Keeps a function out of line even under LTO. Use it for cold error/recovery paths that would
205+
// otherwise be inlined into every one of their call sites and bloat the image.
206+
#if defined(__GNUC__)
207+
#define NANOCLR_NOINLINE __attribute__((noinline))
208+
#elif defined(_MSC_VER)
209+
#define NANOCLR_NOINLINE __declspec(noinline)
210+
#else
211+
#define NANOCLR_NOINLINE
212+
#endif
213+
204214
////////////////////////////////////////////////////////////////////////////////////////////////////
205215
////////////////////////////////////////////////////////////////////////////////////////////////////
206216
////////////////////////////////////////////////////////////////////////////////////////////////////

src/CLR/Include/nanoCLR_Runtime.h

Lines changed: 90 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
////////////////////////////////////////////////////////////////////////////////////////////////////
1010

11+
#include <type_traits>
1112
#include <nanoCLR_Types.h>
1213
#include <nanoCLR_Interop.h>
1314
#include <nanoCLR_ErrorCodes.h>
@@ -515,6 +516,15 @@ struct CLR_RT_Memory
515516
memset(buf, 0, len);
516517
}
517518

519+
template <typename T> static void Clear(T &ref)
520+
{
521+
// A type with a non-trivial destructor owns something that has to be released
522+
// for example, an entry in the CLR_RT_ProtectFromGC chain on which zero-filling it silently orphans that.
523+
static_assert(std::is_trivially_destructible<T>::value, "NANOCLR_CLEAR on a type that owns resources");
524+
525+
ZeroFill(&ref, sizeof(T));
526+
}
527+
518528
//--//
519529

520530
static void Reset();
@@ -551,7 +561,7 @@ extern void CLR_RT_GetVersion(
551561
unsigned short int *pBuild,
552562
unsigned short int *pRevision);
553563

554-
#define NANOCLR_CLEAR(ref) CLR_RT_Memory::ZeroFill(&ref, sizeof(ref))
564+
#define NANOCLR_CLEAR(ref) CLR_RT_Memory::Clear(ref)
555565

556566
//--//
557567

@@ -1581,7 +1591,7 @@ struct CLR_RT_WellKnownTypes
15811591
CLR_RT_TypeDef_Index m_I2cTransferResult;
15821592
CLR_RT_TypeDef_Index m_I2cTransferResult_old;
15831593

1584-
CLR_RT_TypeDef_Index m_RmtCommand;
1594+
CLR_RT_TypeDef_Index m_RmtSymbol;
15851595

15861596
PROHIBIT_COPY_CONSTRUCTORS(CLR_RT_WellKnownTypes);
15871597
};
@@ -1968,6 +1978,50 @@ struct CLR_RT_MethodDef_Instance : public CLR_RT_MethodDef_Index
19681978
#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)
19691979
};
19701980

1981+
////////////////////////////////////////////////////////////////////////////////
1982+
1983+
struct CLR_RT_ProtectFromGC
1984+
{
1985+
static const CLR_UINT32 c_Generic = 0x00000001;
1986+
static const CLR_UINT32 c_HeapBlock = 0x00000002;
1987+
static const CLR_UINT32 c_ResetKeepAlive = 0x00000004;
1988+
1989+
typedef void (*Callback)(void *state);
1990+
1991+
static CLR_RT_ProtectFromGC *s_first;
1992+
1993+
CLR_RT_ProtectFromGC *m_next;
1994+
void **m_data;
1995+
Callback m_fpn;
1996+
CLR_UINT32 m_flags;
1997+
1998+
CLR_RT_ProtectFromGC(CLR_RT_HeapBlock &ref)
1999+
{
2000+
Initialize(ref);
2001+
}
2002+
CLR_RT_ProtectFromGC(void **data, Callback fpn)
2003+
{
2004+
Initialize(data, fpn);
2005+
}
2006+
~CLR_RT_ProtectFromGC()
2007+
{
2008+
Cleanup();
2009+
}
2010+
2011+
static void InvokeAll();
2012+
2013+
private:
2014+
void Initialize(CLR_RT_HeapBlock &ref);
2015+
void Initialize(void **data, Callback fpn);
2016+
void Cleanup();
2017+
2018+
// Cold recovery path for Cleanup(), kept out of line so that it isn't inlined into every
2019+
// destruction site.
2020+
NANOCLR_NOINLINE void UnlinkOutOfOrder();
2021+
2022+
void Invoke();
2023+
};
2024+
19712025
////////////////////////////////////////////////////////////////////////////////////////////////////
19722026

19732027
struct CLR_RT_AttributeEnumerator
@@ -1994,6 +2048,9 @@ struct CLR_RT_AttributeEnumerator
19942048
void Initialize(CLR_RT_Assembly *assm);
19952049
};
19962050

2051+
// Developer note: Value::m_valueGC holds a live entry in the CLR_RT_ProtectFromGC chain for this object whole lifetime.
2052+
// Never memset/memcpy an instance (NANOCLR_CLEAR included) and never give one a lifetime that doesn't nest with the
2053+
// enclosing scope.
19972054
struct CLR_RT_AttributeParser
19982055
{
19992056
struct Value
@@ -2004,10 +2061,34 @@ struct CLR_RT_AttributeParser
20042061
static const int c_DefaultConstructor = 4;
20052062

20062063
int m_mode;
2007-
CLR_RT_HeapBlock m_value;
2064+
// Declaration order below is load-bearing: CLR_RT_ProtectFromGC's constructor reads
2065+
// m_value.IsForcedAlive(), so m_value has to be declared -- and zeroed -- before m_valueGC.
2066+
CLR_RT_HeapBlock m_value{};
2067+
CLR_RT_ProtectFromGC m_valueGC{m_value};
20082068

20092069
int m_pos;
20102070
const char *m_name;
2071+
2072+
//--//
2073+
2074+
// Required, not decorative: declaring the deleted copy constructor below suppresses the
2075+
// implicit default constructor. It also has to stay defaulted *here*, in the class body --
2076+
// an out of line "= default" would make it user provided, which drops the zero
2077+
// initialization that m_valueGC's constructor depends on.
2078+
Value() = default;
2079+
2080+
// Prevent copying because shallow copies of CLR_RT_ProtectFromGC
2081+
// can corrupt the GC protection list during destruction.
2082+
2083+
// Delete copy constructor
2084+
Value(const Value &) = delete;
2085+
// Delete copy-assignment operator
2086+
Value &operator=(const Value &) = delete;
2087+
2088+
// Stack only: the CLR_RT_ProtectFromGC entry is released by popping the chain, not by
2089+
// searching it, so this object's lifetime has to nest with the enclosing scope.
2090+
static void *operator new(size_t) = delete;
2091+
static void *operator new[](size_t) = delete;
20112092
};
20122093

20132094
//--//
@@ -2040,6 +2121,11 @@ struct CLR_RT_AttributeParser
20402121
const CLR_UINT32 size);
20412122
HRESULT ReadString(CLR_RT_HeapBlock *&value);
20422123

2124+
// Stack only, for the same reason as CLR_RT_AttributeParser::Value above: this owns the
2125+
// registration through m_lastValue.
2126+
static void *operator new(size_t) = delete;
2127+
static void *operator new[](size_t) = delete;
2128+
20432129
private:
20442130
const char *GetString();
20452131
};
@@ -2509,46 +2595,6 @@ CT_ASSERT(
25092595

25102596
#endif // _MSC_VER
25112597

2512-
////////////////////////////////////////////////////////////////////////////////
2513-
2514-
struct CLR_RT_ProtectFromGC
2515-
{
2516-
static const CLR_UINT32 c_Generic = 0x00000001;
2517-
static const CLR_UINT32 c_HeapBlock = 0x00000002;
2518-
static const CLR_UINT32 c_ResetKeepAlive = 0x00000004;
2519-
2520-
typedef void (*Callback)(void *state);
2521-
2522-
static CLR_RT_ProtectFromGC *s_first;
2523-
2524-
CLR_RT_ProtectFromGC *m_next;
2525-
void **m_data;
2526-
Callback m_fpn;
2527-
CLR_UINT32 m_flags;
2528-
2529-
CLR_RT_ProtectFromGC(CLR_RT_HeapBlock &ref)
2530-
{
2531-
Initialize(ref);
2532-
}
2533-
CLR_RT_ProtectFromGC(void **data, Callback fpn)
2534-
{
2535-
Initialize(data, fpn);
2536-
}
2537-
~CLR_RT_ProtectFromGC()
2538-
{
2539-
Cleanup();
2540-
}
2541-
2542-
static void InvokeAll();
2543-
2544-
private:
2545-
void Initialize(CLR_RT_HeapBlock &ref);
2546-
void Initialize(void **data, Callback fpn);
2547-
void Cleanup();
2548-
2549-
void Invoke();
2550-
};
2551-
25522598
////////////////////////////////////////
25532599

25542600
#if defined(NANOCLR_TRACE_EARLYCOLLECTION)
@@ -3452,6 +3498,7 @@ typedef enum Events
34523498
Event_UsbOut = 0x00004000,
34533499
Event_IO = 0x00008000,
34543500
Event_I2cSlave = 0x00010000,
3501+
Event_RmtRx = 0x00020000,
34553502
Event_AppDomain = 0x02000000,
34563503
Event_Socket = 0x20000000,
34573504
Event_IdleCPU = 0x40000000,

src/CLR/Startup/CLRStartup.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -425,8 +425,8 @@ void ClrStartup(CLR_SETTINGS params)
425425

426426
if (CLR_EE_DBG_IS_NOT(RebootPending))
427427
{
428-
#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)
429428
CLR_EE_DBG_SET_MASK(StateProgramExited, StateMask);
429+
#if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)
430430
CLR_EE_DBG_EVENT_BROADCAST(CLR_DBG_Commands_c_Monitor_ProgramExit, 0, NULL, WP_Flags_c_NonCritical);
431431
#endif // #if defined(NANOCLR_ENABLE_SOURCELEVELDEBUGGING)
432432

0 commit comments

Comments
 (0)