Skip to content

Commit 5449407

Browse files
kkasperczyk-nopull[bot]
authored andcommitted
[nrfconnect] Fixed DFU over SMP by external flash handling refactor (#18796)
* [nrfconnect] Fixed DFU over SMP by external flash handling refactor Currently DFU over SMP doesn't work properly due to problems with external flash interaction that is put asleep by the OTA Matter module. * Added using BLE connect/disconnect callbacks to control the QSPI NOR power mode. * Refactored ExternalFlashHandler to be generic FlashHandler that can be also implemented by other backends than NOR QSPI * Fixed missing includes.
1 parent de30366 commit 5449407

File tree

6 files changed

+74
-55
lines changed

6 files changed

+74
-55
lines changed

examples/platform/nrfconnect/util/DFUOverSMP.cpp

+20-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
#include <lib/support/logging/CHIPLogging.h>
3232

33+
#include "OTAUtil.h"
34+
3335
using namespace ::chip::DeviceLayer;
3436

3537
constexpr uint16_t kAdvertisingIntervalMinMs = 400;
@@ -44,10 +46,14 @@ void DFUOverSMP::Init(DFUOverSMPRestartAdvertisingHandler startAdvertisingCb)
4446
img_mgmt_set_upload_cb(UploadConfirmHandler, NULL);
4547

4648
memset(&mBleConnCallbacks, 0, sizeof(mBleConnCallbacks));
49+
mBleConnCallbacks.connected = OnBleConnect;
4750
mBleConnCallbacks.disconnected = OnBleDisconnect;
4851

4952
bt_conn_cb_register(&mBleConnCallbacks);
5053

54+
k_work_init(&mFlashSleepWork, [](k_work *) { GetFlashHandler().DoAction(FlashHandler::Action::SLEEP); });
55+
k_work_init(&mFlashWakeUpWork, [](k_work *) { GetFlashHandler().DoAction(FlashHandler::Action::WAKE_UP); });
56+
5157
restartAdvertisingCallback = startAdvertisingCb;
5258

5359
PlatformMgr().AddEventHandler(ChipEventHandler, 0);
@@ -130,8 +136,21 @@ void DFUOverSMP::StartBLEAdvertising()
130136
}
131137
}
132138

139+
void DFUOverSMP::OnBleConnect(bt_conn * conn, uint8_t err)
140+
{
141+
if (GetDFUOverSMP().IsEnabled())
142+
{
143+
(void) k_work_submit(&sDFUOverSMP.mFlashWakeUpWork);
144+
}
145+
}
146+
133147
void DFUOverSMP::OnBleDisconnect(struct bt_conn * conId, uint8_t reason)
134148
{
149+
if (GetDFUOverSMP().IsEnabled())
150+
{
151+
(void) k_work_submit(&sDFUOverSMP.mFlashSleepWork);
152+
}
153+
135154
PlatformMgr().LockChipStack();
136155

137156
// After BLE disconnect SMP advertising needs to be restarted. Before making it ensure that BLE disconnect was not triggered
@@ -159,7 +178,7 @@ void DFUOverSMP::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* arg
159178
sDFUOverSMP.restartAdvertisingCallback();
160179
}
161180
break;
162-
case DeviceEventType::kCommissioningComplete:
181+
case DeviceEventType::kCHIPoBLEConnectionClosed:
163182
// Check if after closing CHIPoBLE connection advertising is working, if no start SMP advertising.
164183
if (!ConnectivityMgr().IsBLEAdvertisingEnabled())
165184
{

examples/platform/nrfconnect/util/OTAUtil.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,19 @@ DefaultOTARequestorStorage sOTARequestorStorage;
3131
DefaultOTARequestorDriver sOTARequestorDriver;
3232
chip::BDXDownloader sBDXDownloader;
3333
chip::DefaultOTARequestor sOTARequestor;
34-
3534
} // namespace
3635

