Skip to content

Commit a2673db

Browse files
committed
add streambuffer updates
1 parent 58151b3 commit a2673db

File tree

9 files changed

+323
-171
lines changed

9 files changed

+323
-171
lines changed

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=FreeRTOS
2-
version=11.0.1-1
2+
version=11.0.1-2
33
author=Richard Barry <[email protected]>
44
maintainer=Phillip Stevens <[email protected]>
55
sentence=FreeRTOS Real Time Operating System implemented for AVR (Uno, Nano, Leonardo, Mega).

src/Arduino_FreeRTOS.h

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,12 +499,36 @@
499499

500500
#endif /* configUSE_TIMERS */
501501

502+
#ifndef portHAS_NESTED_INTERRUPTS
503+
#if defined( portSET_INTERRUPT_MASK_FROM_ISR ) && defined( portCLEAR_INTERRUPT_MASK_FROM_ISR )
504+
#define portHAS_NESTED_INTERRUPTS 1
505+
#else
506+
#define portHAS_NESTED_INTERRUPTS 0
507+
#endif
508+
#endif
509+
502510
#ifndef portSET_INTERRUPT_MASK_FROM_ISR
503-
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
511+
#if ( portHAS_NESTED_INTERRUPTS == 1 )
512+
#error portSET_INTERRUPT_MASK_FROM_ISR must be defined for ports that support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1)
513+
#else
514+
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
515+
#endif
516+
#else
517+
#if ( portHAS_NESTED_INTERRUPTS == 0 )
518+
#error portSET_INTERRUPT_MASK_FROM_ISR must not be defined for ports that do not support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
519+
#endif
504520
#endif
505521

506522
#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
507-
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue )
523+
#if ( portHAS_NESTED_INTERRUPTS == 1 )
524+
#error portCLEAR_INTERRUPT_MASK_FROM_ISR must be defined for ports that support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1)
525+
#else
526+
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue )
527+
#endif
528+
#else
529+
#if ( portHAS_NESTED_INTERRUPTS == 0 )
530+
#error portCLEAR_INTERRUPT_MASK_FROM_ISR must not be defined for ports that do not support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
531+
#endif
508532
#endif
509533

510534
#ifndef portCLEAN_UP_TCB
@@ -2475,6 +2499,22 @@
24752499
#define traceRETURN_xStreamBufferReceiveCompletedFromISR( xReturn )
24762500
#endif
24772501

2502+
#ifndef traceENTER_uxStreamBufferGetStreamBufferNotificationIndex
2503+
#define traceENTER_uxStreamBufferGetStreamBufferNotificationIndex( xStreamBuffer )
2504+
#endif
2505+
2506+
#ifndef traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex
2507+
#define traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex( uxNotificationIndex )
2508+
#endif
2509+
2510+
#ifndef traceENTER_vStreamBufferSetStreamBufferNotificationIndex
2511+
#define traceENTER_vStreamBufferSetStreamBufferNotificationIndex( xStreamBuffer, uxNotificationIndex )
2512+
#endif
2513+
2514+
#ifndef traceRETURN_vStreamBufferSetStreamBufferNotificationIndex
2515+
#define traceRETURN_vStreamBufferSetStreamBufferNotificationIndex()
2516+
#endif
2517+
24782518
#ifndef traceENTER_uxStreamBufferGetStreamBufferNumber
24792519
#define traceENTER_uxStreamBufferGetStreamBufferNumber( xStreamBuffer )
24802520
#endif
@@ -3236,6 +3276,7 @@ typedef struct xSTATIC_STREAM_BUFFER
32363276
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
32373277
void * pvDummy5[ 2 ];
32383278
#endif
3279+
UBaseType_t uxDummy6;
32393280
} StaticStreamBuffer_t;
32403281

32413282
/* Message buffers are built on stream buffers. */

src/atomic.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@
3333
* This file implements atomic functions by disabling interrupts globally.
3434
* Implementations with architecture specific atomic instructions can be
3535
* provided under each compiler directory.
36+
*
37+
* The atomic interface can be used in FreeRTOS tasks on all FreeRTOS ports. It
38+
* can also be used in Interrupt Service Routines (ISRs) on FreeRTOS ports that
39+
* support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1). The
40+
* atomic interface must not be used in ISRs on FreeRTOS ports that do not
41+
* support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
42+
* because ISRs on these ports cannot be interrupted and therefore, do not need
43+
* atomics in ISRs.
3644
*/
3745

