Skip to content

Commit

Permalink
add streambuffer updates
Browse files Browse the repository at this point in the history
  • Loading branch information
feilipu committed Jan 8, 2024
1 parent 58151b3 commit a2673db
Show file tree
Hide file tree
Showing 9 changed files with 323 additions and 171 deletions.
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=FreeRTOS
version=11.0.1-1
version=11.0.1-2
author=Richard Barry <info@freertos.org>
maintainer=Phillip Stevens <phillip.stevens@gmail.com>
sentence=FreeRTOS Real Time Operating System implemented for AVR (Uno, Nano, Leonardo, Mega).
Expand Down
45 changes: 43 additions & 2 deletions src/Arduino_FreeRTOS.h
Original file line number Diff line number Diff line change
Expand Up @@ -499,12 +499,36 @@

#endif /* configUSE_TIMERS */

#ifndef portHAS_NESTED_INTERRUPTS
#if defined( portSET_INTERRUPT_MASK_FROM_ISR ) && defined( portCLEAR_INTERRUPT_MASK_FROM_ISR )
#define portHAS_NESTED_INTERRUPTS 1
#else
#define portHAS_NESTED_INTERRUPTS 0
#endif
#endif

#ifndef portSET_INTERRUPT_MASK_FROM_ISR
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
#if ( portHAS_NESTED_INTERRUPTS == 1 )
#error portSET_INTERRUPT_MASK_FROM_ISR must be defined for ports that support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1)
#else
#define portSET_INTERRUPT_MASK_FROM_ISR() 0
#endif
#else
#if ( portHAS_NESTED_INTERRUPTS == 0 )
#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)
#endif
#endif

#ifndef portCLEAR_INTERRUPT_MASK_FROM_ISR
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue )
#if ( portHAS_NESTED_INTERRUPTS == 1 )
#error portCLEAR_INTERRUPT_MASK_FROM_ISR must be defined for ports that support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1)
#else
#define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) ( uxSavedStatusValue )
#endif
#else
#if ( portHAS_NESTED_INTERRUPTS == 0 )
#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)
#endif
#endif

#ifndef portCLEAN_UP_TCB
Expand Down Expand Up @@ -2475,6 +2499,22 @@
#define traceRETURN_xStreamBufferReceiveCompletedFromISR( xReturn )
#endif

#ifndef traceENTER_uxStreamBufferGetStreamBufferNotificationIndex
#define traceENTER_uxStreamBufferGetStreamBufferNotificationIndex( xStreamBuffer )
#endif

#ifndef traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex
#define traceRETURN_uxStreamBufferGetStreamBufferNotificationIndex( uxNotificationIndex )
#endif

#ifndef traceENTER_vStreamBufferSetStreamBufferNotificationIndex
#define traceENTER_vStreamBufferSetStreamBufferNotificationIndex( xStreamBuffer, uxNotificationIndex )
#endif

#ifndef traceRETURN_vStreamBufferSetStreamBufferNotificationIndex
#define traceRETURN_vStreamBufferSetStreamBufferNotificationIndex()
#endif

#ifndef traceENTER_uxStreamBufferGetStreamBufferNumber
#define traceENTER_uxStreamBufferGetStreamBufferNumber( xStreamBuffer )
#endif
Expand Down Expand Up @@ -3236,6 +3276,7 @@ typedef struct xSTATIC_STREAM_BUFFER
#if ( configUSE_SB_COMPLETED_CALLBACK == 1 )
void * pvDummy5[ 2 ];
#endif
UBaseType_t uxDummy6;
} StaticStreamBuffer_t;

/* Message buffers are built on stream buffers. */
Expand Down
12 changes: 10 additions & 2 deletions src/atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@
* This file implements atomic functions by disabling interrupts globally.
* Implementations with architecture specific atomic instructions can be
* provided under each compiler directory.
*
* The atomic interface can be used in FreeRTOS tasks on all FreeRTOS ports. It
* can also be used in Interrupt Service Routines (ISRs) on FreeRTOS ports that
* support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 1). The
* atomic interface must not be used in ISRs on FreeRTOS ports that do not
* support nested interrupts (i.e. portHAS_NESTED_INTERRUPTS is set to 0)
* because ISRs on these ports cannot be interrupted and therefore, do not need
* atomics in ISRs.
*/

