Skip to content

Commit 57ca4e1

Browse files
hujun260xiaoxiang781216
authored andcommitted
up_rtc_gettime: add spinlock to protect up_rtc_gettime
reason: We have removed the critical section protection for the up_rtc_gettime function in common code. Signed-off-by: hujun5 <[email protected]>
1 parent 89455bc commit 57ca4e1

File tree

10 files changed

+108
-37
lines changed

10 files changed

+108
-37
lines changed

arch/arm/src/cxd56xx/cxd56_rtc.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -399,10 +399,14 @@ time_t up_rtc_time(void)
399399
#ifdef CONFIG_RTC_HIRES
400400
int up_rtc_gettime(struct timespec *tp)
401401
{
402+
irqstate_t flags;
402403
uint64_t count;
403404

404-
count = cxd56_rtc_count();
405+
flags = spin_lock_irqsave(&g_rtc_lock);
406+
407+
count = cxd56_rtc_count_nolock();
405408
count += g_rtc_save->offset;
409+
spin_unlock_irqrestore(&g_rtc_lock, flags);
406410

407411
/* Then we can save the time in seconds and fractional seconds. */
408412

@@ -477,21 +481,28 @@ int up_rtc_settime(const struct timespec *tp)
477481
*
478482
****************************************************************************/
479483

480-
uint64_t cxd56_rtc_count(void)
484+
uint64_t cxd56_rtc_count_nolock(void)
481485
{
482486
uint64_t val;
483-
irqstate_t flags;
484487

485488
/* The pre register is latched with reading the post rtcounter register,
486489
* so these registers always have to been read in the below order,
487490
* 1st post -> 2nd pre, and should be operated in atomic.
488491
*/
489492

490-
flags = spin_lock_irqsave(&g_rtc_lock);
491-
492493
val = (uint64_t)getreg32(CXD56_RTC0_RTPOSTCNT) << 15;
493494
val |= getreg32(CXD56_RTC0_RTPRECNT);
494495

496+
return val;
497+
}
498+
499+
uint64_t cxd56_rtc_count(void)
500+
{
501+
uint64_t val;
502+
irqstate_t flags;
503+
504+
flags = spin_lock_irqsave(&g_rtc_lock);
505+
val = cxd56_rtc_count_nolock();
495506
spin_unlock_irqrestore(&g_rtc_lock, flags);
496507

497508
return val;

arch/arm/src/cxd56xx/cxd56_rtc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ extern "C"
9292
****************************************************************************/
9393

9494
uint64_t cxd56_rtc_count(void);
95+
uint64_t cxd56_rtc_count_nolock(void);
9596

9697
/****************************************************************************
9798
* Name: cxd56_rtc_almcount

arch/arm/src/kinetis/kinetis_rtc.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <nuttx/arch.h>
2929
#include <nuttx/irq.h>
3030
#include <nuttx/timers/rtc.h>
31+
#include <nuttx/spinlock.h>
3132
#include <arch/board/board.h>
3233

3334
#include <stdlib.h>
@@ -62,6 +63,10 @@
6263
* Private Data
6364
****************************************************************************/
6465

66+
#ifdef CONFIG_RTC_HIRES
67+
static spinlock_t g_rtc_lock = SP_UNLOCKED;
68+
#endif
69+
6570
#ifdef CONFIG_RTC_ALARM
6671
static alarmcb_t g_alarmcb;
6772
static bool rtc_irq_state = false;
@@ -436,7 +441,7 @@ int up_rtc_gettime(struct timespec *tp)
436441
* wrapped-around.
437442
*/
438443

439-
flags = enter_critical_section();
444+
flags = spin_lock_irqsave(&g_rtc_lock);
440445
do
441446
{
442447
prescaler = getreg32(KINETIS_RTC_TPR);
@@ -445,7 +450,7 @@ int up_rtc_gettime(struct timespec *tp)
445450
}
446451
while (prescaler > prescaler2);
447452

448-
leave_critical_section(flags);
453+
spin_unlock_irqrestore(&g_rtc_lock, flags);
449454

450455
/* Build seconds + nanoseconds from seconds and prescaler register */
451456

@@ -479,7 +484,7 @@ int up_rtc_settime(const struct timespec *tp)
479484
seconds = tp->tv_sec;
480485
prescaler = tp->tv_nsec / (1000000000 / CONFIG_RTC_FREQUENCY);
481486

482-
flags = enter_critical_section();
487+
flags = spin_lock_irqsave(&g_rtc_lock);
483488

484489
putreg32(0, KINETIS_RTC_SR); /* Disable counter */
485490

@@ -488,7 +493,7 @@ int up_rtc_settime(const struct timespec *tp)
488493

489494
putreg32(RTC_SR_TCE, KINETIS_RTC_SR); /* Re-enable counter */
490495

491-
leave_critical_section(flags);
496+
spin_unlock_irqrestore(&g_rtc_lock, flags);
492497

493498
return OK;
494499
}

arch/arm/src/max326xx/max32660/max32660_rtc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,11 +403,14 @@ time_t up_rtc_time(void)
403403
#ifdef CONFIG_RTC_HIRES
404404
int up_rtc_gettime(struct timespec *tp)
405405
{
406+
irqstate_t flags;
406407
uint64_t tmp;
407408
uint32_t sec;
408409
uint32_t ssec;
409410
uint32_t verify;
410411

412+
flags = spin_lock_irqsave(&g_rtc_lock);
413+
411414
/* Read the time handling rollover to full seconds */
412415

413416
do
@@ -418,6 +421,8 @@ int up_rtc_gettime(struct timespec *tp)
418421
}
419422
while (verify != sec);
420423

424+
spin_unlock_irqrestore(&g_rtc_lock, flags);
425+
421426
/* Format as a tm */
422427

423428
tmp = ((uint64_t)ssec * NSEC_PER_SEC) / 256;

arch/arm/src/s32k1xx/s32k1xx_rtc.c

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <nuttx/arch.h>
3838
#include <nuttx/irq.h>
3939
#include <nuttx/timers/rtc.h>
40+
#include <nuttx/spinlock.h>
4041

4142
#include <arch/board/board.h>
4243

@@ -60,6 +61,12 @@
6061

6162
volatile bool g_rtc_enabled = false;
6263

64+
/****************************************************************************
65+
* Private Data
66+
****************************************************************************/
67+
68+
static spinlock_t g_rtc_lock = SP_UNLOCKED;
69+
6370
/****************************************************************************
6471
* Private Functions
6572
****************************************************************************/
@@ -247,7 +254,7 @@ int up_rtc_gettime(struct timespec *tp)
247254
* wrapped-around.
248255
*/
249256

250-
flags = enter_critical_section();
257+
flags = spin_lock_irqsave(&g_rtc_lock);
251258
do
252259
{
253260
prescaler = getreg32(S32K1XX_RTC_TPR);
@@ -256,7 +263,7 @@ int up_rtc_gettime(struct timespec *tp)
256263
}
257264
while (prescaler > prescaler2);
258265

259-
leave_critical_section(flags);
266+
spin_unlock_irqrestore(&g_rtc_lock, flags);
260267

261268
/* Build seconds + nanoseconds from seconds and prescaler register */
262269

@@ -296,7 +303,7 @@ int up_rtc_settime(const struct timespec *ts)
296303
prescaler = 0;
297304
#endif
298305

299-
flags = enter_critical_section();
306+
flags = spin_lock_irqsave(&g_rtc_lock);
300307

301308
s32k1xx_rtc_disable();
302309

@@ -305,7 +312,7 @@ int up_rtc_settime(const struct timespec *ts)
305312

306313
s32k1xx_rtc_enable();
307314

308-
leave_critical_section(flags);
315+
spin_unlock_irqrestore(&g_rtc_lock, flags);
309316

310317
return OK;
311318
}

