Skip to content

Commit 7ea9e4d

Browse files
WIP
1 parent 000f5fc commit 7ea9e4d

20 files changed

+238
-5
lines changed

include/openthread/platform/radio.h

+22
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,28 @@ uint64_t otPlatRadioGetNow(otInstance *aInstance);
737737
*/
738738
uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance);
739739

740+
/**
741+
* Get the bus latency in microseconds between the host and the radio chip.
742+
*
743+
* @param[in] aInstance A pointer to an OpenThread instance.
744+
*
745+
* @returns The bus latency in microseconds between the host and the radio chip.
746+
* Return 0 when the MAC and above layer and Radio layer resides on the same chip.
747+
*
748+
*/
749+
uint32_t otPlatRadioGetBusLatency(otInstance *aInstance);
750+
751+
/**
752+
* Set the bus latency in microseconds between the host and the radio chip.
753+
*
754+
* @note This function does not do anything when the MAC and above layer and Radio layer resides on the same chip.
755+
*
756+
* @param[in] aInstance A pointer to an OpenThread instance.
757+
* @param[in] aLatency Bus latency in microseconds.
758+
*
759+
*/
760+
void otPlatRadioSetBusLatency(otInstance *aInstance, uint32_t aLatency);
761+
740762
/**
741763
* @}
742764
*

include/openthread/thread.h

+15
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,21 @@ otError otThreadSendProactiveBackboneNotification(otInstance *aIns
11361136
*/
11371137
otError otThreadDetachGracefully(otInstance *aInstance, otDetachGracefullyCallback aCallback, void *aContext);
11381138

1139+
/**
1140+
* Notifies other nodes in the network (if any) and then stops Thread protocol operation.
1141+
*
1142+
* It sends an Address Release if it's a router, or sets its child timeout to 0 if it's a child.
1143+
*
1144+
* @param[in] aInstance A pointer to an OpenThread instance.
1145+
* @param[in] aCallback A pointer to a function that is called upon finishing detaching.
1146+
* @param[in] aContext A pointer to callback application-specific context.
1147+
*
1148+
* @retval OT_ERROR_NONE Successfully started detaching.
1149+
* @retval OT_ERROR_BUSY Detaching is already in progress.
1150+
*
1151+
*/
1152+
void otThreaUpdateCslTimeout(otInstance *aInstance);
1153+
11391154
#define OT_DURATION_STRING_SIZE 21 ///< Recommended size for string representation of `uint32_t` duration in seconds.
11401155