#ifndef ATOMIC_H
Expand All @@ -59,7 +67,7 @@
* ATOMIC_ENTER_CRITICAL().
*
*/
#if defined( portSET_INTERRUPT_MASK_FROM_ISR )
#if ( portHAS_NESTED_INTERRUPTS == 1 )

/* Nested interrupt scheme is supported in this port. */
#define ATOMIC_ENTER_CRITICAL() \
Expand All @@ -74,7 +82,7 @@
#define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
#define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()

#endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
#endif /* portHAS_NESTED_INTERRUPTS */

/*
* Port specific definition -- "always inline".
Expand Down
161 changes: 83 additions & 78 deletions src/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,10 @@
*----------------------------------------------------------*/

/* Start tasks with interrupts enabled. */
#define portFLAGS_INT_ENABLED ( (StackType_t) 0x80 )
#define portFLAGS_INT_ENABLED ( ( StackType_t ) 0x80 )

#if defined( portUSE_WDTO )
#define portSCHEDULER_ISR WDT_vect
#define portSCHEDULER_ISR WDT_vect

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

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

/*-----------------------------------------------------------*/

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

#if defined( portUSE_WDTO )

Expand Down Expand Up @@ -121,26 +121,26 @@ void wdt_interrupt_enable (const uint8_t value)

/*-----------------------------------------------------------*/
/**
Enable the watchdog timer, configuring it for expire after
(value) timeout (which is a combination of the WDP0
through WDP3 bits).
This function is derived from <avr/wdt.h> but enables both
the reset bit (WDE), and the interrupt bit (WDIE).
This will ensure that if the interrupt is not serviced
before the second timeout, the AVR will reset.
Servicing the interrupt automatically clears it,
and ensures the AVR does not reset.
Can't find it documented but the WDT, once enabled,
rolls over and fires a new interrupt each time.
See also the symbolic constants WDTO_15MS et al.
Updated to match avr-libc 2.0.0
*/
* Enable the watchdog timer, configuring it for expire after
* (value) timeout (which is a combination of the WDP0
* through WDP3 bits).
*
* This function is derived from <avr/wdt.h> but enables both
* the reset bit (WDE), and the interrupt bit (WDIE).
*
* This will ensure that if the interrupt is not serviced
* before the second timeout, the AVR will reset.
*
* Servicing the interrupt automatically clears it,
* and ensures the AVR does not reset.
*
* Can't find it documented but the WDT, once enabled,
* rolls over and fires a new interrupt each time.
*
* See also the symbolic constants WDTO_15MS et al.
*
* Updated to match avr-libc 2.0.0
*/

#if defined( portUSE_WDTO )

Expand Down Expand Up @@ -551,10 +551,11 @@ uint16_t usAddress;
#endif

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

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

/* Should not get here. */
Expand All @@ -622,15 +623,15 @@ void vPortEndScheduler( void )
}
/*-----------------------------------------------------------*/

/*
* Choose which delay function to use.
* Arduino delay() is a millisecond granularity busy wait, that
* that breaks FreeRTOS. So its use is limited to less than one
* System Tick (portTICK_PERIOD_MS milliseconds).
* FreeRTOS vTaskDelay() is relies on the System Tick which here
* has a granularity of portTICK_PERIOD_MS milliseconds (15ms),
* with the remainder implemented as an Arduino delay().
*/
/*
* Choose which delay function to use.
* Arduino delay() is a millisecond granularity busy wait, that
* that breaks FreeRTOS. So its use is limited to less than one
* System Tick (portTICK_PERIOD_MS milliseconds).
* FreeRTOS vTaskDelay() is relies on the System Tick which here
* has a granularity of portTICK_PERIOD_MS milliseconds (15ms),
* with the remainder implemented as an Arduino delay().
*/

#ifdef delay
#undef delay
Expand All @@ -639,7 +640,7 @@ void vPortEndScheduler( void )
extern void delay ( unsigned long ms );