arch/arm/src/sam34/sam_rtc.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <nuttx/arch.h>
3535
#include <nuttx/irq.h>
3636
#include <nuttx/wqueue.h>
37+
#include <nuttx/spinlock.h>
3738

3839
#include <arch/board/board.h>
3940

@@ -72,6 +73,8 @@
7273
* Private Data
7374
****************************************************************************/
7475

76+
static spinlock_t g_rtc_lock = SP_UNLOCKED;
77+
7578
/* Callback to use when the alarm expires */
7679

7780
#ifdef CONFIG_RTC_ALARM
@@ -654,7 +657,8 @@ int sam_rtc_setalarm(const struct timespec *tp, alarmcb_t callback)
654657

655658
/* Is there already something waiting on the ALARM? */
656659

657-
flags = enter_critical_section();
660+
flags = spin_lock_irqsave(&g_rtc_lock);
661+
sched_lock();
658662
if (g_alarmcb == NULL)
659663
{
660664
/* No.. Save the callback function pointer */
@@ -732,7 +736,8 @@ int sam_rtc_setalarm(const struct timespec *tp, alarmcb_t callback)
732736
ret = OK;
733737
}
734738

735-
leave_critical_section(flags);
739+
spin_unlock_irqrestore(&g_rtc_lock, flags);
740+
sched_unlock();
736741
return ret;
737742
}
738743
#endif
@@ -759,11 +764,13 @@ int up_rtc_gettime(struct timespec *tp)
759764
{
760765
/* This is a hack to emulate a high resolution rtc using the rtt */
761766

767+
irqstate_t flags;
762768
uint32_t rtc_cal;
763769
uint32_t rtc_tim;
764770
uint32_t rtt_val;
765771
struct tm t;
766772

773+
flags = spin_lock_irqsave(&g_rtc_lock);
767774
do
768775
{
769776
rtc_cal = getreg32(SAM_RTC_CALR);
@@ -774,6 +781,7 @@ int up_rtc_gettime(struct timespec *tp)
774781
rtc_tim != getreg32(SAM_RTC_TIMR) ||
775782
rtt_val != getreg32(SAM_RTT_VR));
776783

784+
spin_unlock_irqrestore(&g_rtc_lock, flags);
777785
t.tm_sec = rtc_bcd2bin((rtc_tim & RTC_TIMR_SEC_MASK) >>
778786
RTC_TIMR_SEC_SHIFT);
779787
t.tm_min = rtc_bcd2bin((rtc_tim & RTC_TIMR_MIN_MASK) >>

arch/arm/src/stm32/stm32_eth.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <nuttx/net/mii.h>
4949
#include <nuttx/net/ip.h>
5050
#include <nuttx/net/netdev.h>
51+
#include <nuttx/spinlock.h>
5152

5253
#if defined(CONFIG_NET_PKT)
5354
# include <nuttx/net/pkt.h>
@@ -651,6 +652,7 @@ static uint8_t g_alloc[STM32_ETH_NFREEBUFFERS *
651652
static struct stm32_ethmac_s g_stm32ethmac[STM32_NETHERNET];
652653

653654
#ifdef CONFIG_STM32_ETH_PTP_RTC_HIRES
655+
static spinlock_t g_rtc_lock = SP_UNLOCKED;
654656
volatile bool g_rtc_enabled;
655657
static struct timespec g_stm32_eth_ptp_basetime;
656658
#endif
@@ -3778,10 +3780,10 @@ static void stm32_eth_ptp_convert_rxtime(struct stm32_ethmac_s *priv)
37783780

37793781
/* Sample PTP and CLOCK_REALTIME close to each other */
37803782

3781-
flags = enter_critical_section();
37823783
clock_gettime(CLOCK_REALTIME, &realtime);
3784+
flags = spin_lock_irqsave(&g_rtc_lock);
37833785
ptptime = stm32_eth_ptp_gettime();
3784-
leave_critical_section(flags);
3786+
spin_unlock_irqrestore(&g_rtc_lock, flags);
37853787

37863788
/* Compute how much time has elapsed since packet reception
37873789
* and add that to current time.
@@ -4308,7 +4310,10 @@ int up_rtc_initialize(void)
43084310

43094311
int up_rtc_gettime(struct timespec *tp)
43104312
{
4313+
irqstate_t flags;
43114314
uint64_t timestamp;
4315+
4316+
flags = spin_lock_irqsave(&g_rtc_lock);
43124317
timestamp = stm32_eth_ptp_gettime();
43134318

43144319
if (timestamp == 0)
@@ -4317,12 +4322,14 @@ int up_rtc_gettime(struct timespec *tp)
43174322
* Normally we shouldn't end up here because g_rtc_enabled is false.
43184323
*/
43194324

4325+
spin_unlock_irqrestore(&g_rtc_lock, flags);
43204326
DEBUGASSERT(!g_rtc_enabled);
43214327
return -EBUSY;
43224328
}
43234329

43244330
ptp_to_timespec(timestamp, tp);
43254331
clock_timespec_add(tp, &g_stm32_eth_ptp_basetime, tp);
4332+
spin_unlock_irqrestore(&g_rtc_lock, flags);
43264333

43274334
return OK;
43284335
}
@@ -4346,6 +4353,9 @@ int up_rtc_settime(const struct timespec *tp)
43464353
{
43474354
struct timespec ptptime;
43484355
uint64_t timestamp;
4356+
irqstate_t flags;
4357+
4358+
flags = spin_lock_irqsave(&g_rtc_lock);
43494359
timestamp = stm32_eth_ptp_gettime();
43504360

43514361
if (timestamp == 0)
@@ -4354,6 +4364,7 @@ int up_rtc_settime(const struct timespec *tp)
43544364
* Normally we shouldn't end up here because g_rtc_enabled is false.
43554365
*/
43564366

4367+
spin_unlock_irqrestore(&g_rtc_lock, flags);
43574368
DEBUGASSERT(!g_rtc_enabled);
43584369
return -EBUSY;
43594370
}
@@ -4365,6 +4376,7 @@ int up_rtc_settime(const struct timespec *tp)
43654376

43664377
ptp_to_timespec(timestamp, &ptptime);
43674378
clock_timespec_subtract(tp, &ptptime, &g_stm32_eth_ptp_basetime);
4379+
spin_unlock_irqrestore(&g_rtc_lock, flags);
43684380

43694381
return OK;
43704382
}

0 commit comments

Comments
 (0)