3846
#ifndef ATOMIC_H
@@ -59,7 +67,7 @@
5967
* ATOMIC_ENTER_CRITICAL().
6068
*
6169
*/
62-
#if defined( portSET_INTERRUPT_MASK_FROM_ISR )
70+
#if ( portHAS_NESTED_INTERRUPTS == 1 )
6371

6472
/* Nested interrupt scheme is supported in this port. */
6573
#define ATOMIC_ENTER_CRITICAL() \
@@ -74,7 +82,7 @@
7482
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
7583
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
7684

77-
#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
85+
#endif /* portHAS_NESTED_INTERRUPTS */
7886

7987
/*
8088
* Port specific definition -- "always inline".

src/port.c

Lines changed: 83 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,10 @@
4242
*----------------------------------------------------------*/
4343

4444
/* Start tasks with interrupts enabled. */
45-
#define portFLAGS_INT_ENABLED ( (StackType_t) 0x80 )
45+
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )
4646

4747
#if defined( portUSE_WDTO )
48-
#define portSCHEDULER_ISR WDT_vect
48+
#define portSCHEDULER_ISR WDT_vect
4949

5050
#else
5151
#warning "The user must define a Timer to be used for the Scheduler."
@@ -54,27 +54,27 @@
5454
/*-----------------------------------------------------------*/
5555

5656
/* We require the address of the pxCurrentTCB variable, but don't want to know
57-
any details of its type. */
57+
* any details of its type. */
5858
typedef void TCB_t;
5959
extern volatile TCB_t * volatile pxCurrentTCB;
6060

6161
/*-----------------------------------------------------------*/
6262

6363
/**
64-
Enable the watchdog timer, configuring it for expire after
65-
(value) timeout (which is a combination of the WDP0
66-
through WDP3 bits).
67-
68-
This function is derived from <avr/wdt.h> but enables only
69-
the interrupt bit (WDIE), rather than the reset bit (WDE).
70-
71-
Can't find it documented but the WDT, once enabled,
72-
rolls over and fires a new interrupt each time.
73-
74-
See also the symbolic constants WDTO_15MS et al.
75-
76-
Updated to match avr-libc 2.0.0
77-
*/
64+
* Enable the watchdog timer, configuring it for expire after
65+
* (value) timeout (which is a combination of the WDP0
66+
* through WDP3 bits).
67+
*
68+
* This function is derived from <avr/wdt.h> but enables only
69+
* the interrupt bit (WDIE), rather than the reset bit (WDE).
70+
*
71+
* Can't find it documented but the WDT, once enabled,
72+
* rolls over and fires a new interrupt each time.
73+
*
74+
* See also the symbolic constants WDTO_15MS et al.
75+
*
76+
* Updated to match avr-libc 2.0.0
77+
*/
7878

7979
#if defined( portUSE_WDTO )
8080

@@ -121,26 +121,26 @@ void wdt_interrupt_enable (const uint8_t value)
121121

122122
/*-----------------------------------------------------------*/
123123
/**
124-
Enable the watchdog timer, configuring it for expire after
125-
(value) timeout (which is a combination of the WDP0
126-
through WDP3 bits).
127-
128-
This function is derived from <avr/wdt.h> but enables both
129-
the reset bit (WDE), and the interrupt bit (WDIE).
130-
131-
This will ensure that if the interrupt is not serviced
132-
before the second timeout, the AVR will reset.
133-
134-
Servicing the interrupt automatically clears it,
135-
and ensures the AVR does not reset.
136-
137-
Can't find it documented but the WDT, once enabled,
138-
rolls over and fires a new interrupt each time.
139-
140-
See also the symbolic constants WDTO_15MS et al.
141-
142-
Updated to match avr-libc 2.0.0
143-
*/
124+
* Enable the watchdog timer, configuring it for expire after
125+
* (value) timeout (which is a combination of the WDP0
126+
* through WDP3 bits).
127+
*
128+
* This function is derived from <avr/wdt.h> but enables both
129+
* the reset bit (WDE), and the interrupt bit (WDIE).
130+
*
131+
* This will ensure that if the interrupt is not serviced
132+
* before the second timeout, the AVR will reset.
133+
*
134+
* Servicing the interrupt automatically clears it,
135+
* and ensures the AVR does not reset.
136+
*
137+
* Can't find it documented but the WDT, once enabled,
138+
* rolls over and fires a new interrupt each time.
139+
*
140+
* See also the symbolic constants WDTO_15MS et al.
141+
*
142+
* Updated to match avr-libc 2.0.0
143+
*/
144144