#if defined( portUSE_WDTO )
void vPortDelay( const uint32_t ms ) __attribute__ ((hot, flatten));
void vPortDelay( const uint32_t ms ) __attribute__ ( ( hot, flatten ) );
void vPortDelay( const uint32_t ms )
{
if ( ms < portTICK_PERIOD_MS )
Expand All @@ -655,15 +656,15 @@ void vPortDelay( const uint32_t ms )
#else
#warning "The user is responsible to provide function `vPortDelay()`"
#warning "Arduino uses all AVR MCU Timers, so breakage may occur"
extern void vPortDelay( const uint32_t ms ) __attribute__ ((hot, flatten));
extern void vPortDelay( const uint32_t ms ) __attribute__ ( ( hot, flatten ) );
#endif
/*-----------------------------------------------------------*/

/*
* Manual context switch. The first thing we do is save the registers so we
* can use a naked attribute.
*/
void vPortYield( void ) __attribute__ ((hot, flatten, naked));
void vPortYield( void ) __attribute__( ( hot, flatten, naked ) );
void vPortYield( void )
{
portSAVE_CONTEXT();
Expand All @@ -678,7 +679,7 @@ void vPortYield( void )
* Manual context switch callable from ISRs. The first thing we do is save
* the registers so we can use a naked attribute.
*/
void vPortYieldFromISR( void ) __attribute__ ((hot, flatten, naked));
void vPortYieldFromISR( void ) __attribute__( ( hot, flatten, naked ) );
void vPortYieldFromISR( void )
{
portSAVE_CONTEXT();
Expand All @@ -695,7 +696,7 @@ void vPortYieldFromISR( void )
* difference from vPortYield() is the tick count is incremented as the
* call comes from the tick ISR.
*/
void vPortYieldFromTick( void ) __attribute__ ((hot, flatten, naked));
void vPortYieldFromTick( void ) __attribute__( ( hot, flatten, naked ) );
void vPortYieldFromTick( void )
{
portSAVE_CONTEXT();
Expand All @@ -704,28 +705,30 @@ void vPortYieldFromTick( void )
{
vTaskSwitchContext();
}

portRESTORE_CONTEXT();

__asm__ __volatile__ ( "ret" );
}
/*-----------------------------------------------------------*/

#if defined( portUSE_WDTO )
/*
* Setup WDT to generate a tick interrupt.
*/
void prvSetupTimerInterrupt( void )
{
/* reset watchdog */
wdt_reset();

/* set up WDT Interrupt (rather than the WDT Reset). */
wdt_interrupt_enable( portUSE_WDTO );
}
/*
* Setup WDT to generate a tick interrupt.
*/
void prvSetupTimerInterrupt( void )
{
/* reset watchdog */
wdt_reset();

/* set up WDT Interrupt (rather than the WDT Reset). */
wdt_interrupt_enable( portUSE_WDTO );
}

#else
#warning "The user is responsible to provide function `prvSetupTimerInterrupt()`"
extern void prvSetupTimerInterrupt( void );
#warning "The user is responsible to provide function `prvSetupTimerInterrupt()`"
extern void prvSetupTimerInterrupt( void );
#endif

/*-----------------------------------------------------------*/
Expand All @@ -740,15 +743,16 @@ extern void prvSetupTimerInterrupt( void );
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
*
*/
ISR(portSCHEDULER_ISR, ISR_NAKED) __attribute__ ((hot, flatten));
/* ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten));
*/
ISR(portSCHEDULER_ISR)
ISR( portSCHEDULER_ISR, ISR_NAKED ) __attribute__( ( hot, flatten ) );

/* ISR(portSCHEDULER_ISR, ISR_NAKED ISR_NOBLOCK) __attribute__ ((hot, flatten));
*/
ISR( portSCHEDULER_ISR )
{
vPortYieldFromTick();
__asm__ __volatile__ ( "reti" );
}
#else
#else /* if configUSE_PREEMPTION == 1 */

/*
* Tick ISR for the cooperative scheduler. All this does is increment the
Expand All @@ -757,11 +761,12 @@ extern void prvSetupTimerInterrupt( void );
*
* use ISR_NOBLOCK where there is an important timer running, that should preempt the scheduler.
*/
ISR(portSCHEDULER_ISR) __attribute__ ((hot, flatten));
/* ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten));
*/
ISR(portSCHEDULER_ISR)
ISR( portSCHEDULER_ISR ) __attribute__( ( hot, flatten ) );

/* ISR(portSCHEDULER_ISR, ISR_NOBLOCK) __attribute__ ((hot, flatten));
*/
ISR( portSCHEDULER_ISR )
{
xTaskIncrementTick();
}
#endif
#endif /* if configUSE_PREEMPTION == 1 */
Loading

0 comments on commit a2673db

Please sign in to comment.