36+
FlashHandler & GetFlashHandler()
37+
{
38+
static FlashHandler sFlashHandler;
39+
return sFlashHandler;
40+
}
41+
3742
// compile-time factory method
3843
OTAImageProcessorImpl & GetOTAImageProcessor()
3944
{
4045
#if CONFIG_PM_DEVICE && CONFIG_NORDIC_QSPI_NOR
41-
static ExtFlashHandler sQSPIHandler;
42-
static OTAImageProcessorImplPMDevice sOTAImageProcessor{ sQSPIHandler };
46+
static OTAImageProcessorImpl sOTAImageProcessor(&GetFlashHandler());
4347
#else
4448
static OTAImageProcessorImpl sOTAImageProcessor;
4549
#endif
@@ -55,4 +59,5 @@ void InitBasicOTARequestor()
5559
sOTARequestor.Init(Server::GetInstance(), sOTARequestorStorage, sOTARequestorDriver, sBDXDownloader);
5660
chip::SetRequestorInstance(&sOTARequestor);
5761
sOTARequestorDriver.Init(&sOTARequestor, &imageProcessor);
62+
imageProcessor.TriggerFlashAction(FlashHandler::Action::SLEEP);
5863
}

examples/platform/nrfconnect/util/include/DFUOverSMP.h

+3
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,15 @@ class DFUOverSMP
4242
friend DFUOverSMP & GetDFUOverSMP(void);
4343

4444
static int UploadConfirmHandler(uint32_t offset, uint32_t size, void * arg);
45+
static void OnBleConnect(bt_conn * conn, uint8_t err);
4546
static void OnBleDisconnect(bt_conn * conn, uint8_t reason);
4647
static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg);
4748

4849
bool mIsEnabled;
4950
bool mIsAdvertisingEnabled;
5051
bt_conn_cb mBleConnCallbacks;
52+
k_work mFlashSleepWork;
53+
k_work mFlashWakeUpWork;
5154
DFUOverSMPRestartAdvertisingHandler restartAdvertisingCallback;
5255

5356
static DFUOverSMP sDFUOverSMP;

examples/platform/nrfconnect/util/include/OTAUtil.h

+10
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,22 @@
1717

1818
#pragma once
1919

20+
#include <platform/nrfconnect/OTAImageProcessorImpl.h>
21+
2022
namespace chip {
2123
namespace DeviceLayer {
2224
class OTAImageProcessorImpl;
2325
} // namespace DeviceLayer
2426
} // namespace chip
2527