145145
#if defined( portUSE_WDTO )
146146

@@ -551,10 +551,11 @@ uint16_t usAddress;
551551
#endif
552552

553553
/* Next simulate the stack as if after a call to portSAVE_CONTEXT().
554-
portSAVE_CONTEXT places the flags on the stack immediately after r0
555-
to ensure the interrupts get disabled as soon as possible, and so ensuring
556-
the stack use is minimal should a context switch interrupt occur. */
557-
*pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
554+
* portSAVE_CONTEXT places the flags on the stack immediately after r0
555+
* to ensure the interrupts get disabled as soon as possible, and so ensuring
556+
* the stack use is minimal should a context switch interrupt occur.
557+
*/
558+
*pxTopOfStack = ( StackType_t ) 0x00; /* R0 */
558559
pxTopOfStack--;
559560
*pxTopOfStack = portFLAGS_INT_ENABLED;
560561
pxTopOfStack--;
@@ -605,7 +606,7 @@ BaseType_t xPortStartScheduler( void )
605606
portRESTORE_CONTEXT();
606607

607608
/* Simulate a function call end as generated by the compiler. We will now
608-
jump to the start of the task the context of which we have just restored. */
609+
* jump to the start of the task the context of which we have just restored. */
609610
__asm__ __volatile__ ( "ret" );
610611

611612
/* Should not get here. */
@@ -622,15 +623,15 @@ void vPortEndScheduler( void )
622623
}
623624
/*-----------------------------------------------------------*/
624625

625-
/*
626-
* Choose which delay function to use.
627-
* Arduino delay() is a millisecond granularity busy wait, that
628-
* that breaks FreeRTOS. So its use is limited to less than one
629-
* System Tick (portTICK_PERIOD_MS milliseconds).
630-
* FreeRTOS vTaskDelay() is relies on the System Tick which here
631-
* has a granularity of portTICK_PERIOD_MS milliseconds (15ms),
632-
* with the remainder implemented as an Arduino delay().
633-
*/
626+
/*
627+
* Choose which delay function to use.
628+
* Arduino delay() is a millisecond granularity busy wait, that
629+
* that breaks FreeRTOS. So its use is limited to less than one
630+
* System Tick (portTICK_PERIOD_MS milliseconds).
631+
* FreeRTOS vTaskDelay() is relies on the System Tick which here
632+
* has a granularity of portTICK_PERIOD_MS milliseconds (15ms),
633+
* with the remainder implemented as an Arduino delay().
634+
*/
634635

635636
#ifdef delay
636637
#undef delay
@@ -639,7 +640,7 @@ void vPortEndScheduler( void )
639640
extern void delay ( unsigned long ms );
640641