11411156
/**

src/cli/README.md

+19
Original file line numberDiff line numberDiff line change
@@ -3218,6 +3218,25 @@ OPENTHREAD/20191113-00825-g82053cc9d-dirty; SIMULATION; Jun 4 2020 17:53:16
32183218
Done
32193219
```
32203220
3221+
### rcp latency
3222+
3223+
Get the bus latency in microseconds between the host and the radio chip.
3224+
3225+
```bash
3226+
> rcp latency
3227+
0
3228+
Done
3229+
```
3230+
3231+
### rcp latency \<latency\>
3232+
3233+
Set the bus latency in microseconds between the host and the radio chip.
3234+
3235+
```bash
3236+
> rcp latency 1000
3237+
Done
3238+
```
3239+
32213240
### releaserouterid \<routerid\>
32223241
32233242
Release a Router ID that has been allocated by the device in the Leader role.

src/cli/cli.cpp

+24-1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
#include "common/new.hpp"
9393
#include "common/numeric_limits.hpp"
9494
#include "common/string.hpp"
95+
9596
#include "mac/channel_mask.hpp"
9697

9798
namespace ot {
@@ -5956,7 +5957,29 @@ template <> otError Interpreter::Process<Cmd("rcp")>(Arg aArgs[])
59565957
{
59575958
OutputLine("%s", version);
59585959
}
5959-
5960+
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
5961+
/**
5962+
* @cli rcp latency (get,set)
5963+
* @code
5964+
* rcp latency
5965+
* 0
5966+
* Done
5967+
* @endcode
5968+
* @code
5969+
* rcp latency 1000
5970+
* Done
5971+
* @endcode
5972+
* @cparam rcp latency [@ca{latency}]
5973+
* @par
5974+
* Gets or sets the bus latency in microseconds between the host and the radio chip.
5975+
* @sa otPlatRadioGetBusLatency
5976+
* @sa otPlatRadioSetBusLatency
5977+
*/
5978+
else if (aArgs[0] == "latency")
5979+
{
5980+
SuccessOrExit(error = ProcessGetSet(aArgs + 1, otPlatRadioGetBusLatency, otPlatRadioSetBusLatency));
5981+
}
5982+
#endif
59605983
else
59615984
{
59625985
error = OT_ERROR_INVALID_ARGS;

src/core/api/thread_api.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,15 @@ otError otThreadDetachGracefully(otInstance *aInstance, otDetachGracefullyCallba
512512

513513
#endif // OPENTHREAD_FTD || OPENTHREAD_MTD
514514

515+
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
516+
517+
void otThreaUpdateCslTimeout(otInstance *aInstance)
518+
{
519+
AsCoreType(aInstance).Get<CslTxScheduler>().UpdateFrameRequestAhead();
520+
// Get<AnycastLocator>().IsInProgress();
521+
}
522+
#endif
523+
515524
#if OPENTHREAD_CONFIG_UPTIME_ENABLE
516525
void otConvertDurationInSecondsToString(uint32_t aDuration, char *aBuffer, uint16_t aSize)
517526
{

src/core/radio/radio_platform.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,19 @@ OT_TOOL_WEAK uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance)
250250
return 0;
251251
}
252252

253+
OT_TOOL_WEAK uint32_t otPlatRadioGetBusLatency(otInstance *aInstance)
254+
{
255+
OT_UNUSED_VARIABLE(aInstance);
256+
257+
return 0;
258+
}
259+
260+
OT_TOOL_WEAK void otPlatRadioSetBusLatency(otInstance *aInstance, uint32_t aLatency)
261+
{
262+
OT_UNUSED_VARIABLE(aInstance);
263+
OT_UNUSED_VARIABLE(aLatency);
264+
}
265+
253266
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
254267
OT_TOOL_WEAK otError otPlatRadioResetCsl(otInstance *aInstance)
255268
{

src/core/thread/csl_tx_scheduler.cpp

+8-3
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232

3333
#include "common/locator_getters.hpp"
3434
#include "common/log.hpp"
35+
#include "common/num_utils.hpp"
3536
#include "common/time.hpp"
3637
#include "mac/mac.hpp"
3738

@@ -68,16 +69,20 @@ CslTxScheduler::CslTxScheduler(Instance &aInstance)
6869
, mFrameContext()
6970
, mCallbacks(aInstance)
7071
{
71-
InitFrameRequestAhead();
72+
UpdateFrameRequestAhead();
7273
}
7374

74-
void CslTxScheduler::InitFrameRequestAhead(void)
75+
void CslTxScheduler::UpdateFrameRequestAhead(void)
7576
{
7677
uint32_t busSpeedHz = otPlatRadioGetBusSpeed(&GetInstance());
78+
uint32_t busLatency = otPlatRadioGetBusLatency(&GetInstance());
79+
7780
// longest frame on bus is 127 bytes with some metadata, use 150 bytes for bus Tx time estimation
7881
uint32_t busTxTimeUs = ((busSpeedHz == 0) ? 0 : (150 * 8 * 1000000 + busSpeedHz - 1) / busSpeedHz);
7982

80-
mCslFrameRequestAheadUs = OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US + busTxTimeUs;
83+
mCslFrameRequestAheadUs = OPENTHREAD_CONFIG_MAC_CSL_REQUEST_AHEAD_US + busTxTimeUs + busLatency;
84+
LogInfo("Declared Bus TX Time: %lu, Latency: %lu. Calculated CSL Frame Request Ahead: %lu", ToUlong(busTxTimeUs),
85+
ToUlong(busLatency), ToUlong(mCslFrameRequestAheadUs));
8186
}
8287

8388
void CslTxScheduler::Update(void)

src/core/thread/csl_tx_scheduler.hpp

+6-1
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,16 @@ class CslTxScheduler : public InstanceLocator, private NonCopyable
231231
*/
232232
void Clear(void);
233233

234+
/**
235+
* Updates the value of `mCslFrameRequestAheadUs`.
236+
*
237+
*/
238+
void UpdateFrameRequestAhead(void);
239+
234240
private:
235241
// Guard time in usec to add when checking delay while preparing the CSL frame for tx.
236242
static constexpr uint32_t kFramePreparationGuardInterval = 1500;
237243

238-
void InitFrameRequestAhead(void);
239244
void RescheduleCslTx(void);
240245

241246
uint32_t GetNextCslTransmissionDelay(const Child &aChild, uint32_t &aDelayFromLastRx, uint32_t aAheadUs) const;

src/lib/spinel/radio_spinel.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1906,6 +1906,10 @@ uint64_t RadioSpinel::GetNow(void) { return (mIsTimeSynced) ? (otPlatTimeGet() +
19061906

19071907
uint32_t RadioSpinel::GetBusSpeed(void) const { return GetSpinelDriver().GetSpinelInterface()->GetBusSpeed(); }
19081908

1909+
uint32_t RadioSpinel::GetBusLatency(void) const { return GetSpinelDriver().GetSpinelInterface()->GetBusLatency(); }
1910+
1911+
void RadioSpinel::SetBusLatency(uint32_t aLatency) { GetSpinelDriver().GetSpinelInterface()->SetBusLatency(aLatency); }
1912+
19091913
void RadioSpinel::HandleRcpUnexpectedReset(spinel_status_t aStatus)
19101914
{
19111915
OT_UNUSED_VARIABLE(aStatus);

src/lib/spinel/radio_spinel.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,22 @@ class RadioSpinel : private Logger
852852
*/
853853
uint32_t GetBusSpeed(void) const;
854854

855+
/**
856+
* Returns the bus latency between the host and the radio.
857+
*
858+
* @returns Bus latency in microseconds.
859+
*
860+
*/
861+
uint32_t GetBusLatency(void) const;
862+
863+
/**
864+
* Sets the bus latency between the host and the radio.
865+
*
866+
* @param[in] aLatency Bus latency in microseconds.
867+
*
868+
*/
869+
void SetBusLatency(uint32_t aLatency);
870+
855871
/**
856872
* Returns the co-processor sw version string.
857873
*

src/lib/spinel/spinel_interface.hpp

+16
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,22 @@ class SpinelInterface
134134
*/
135135
virtual uint32_t GetBusSpeed(void) const = 0;
136136

137+
/**
138+
* Returns the bus latency between the host and the radio.
139+
*
140+
* @returns Bus latency in microseconds.
141+
*
142+
*/
143+
virtual uint32_t GetBusLatency(void) const = 0;
144+
145+
/**
146+
* Sets the bus latency between the host and the radio.
147+
*
148+
* @param[in] aLatency Bus latency in microseconds.
149+
*
150+
*/
151+
virtual void SetBusLatency(uint32_t aLatency) = 0;
152+
137153
/**
138154
* Hardware resets the RCP.
139155
*

src/posix/platform/hdlc_interface.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ int HdlcInterface::OpenFile(const Url::Url &aRadioUrl)
466466
speed_t speed;
467467
uint8_t stopBit = 1;
468468
uint32_t baudrate = 115200;
469+
uint32_t latency = 0;
469470

470471
VerifyOrExit((rval = tcgetattr(fd, &tios)) == 0);
471472

@@ -596,6 +597,10 @@ int HdlcInterface::OpenFile(const Url::Url &aRadioUrl)
596597

597598
mBaudRate = baudrate;
598599

600+
IgnoreError(aRadioUrl.ParseUint32("uart-latency", latency));
601+
602+
mLatency = latency;
603+
599604
if (aRadioUrl.HasParam("uart-flow-control"))
600605
{
601606
tios.c_cflag |= CRTSCTS;

src/posix/platform/hdlc_interface.hpp

+17
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,22 @@ class HdlcInterface : public ot::Spinel::SpinelInterface, public Logger<HdlcInte
141141
*/
142142
uint32_t GetBusSpeed(void) const { return mBaudRate; }
143143

144+
/**
145+
* Returns the bus latency between the host and the radio.
146+
*
147+
* @returns Bus latency in microseconds.
148+
*
149+
*/
150+
uint32_t GetBusLatency(void) const { return mLatency; }
151+
152+
/**
153+
* Sets the bus latency between the host and the radio.
154+
*
155+
* @param[in] aLatency Bus latency in microseconds.
156+
*
157+
*/
158+
void SetBusLatency(uint32_t aLatency) { mLatency = aLatency; }
159+
144160
/**
145161
* Hardware resets the RCP.
146162
*
@@ -263,6 +279,7 @@ class HdlcInterface : public ot::Spinel::SpinelInterface, public Logger<HdlcInte
263279

264280
int mSockFd;
265281
uint32_t mBaudRate;
282+
uint32_t mLatency;
266283
Hdlc::Decoder mHdlcDecoder;
267284
const Url::Url &mRadioUrl;
268285

src/posix/platform/radio.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include <string.h>
3737

3838
#include <openthread/logging.h>
39+
#include <openthread/thread.h>
3940
#include <openthread/platform/diag.h>
4041

4142
#include "common/code_utils.hpp"
@@ -900,6 +901,22 @@ uint32_t otPlatRadioGetBusSpeed(otInstance *aInstance)
900901
return GetRadioSpinel().GetBusSpeed();
901902
}
902903

904+
uint32_t otPlatRadioGetBusLatency(otInstance *aInstance)
905+
{
906+
OT_UNUSED_VARIABLE(aInstance);
907+
return GetRadioSpinel().GetBusLatency();
908+
}
909+
910+
void otPlatRadioSetBusLatency(otInstance *aInstance, uint32_t aLatency)
911+
{
912+
GetRadioSpinel().SetBusLatency(aLatency);
913+
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
914+
otThreaUpdateCslTimeout(aInstance);
915+
#else
916+
OT_UNUSED_VARIABLE(aInstance);
917+
#endif
918+
}
919+
903920
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
904921
uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance)
905922
{

src/posix/platform/radio_url.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ const char *otSysGetRadioUrlHelpString(void)
6464
" spi-speed[=hertz] Specify the SPI speed in hertz.\n" \
6565
" spi-cs-delay[=usec] Specify the delay after C̅S̅ assertion, in µsec.\n" \
6666
" spi-reset-delay[=ms] Specify the delay after R̅E̅S̅E̅T̅ assertion, in milliseconds.\n" \
67+
" spi-latency[=usec] Specify the communication latency, in usec, default is 0.\n" \
6768
" spi-align-allowance[=n] Specify the maximum number of 0xFF bytes to clip from start of\n" \
6869
" MISO frame. Max value is 16.\n" \
6970
" spi-small-packet=[n] Specify the smallest packet we can receive in a single transaction.\n" \
@@ -83,6 +84,7 @@ const char *otSysGetRadioUrlHelpString(void)
8384
" uart-parity[=even|odd] Uart parity config, optional.\n" \
8485
" uart-stop[=number-of-bits] Uart stop bit, default is 1.\n" \
8586
" uart-baudrate[=baudrate] Uart baud rate, default is 115200.\n" \
87+
" uart-latency[=usec] Uart communication latency in usec, default is 0.\n" \
8688
" uart-flow-control Enable flow control, disabled by default.\n" \
8789
" uart-reset Reset connection after hard resetting RCP(USB CDC ACM).\n" \
8890
"\n"

src/posix/platform/spi_interface.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ otError SpiInterface::Init(ReceiveFrameCallback aCallback, void *aCallbackContex
120120
uint8_t spiGpioResetLine = 0;
121121
uint8_t spiMode = OT_PLATFORM_CONFIG_SPI_DEFAULT_MODE;
122122
uint32_t spiSpeed = SPI_IOC_WR_MAX_SPEED_HZ;
123+
uint32_t spiLatency = 0;
123124
uint32_t spiResetDelay = OT_PLATFORM_CONFIG_SPI_DEFAULT_RESET_DELAY_MS;
124125
uint16_t spiCsDelay = OT_PLATFORM_CONFIG_SPI_DEFAULT_CS_DELAY_US;
125126
uint8_t spiAlignAllowance = OT_PLATFORM_CONFIG_SPI_DEFAULT_ALIGN_ALLOWANCE;
@@ -138,6 +139,7 @@ otError SpiInterface::Init(ReceiveFrameCallback aCallback, void *aCallbackContex
138139
VerifyOrDie(mRadioUrl.ParseUint32("spi-speed", spiSpeed) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS);
139140
VerifyOrDie(mRadioUrl.ParseUint32("spi-reset-delay", spiResetDelay) != OT_ERROR_INVALID_ARGS,
140141
OT_EXIT_INVALID_ARGUMENTS);
142+
VerifyOrDie(mRadioUrl.ParseUint32("spi-latency", spiLatency) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS);
141143
VerifyOrDie(mRadioUrl.ParseUint16("spi-cs-delay", spiCsDelay) != OT_ERROR_INVALID_ARGS, OT_EXIT_INVALID_ARGUMENTS);
142144
VerifyOrDie(mRadioUrl.ParseUint8("spi-align-allowance", spiAlignAllowance) != OT_ERROR_INVALID_ARGS,
143145
OT_EXIT_INVALID_ARGUMENTS);
@@ -146,6 +148,7 @@ otError SpiInterface::Init(ReceiveFrameCallback aCallback, void *aCallbackContex
146148
VerifyOrDie(spiAlignAllowance <= kSpiAlignAllowanceMax, OT_EXIT_INVALID_ARGUMENTS);
147149

148150
mSpiResetDelay = spiResetDelay;
151+
mSpiLatency = spiLatency;
149152
mSpiCsDelayUs = spiCsDelay;
150153
mSpiSmallPacketSize = spiSmallPacketSize;
151154
mSpiAlignAllowance = spiAlignAllowance;

0 commit comments

Comments
 (0)