28+
/**
29+
* Get FlashHandler static instance.
30+
*
31+
* Returned object can be used to control the QSPI external flash,
32+
* which can be introduced into sleep mode and woken up on demand.
33+
*/
34+
chip::DeviceLayer::FlashHandler & GetFlashHandler();
35+
2636
/**
2737
* Select recommended OTA image processor implementation.
2838
*

src/platform/nrfconnect/OTAImageProcessorImpl.cpp

+17-27
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ CHIP_ERROR OTAImageProcessorImpl::PrepareDownload()
3737
{
3838
VerifyOrReturnError(mDownloader != nullptr, CHIP_ERROR_INCORRECT_STATE);
3939

40+
TriggerFlashAction(FlashHandler::Action::WAKE_UP);
41+
4042
return DeviceLayer::SystemLayer().ScheduleLambda([this] { mDownloader->OnPreparedForDownload(PrepareDownloadImpl()); });
4143
}
4244

@@ -56,7 +58,10 @@ CHIP_ERROR OTAImageProcessorImpl::Finalize()
5658

5759
CHIP_ERROR OTAImageProcessorImpl::Abort()
5860
{
59-
return System::MapErrorZephyr(dfu_target_reset());
61+
CHIP_ERROR error = System::MapErrorZephyr(dfu_target_reset());
62+
63+
TriggerFlashAction(FlashHandler::Action::SLEEP);
64+
return error;
6065
}
6166

6267
CHIP_ERROR OTAImageProcessorImpl::Apply()
@@ -68,6 +73,8 @@ CHIP_ERROR OTAImageProcessorImpl::Apply()
6873
err = dfu_target_schedule_update(-1);
6974
}
7075

76+
TriggerFlashAction(FlashHandler::Action::SLEEP);
77+
7178
#ifdef CONFIG_CHIP_OTA_REQUESTOR_REBOOT_ON_APPLY
7279
if (!err)
7380
{
@@ -214,8 +221,16 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & aBlock)
214221
return CHIP_NO_ERROR;
215222
}
216223

224+
void OTAImageProcessorImpl::TriggerFlashAction(FlashHandler::Action action)
225+
{
226+
if (mFlashHandler)
227+
{
228+
mFlashHandler->DoAction(action);
229+
}
230+
}
231+
217232
// external flash power consumption optimization
218-
void ExtFlashHandler::DoAction(Action aAction)
233+
void FlashHandler::DoAction(Action aAction)
219234
{
220235
#if CONFIG_PM_DEVICE && CONFIG_NORDIC_QSPI_NOR && !CONFIG_SOC_NRF52840 // nRF52 is optimized per default
221236
// utilize the QSPI driver sleep power mode
@@ -228,30 +243,5 @@ void ExtFlashHandler::DoAction(Action aAction)
228243
#endif
229244
}
230245

231-
OTAImageProcessorImplPMDevice::OTAImageProcessorImplPMDevice(ExtFlashHandler & aHandler) : mHandler(aHandler)
232-
{
233-
mHandler.DoAction(ExtFlashHandler::Action::SLEEP);
234-
}
235-
236-
CHIP_ERROR OTAImageProcessorImplPMDevice::PrepareDownload()
237-
{
238-
mHandler.DoAction(ExtFlashHandler::Action::WAKE_UP);
239-
return OTAImageProcessorImpl::PrepareDownload();
240-
}
241-
242-
CHIP_ERROR OTAImageProcessorImplPMDevice::Abort()
243-
{
244-
auto status = OTAImageProcessorImpl::Abort();
245-
mHandler.DoAction(ExtFlashHandler::Action::SLEEP);
246-
return status;
247-
}
248-
249-
CHIP_ERROR OTAImageProcessorImplPMDevice::Apply()
250-
{
251-
auto status = OTAImageProcessorImpl::Apply();
252-
mHandler.DoAction(ExtFlashHandler::Action::SLEEP);
253-
return status;
254-
}
255-
256246
} // namespace DeviceLayer
257247
} // namespace chip

src/platform/nrfconnect/OTAImageProcessorImpl.h

+16-24
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,25 @@ class OTADownloader;
2727

2828
namespace DeviceLayer {
2929

30+
class FlashHandler
31+
{
32+
public:
33+
enum class Action : uint8_t
34+
{
35+
WAKE_UP,
36+
SLEEP
37+
};
38+
virtual ~FlashHandler() {}
39+
virtual void DoAction(Action aAction);
40+
};
41+
3042
class OTAImageProcessorImpl : public OTAImageProcessorInterface
3143
{
3244
public:
3345
static constexpr size_t kBufferSize = CONFIG_CHIP_OTA_REQUESTOR_BUFFER_SIZE;
3446

47+
OTAImageProcessorImpl(FlashHandler * flashHandler = nullptr) : mFlashHandler(flashHandler){};
48+
3549
enum class ImageType : uint8_t
3650
{
3751
kAppImage = 0,
@@ -54,6 +68,7 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
5468
CHIP_ERROR ProcessBlock(ByteSpan & aBlock) override;
5569
bool IsFirstImageRun() override;
5670
CHIP_ERROR ConfirmCurrentImage() override;
71+
void TriggerFlashAction(FlashHandler::Action action);
5772

5873
private:
5974
CHIP_ERROR PrepareDownloadImpl();
@@ -66,30 +81,7 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
6681
uint8_t mBuffer[kBufferSize];
6782
OTAImageContentHeader mContentHeader;
6883
OTAImage mCurrentImage;
69-
};
70-
71-
class ExtFlashHandler
72-
{
73-
public:
74-
enum class Action : uint8_t
75-
{
76-
WAKE_UP,
77-
SLEEP
78-
};
79-
virtual ~ExtFlashHandler() {}
80-
virtual void DoAction(Action aAction);
81-
};
82-
83-
class OTAImageProcessorImplPMDevice : public OTAImageProcessorImpl
84-
{
85-
public:
86-
explicit OTAImageProcessorImplPMDevice(ExtFlashHandler & aHandler);
87-
CHIP_ERROR PrepareDownload() override;
88-
CHIP_ERROR Abort() override;
89-
CHIP_ERROR Apply() override;
90-
91-
private:
92-
ExtFlashHandler & mHandler;
84+
FlashHandler * mFlashHandler;
9385
};
9486

9587
} // namespace DeviceLayer

0 commit comments

Comments
 (0)