641642
#if defined( portUSE_WDTO )
642-
void vPortDelay( const uint32_t ms ) __attribute__ ((hot, flatten));
643+
void vPortDelay( const uint32_t ms ) __attribute__ ( ( hot, flatten ) );
643644
void vPortDelay( const uint32_t ms )
644645
{
645646
if ( ms < portTICK_PERIOD_MS )
@@ -655,15 +656,15 @@ void vPortDelay( const uint32_t ms )
655656
#else
656657
#warning "The user is responsible to provide function `vPortDelay()`"
657658
#warning "Arduino uses all AVR MCU Timers, so breakage may occur"
658-
extern void vPortDelay( const uint32_t ms ) __attribute__ ((hot, flatten));
659+
extern void vPortDelay( const uint32_t ms ) __attribute__ ( ( hot, flatten ) );
659660
#endif
660661
/*-----------------------------------------------------------*/
661662

662663
/*
663664
* Manual context switch. The first thing we do is save the registers so we
664665
* can use a naked attribute.
665666
*/
666-
void vPortYield( void ) __attribute__ ((hot, flatten, naked));
667+
void vPortYield( void ) __attribute__( ( hot, flatten, naked ) );
667668
void vPortYield( void )
668669
{
669670
portSAVE_CONTEXT();
@@ -678,7 +679,7 @@ void vPortYield( void )
678679
* Manual context switch callable from ISRs. The first thing we do is save
679680
* the registers so we can use a naked attribute.
680681
*/
681-
void vPortYieldFromISR( void ) __attribute__ ((hot, flatten, naked));
682+
void vPortYieldFromISR( void ) __attribute__( ( hot, flatten, naked ) );
682683
void vPortYieldFromISR( void )
683684
{
684685
portSAVE_CONTEXT();
@@ -695,7 +696,7 @@ void vPortYieldFromISR( void )
695696
* difference from vPortYield() is the tick count is incremented as the
696697
* call comes from the tick ISR.
697698
*/
698-
void vPortYieldFromTick( void ) __attribute__ ((hot, flatten, naked));
699+
void vPortYieldFromTick( void ) __attribute__( ( hot, flatten, naked ) );
699700
void vPortYieldFromTick( void )
700701
{
701702
portSAVE_CONTEXT();
@@ -704,28 +705,30 @@ void vPortYieldFromTick( void )
704705
{
705706
vTaskSwitchContext();
706707
}
708+
707709
portRESTORE_CONTEXT();
708710

709711
__asm__ __volatile__ ( "ret" );
710712
}
711713
/*-----------------------------------------------------------*/
712714

713715
#if defined( portUSE_WDTO )
714-
/*
715-
* Setup WDT to generate a tick interrupt.
716-
*/
717-
void prvSetupTimerInterrupt( void )
718-
{
719-
/* reset watchdog */
720-
wdt_reset();
721716

722-
/* set up WDT Interrupt (rather than the WDT Reset). */
723-
wdt_interrupt_enable( portUSE_WDTO );
724-
}
717+
/*
718+
* Setup WDT to generate a tick interrupt.
719+
*/
720+
void prvSetupTimerInterrupt( void )
721+
{
722+
/* reset watchdog */
723+
wdt_reset();
724+
725+
/* set up WDT Interrupt (rather than the WDT Reset). */
726+
wdt_interrupt_enable( portUSE_WDTO );
727+
}
725728

726729
#else
727-
#warning "The user is responsible to provide function `prvSetupTimerInterrupt()`"
728-
extern void prvSetupTimerInterrupt( void );
730+
#warning "The user is responsible to provide function `prvSetupTimerInterrupt()`"
731+
extern void prvSetupTimerInterrupt( void );
729732
#endif
730733

731734
/*-----------------------------------------------------------*/
@@ -740,15 +743,16 @@ extern void prvSetupTimerInterrupt( void );
740743
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
741744
*
742745
*/
743-
ISR(portSCHEDULER_ISR, ISR_NAKED) __attribute__ ((hot, flatten));
744-
/* ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten));
745-
*/
746-
ISR(portSCHEDULER_ISR)
746+
ISR( portSCHEDULER_ISR, ISR_NAKED ) __attribute__( ( hot, flatten ) );
747+
748+
/* ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten));
749+
*/
750+
ISR( portSCHEDULER_ISR )
747751
{
748752
vPortYieldFromTick();
749753
__asm__ __volatile__ ( "reti" );
750754
}
751-
#else
755+
#else /* if configUSE_PREEMPTION == 1 */
752756

753757
/*
754758
* Tick ISR for the cooperative scheduler. All this does is increment the
@@ -757,11 +761,12 @@ extern void prvSetupTimerInterrupt( void );
757761
*
758762
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
759763
*/
760-
ISR(portSCHEDULER_ISR) __attribute__ ((hot, flatten));
761-
/* ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten));
762-
*/
763-
ISR(portSCHEDULER_ISR)
764+
ISR( portSCHEDULER_ISR ) __attribute__( ( hot, flatten ) );
765+
766+
/* ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten));
767+
*/
768+
ISR( portSCHEDULER_ISR )
764769
{
765770
xTaskIncrementTick();
766771
}
767-
#endif
772+
#endif /* if configUSE_PREEMPTION == 1 */

0 commit comments

Comments
 (0)