27
27
28
28
29
29
#include <stdlib.h>
30
+
31
+ #include <avr/io.h>
30
32
#include <avr/interrupt.h>
31
33
#include <avr/wdt.h>
32
34
@@ -524,17 +526,6 @@ static void prvSetupTimerInterrupt( void );
524
526
StackType_t * pxPortInitialiseStack ( StackType_t * pxTopOfStack , TaskFunction_t pxCode , void * pvParameters )
525
527
{
526
528
uint16_t usAddress ;
527
-
528
- /* Place a few bytes of known values on the bottom of the stack.
529
- This is just useful for debugging. */
530
-
531
- * pxTopOfStack = 0x11 ;
532
- pxTopOfStack -- ;
533
- * pxTopOfStack = 0x22 ;
534
- pxTopOfStack -- ;
535
- * pxTopOfStack = 0x33 ;
536
- pxTopOfStack -- ;
537
-
538
529
/* Simulate how the stack would look after a call to vPortYield() generated by
539
530
the compiler. */
540
531
@@ -590,51 +581,9 @@ uint16_t usAddress;
590
581
591
582
/* Now the remaining registers. The compiler expects R1 to be 0. */
592
583
* pxTopOfStack = ( StackType_t ) 0x00 ; /* R1 */
593
- pxTopOfStack -- ;
594
- * pxTopOfStack = ( StackType_t ) 0x02 ; /* R2 */
595
- pxTopOfStack -- ;
596
- * pxTopOfStack = ( StackType_t ) 0x03 ; /* R3 */
597
- pxTopOfStack -- ;
598
- * pxTopOfStack = ( StackType_t ) 0x04 ; /* R4 */
599
- pxTopOfStack -- ;
600
- * pxTopOfStack = ( StackType_t ) 0x05 ; /* R5 */
601
- pxTopOfStack -- ;
602
- * pxTopOfStack = ( StackType_t ) 0x06 ; /* R6 */
603
- pxTopOfStack -- ;
604
- * pxTopOfStack = ( StackType_t ) 0x07 ; /* R7 */
605
- pxTopOfStack -- ;
606
- * pxTopOfStack = ( StackType_t ) 0x08 ; /* R8 */
607
- pxTopOfStack -- ;
608
- * pxTopOfStack = ( StackType_t ) 0x09 ; /* R9 */
609
- pxTopOfStack -- ;
610
- * pxTopOfStack = ( StackType_t ) 0x10 ; /* R10 */
611
- pxTopOfStack -- ;
612
- * pxTopOfStack = ( StackType_t ) 0x11 ; /* R11 */
613
- pxTopOfStack -- ;
614
- * pxTopOfStack = ( StackType_t ) 0x12 ; /* R12 */
615
- pxTopOfStack -- ;
616
- * pxTopOfStack = ( StackType_t ) 0x13 ; /* R13 */
617
- pxTopOfStack -- ;
618
- * pxTopOfStack = ( StackType_t ) 0x14 ; /* R14 */
619
- pxTopOfStack -- ;
620
- * pxTopOfStack = ( StackType_t ) 0x15 ; /* R15 */
621
- pxTopOfStack -- ;
622
- * pxTopOfStack = ( StackType_t ) 0x16 ; /* R16 */
623
- pxTopOfStack -- ;
624
- * pxTopOfStack = ( StackType_t ) 0x17 ; /* R17 */
625
- pxTopOfStack -- ;
626
- * pxTopOfStack = ( StackType_t ) 0x18 ; /* R18 */
627
- pxTopOfStack -- ;
628
- * pxTopOfStack = ( StackType_t ) 0x19 ; /* R19 */
629
- pxTopOfStack -- ;
630
- * pxTopOfStack = ( StackType_t ) 0x20 ; /* R20 */
631
- pxTopOfStack -- ;
632
- * pxTopOfStack = ( StackType_t ) 0x21 ; /* R21 */
633
- pxTopOfStack -- ;
634
- * pxTopOfStack = ( StackType_t ) 0x22 ; /* R22 */
635
- pxTopOfStack -- ;
636
- * pxTopOfStack = ( StackType_t ) 0x23 ; /* R23 */
637
- pxTopOfStack -- ;
584
+
585
+ /* Leave R2 - R23 untouched */
586
+ pxTopOfStack -= 23 ;
638
587
639
588
/* Place the parameter on the stack in the expected location. */
640
589
usAddress = ( uint16_t ) pvParameters ;
@@ -643,20 +592,9 @@ uint16_t usAddress;
643
592
644
593
usAddress >>= 8 ;
645
594
* pxTopOfStack = ( StackType_t ) ( usAddress & ( uint16_t ) 0x00ff );
646
- pxTopOfStack -- ;
647
595
648
- * pxTopOfStack = ( StackType_t ) 0x26 ; /* R26 X */
649
- pxTopOfStack -- ;
650
- * pxTopOfStack = ( StackType_t ) 0x27 ; /* R27 */
651
- pxTopOfStack -- ;
652
- * pxTopOfStack = ( StackType_t ) 0x28 ; /* R28 Y */
653
- pxTopOfStack -- ;
654
- * pxTopOfStack = ( StackType_t ) 0x29 ; /* R29 */
655
- pxTopOfStack -- ;
656
- * pxTopOfStack = ( StackType_t ) 0x30 ; /* R30 Z */
657
- pxTopOfStack -- ;
658
- * pxTopOfStack = ( StackType_t ) 0x031 ; /* R31 */
659
- pxTopOfStack -- ;
596
+ /* Leave register R26 - R31 untouched */
597
+ pxTopOfStack -= 7 ;
660
598
661
599
return pxTopOfStack ;
662
600
}
@@ -709,6 +647,21 @@ void vPortYield( void )
709
647
}
710
648
/*-----------------------------------------------------------*/
711
649
650
+ /*
651
+ * Manual context switch callable from ISRs. The first thing we do is save
652
+ * the registers so we can use a naked attribute.
653
+ */
654
+ void vPortYieldFromISR (void ) __attribute__ ( ( hot , flatten , naked ) );
655
+ void vPortYieldFromISR (void )
656
+ {
657
+ portSAVE_CONTEXT ();
658
+ vTaskSwitchContext ();
659
+ portRESTORE_CONTEXT ();
660
+
661
+ __asm__ __volatile__ ( "reti" );
662
+ }
663
+ /*-----------------------------------------------------------*/
664
+
712
665
/*
713
666
* Context switch function used by the tick. This must be identical to
714
667
* vPortYield() from the call to vTaskSwitchContext() onwards. The only
@@ -725,7 +678,7 @@ void vPortYieldFromTick( void )
725
678
}
726
679
portRESTORE_CONTEXT ();
727
680
728
- __asm__ __volatile__ ( "ret " );
681
+ __asm__ __volatile__ ( "reti " );
729
682
}
730
683
/*-----------------------------------------------------------*/
731
684
@@ -776,7 +729,6 @@ uint8_t ucLowByte;
776
729
ucLowByte = portTIMSK ;
777
730
ucLowByte |= portCOMPARE_MATCH_A_INTERRUPT_ENABLE ;
778
731
portTIMSK = ucLowByte ;
779
-
780
732
}
781
733
782
734
#endif
@@ -799,7 +751,6 @@ uint8_t ucLowByte;
799
751
ISR (portSCHEDULER_ISR )
800
752
{
801
753
vPortYieldFromTick ();
802
- __asm__ __volatile__ ( "reti" );
803
754
}
804
755
#else
805
756
0 commit comments