]> rtime.felk.cvut.cz Git - arc.git/commitdiff
Merged in from jonte-1
authortojo <tobias.johansson@arccore.com>
Mon, 22 Nov 2010 13:29:44 +0000 (14:29 +0100)
committertojo <tobias.johansson@arccore.com>
Mon, 22 Nov 2010 13:29:44 +0000 (14:29 +0100)
21 files changed:
arch/arm/arm_cm3/drivers/Dio.c
arch/arm/arm_cm3/kernel/arch_krn.sx
arch/arm/arm_cm3/kernel/core_cm3.h
arch/arm/arm_cm3/kernel/irq.c
arch/arm/arm_cm3/kernel/startup_stm32f10x.s
arch/arm/arm_cm3/kernel/sys_tick.c
arch/arm/arm_cm3/scripts/linkscript_gcc.ldf
boards/board_common.mk
boards/stm32_stm3210c/build_config.mk
boards/stm32_stm3210c/config/Dio_Cfg.h
boards/stm32_stm3210c/config/Port_Cfg.c
common/cirq_buffer.c
common/tcf/streams.c
common/tcf/sys_monitor.c
common/tcf/tcf.c
common/tcf/tcf.h
include/arm/stm32f10x.h
include/cirq_buffer.h
include/sleep.h
system/kernel/include/internal.h
system/kernel/isr.c

index 44757c9c2b55a22c8035757b6a659c5479910e16..9acbd90e3e2b97a8dcde0f44c360b8446f83b6ec 100644 (file)
@@ -200,11 +200,4 @@ void Dio_WriteChannelGroup(const Dio_ChannelGroupType *channelGroupIdPtr,
        cleanup: return;\r
 }\r
 \r
-#if (DIO_VERSION_INFO_API == STD_ON)\r
-void Dio_GetVersionInfo(Std_VersionInfoType *versionInfo)\r
-{\r
-  memcpy(versionInfo, &_Dio_VersionInfo, sizeof(Std_VersionInfoType));\r
-}\r
-#endif\r
-\r
 \r
index 2a82bd89b415d25826338f0e9688ebca869a2680..c9103fd39b2671d649bcda7132c015b7ad4b439b 100644 (file)
@@ -11,6 +11,7 @@
 #include "stack.h"\r
 \r
 .extern os_sys\r
+.extern TailChaining\r
 \r
        .syntax unified\r
        .cpu cortex-m3\r
 \r
        .global Irq_Handler\r
     .type      Irq_Handler, %function\r
+       .global SVC_Handler\r
+    .type      SVC_Handler, %function\r
+       .global PendSV_Handler\r
+    .type      PendSV_Handler, %function\r
 \r
 #define IRQ_ENABLE()           cpsie   i\r
 #define IRQ_DISABLE()          cpsid   i\r
 // lr\r
 #define REG_SAVE r4-r8,r10,r11\r
 \r
+SVC_Handler: \r
+    add     sp,sp,#(8*4)    /* remove one interrupt frame from the stack */\r
+    bx      lr              /* return to the preempted task */\r
 \r
-Irq_Handler:\r
+PendSV_Handler:\r
+    IRQ_DISABLE()\r
+    push    {REG_SAVE,lr}\r
+    sub.w   sp,sp,#C_SIZE\r
+    mov.w   r4,#LC_PATTERN\r
+    str     r4,[sp,#C_CONTEXT_OFFS]    \r
+    mov        r2,sp                   // stack as first arg\r
+\r
+       mov     r1,#0x01000000  // make up a task xPSR that has only the T bit set \r
+       ldr     r0,=TailChaining   // load the address of scheduler wrapper (new PC) \r
+       push    {r0-r1}         // push xPSR,PC \r
+       sub     sp,sp,#(5*4)    // don't care for lr,r12,r3,r2,r1\r
+    push    {r2}            // stack as first arg\r
+       bx      lr              // interrupt return to the scheduler wrapper\r
\r
+Irq_Handler:        \r
     push    {REG_SAVE,lr}\r
     sub.w   sp,sp,#C_SIZE\r
     mov.w   r4,#LC_PATTERN\r
     str     r4,[sp,#C_CONTEXT_OFFS]    \r
     mov        r0,sp                   // stack as first arg\r
-    \r
-// When at interrupt nest count = 0, load interrupt stack    \r
+\r
+    // When at interrupt nest count = 0, load interrupt stack    \r
        ldr      r4,=os_sys\r
        ldr      r5,[r4,#SYS_INT_NEST_CNT]\r
        cmp      r5, #0\r
-       bgt      arggg\r
-    \r
-       ldr      sp,[r4,#SYS_INT_STACK]   \r
-      \r
+       bgt      arggg  \r
+       ldr      sp,[r4,#SYS_INT_STACK]         \r
 arggg:  \r
     bl      Irq_Entry\r
     mov     sp, r0                     // pop from returned stack\r
@@ -52,10 +73,7 @@ arggg:
        /* Do a normal exception return */\r
     add.w   sp,sp,#C_SIZE\r
     pop     {REG_SAVE,lr}\r
-    bx                 lr\r
-\r
-//    b                os_lc_restore\r
-       \r
+    bx                 lr      \r
        \r
 /**\r
  * Fake an interrupt stack to be able to return to thread mode.\r
@@ -167,7 +185,6 @@ os_stack_problem:
         */\r
 os_sc_restore:\r
     add.w   sp,sp,#C_SIZE\r
-\r
     pop     {REG_SAVE,lr}\r
     bx      lr\r
 \r
@@ -186,38 +203,9 @@ os_lc_restore:
     add.w   sp,sp,#C_SIZE\r
     /* Pop function stack (LR will be 0xffff_fff9 here, just ignore */\r
     pop     {REG_SAVE,lr}\r
-    \r
-    /* If we were in handler mode a "bx lr" would pop back all the registers\r
-     * that were automatically pushed by the CPU. Now we have to do this \r
-     * manually instead. \r
-     * The problem here is PSR since its not a register that we can pop\r
-     * back so we have to do it manually, use r0 as scratch */\r
-    \r
-    /* Grab stack xPSR and move to psr  */\r
-    /* TODO: Does this enable interrupts?? */\r
-    ldr         r0,[sp,#28]\r
-    msr         apsr,r0\r
-    \r
-    /* Update bit[0] of PC.\r
-     *\r
-     * From "3.3.1 STM32F10xxx Cortex-M3 programming manual"\r
-     * Bit[0] of any address written to the PC with a BX, BLX, LDM, LDR, or POP instruction must\r
-     * be 1 for correct execution, because this bit indicates the required instruction set, and the\r
-     * Cortex-M3 processor only supports thumb instructions. */\r
-    ldr r0,[sp,#24]\r
-    orr r0,r0,#1\r
-    str r0,[sp,#24]\r
-    \r
-    /* Pop part of the exception stack */\r
-    pop {r0-r3,r12,lr}\r
-    \r
-    add.w      sp,sp,#(2*4)    /* Adjust for xPSR and PC */\r
-       /* We do return directly to the preempted task here, so enable interrupts */\r
-    cpsie      i                       /* Enable interrupts */\r
+    IRQ_ENABLE()       /* Enable interrupts to allow svc */\r
+    svc 0              /* cause exception to return to the preempted task */\r
 \r
-    /* Jump to PC from PC on stack (the branch value on the stack must be + 1 to\r
-     * stay in thumb mode) */\r
-    ldr                pc,[sp,#-8]\r
 \r
     \r
 \r
index f4eae74e9661c135a527fe23a8e5c95482ca3148..5dafaf2661aab7ffcf7c22ad85cb95856c7a0a62 100644 (file)
@@ -1184,10 +1184,12 @@ static __INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
  */\r
 static __INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)\r
 {\r
+  uint32_t prio = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);\r
+\r
   if(IRQn < 0) {\r
-    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M3 System Interrupts */\r
+    SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = prio; } /* set Priority for Cortex-M3 System Interrupts */\r
   else {\r
-    NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff);    }        /* set Priority for device specific Interrupts      */\r
+    NVIC->IP[(uint32_t)(IRQn)] = prio;    }        /* set Priority for device specific Interrupts      */\r
 }\r
 \r
 /**\r
@@ -1302,7 +1304,7 @@ static __INLINE uint32_t SysTick_Config(uint32_t ticks)
   if (ticks > SYSTICK_MAXCOUNT)  return (1);                                             /* Reload value impossible */\r
 \r
   SysTick->LOAD  =  (ticks & SYSTICK_MAXCOUNT) - 1;                                      /* set reload register */\r
-  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);                            /* set Priority for Cortex-M0 System Interrupts */\r
+  //NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);                            /* set Priority for Cortex-M0 System Interrupts */\r
   SysTick->VAL   =  (0x00);                                                              /* Load the SysTick Counter Value */\r
   SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); /* Enable SysTick IRQ and SysTick Timer */\r
   return (0);                                                                            /* Function successful */\r
index be48879f624c68566f7c7e24367170ce0287427f..67dcad999d6493fdbf3b35476a3ff891aeecae9b 100644 (file)
 
 extern void *Irq_VectorTable[NUMBER_OF_INTERRUPTS_AND_EXCEPTIONS];
 
-/*
-* PRIGROUP[2:0]        Group prios     Sub prios
-* 0b011                        16                              None
-* 0b100                        8                               2
-* 0b101                        4                               4
-* 0b110                        2                               8
-* 0b111                        None                    16
-*/
-#define AIRCR_VECTKEY    ((uint32_t)0x05FA0000)
-
-/** Set NVIC prio group */
-static void NVIC_SetPrioGroup(uint32_t prioGroup)
+/**
+ * Init NVIC vector. We do not use subpriority
+ *
+ * @param vector       The IRQ number
+ * @param prio      NVIC priority, 0-31, 0-high prio
+ */
+static void NVIC_InitVector(IRQn_Type vector, uint32_t prio)
 {
-  SCB->AIRCR = AIRCR_VECTKEY | (prioGroup<<8);
+       // Set prio
+       NVIC_SetPriority(vector,prio);
+
+       // Enable
+    NVIC->ISER[vector >> 5] = (uint32_t)1 << (vector & (uint8_t)0x1F);
 }
 
+/*
+PRIGROUP
+0                      7.1 indicates seven bits of pre-emption priority, one bit of subpriority
+1                      6.2 indicates six bits of pre-emption priority, two bits of subpriority
+2                      5.3 indicates five bits of pre-emption priority, three bits of subpriority
+3                      4.4 indicates four bits of pre-emption priority, four bits of subpriority
+4                      3.5 indicates three bits of pre-emption priority, five bits of subpriority
+5                      2.6 indicates two bits of pre-emption priority, six bits of subpriority
+6                      1.7 indicates one bit of pre-emption priority, seven bits of subpriority
+7                      0.8 indicates no pre-emption priority, eight bits of subpriority.
+*/
 void Irq_Init( void ) {
-       NVIC_SetPrioGroup(3); // No sub prioritys
+       NVIC_SetPriorityGrouping(0);
+       NVIC_SetPriority(SVCall_IRQn, 0xff); // Set lowest prio
+       NVIC_SetPriority(PendSV_IRQn, 0xff); // Set lowest prio
+
+       /* Stop counters and watchdogs when halting in debug */
+       DBGMCU->CR |= 0x00ffffff00;
 }
 
 void Irq_EOI( void ) {
@@ -64,27 +79,6 @@ static uint32_t NVIC_GetActiveVector( void) {
        return (SCB->ICSR &  ICSR_VECTACTIVE);
 }
 
-/**
- * Init NVIC vector. We do not use subriority
- *
- */
-
-/**
- * Init NVIC vector. We do not use subpriority
- *
- * @param vector       The IRQ number
- * @param prio      NVIC priority, 0-15, 0-high prio
- */
-static void NVIC_InitVector(IRQn_Type vector, uint32_t prio)
-{
-       // Set prio
-       NVIC_SetPriority(vector,prio);
-       //NVIC->IP[vector] = prio;
-
-       // Enable
-       //NVIC_EnableIRQ(vector);
-    NVIC->ISER[vector >> 5] = (uint32_t)1 << (vector & (uint8_t)0x1F);
-}
 
 /**
  *
@@ -93,13 +87,10 @@ static void NVIC_InitVector(IRQn_Type vector, uint32_t prio)
  * The stack holds C, NVGPR, VGPR and the EXC frame.
  *
  */
-void *Irq_Entry( void *stack_p )
-{
+void *Irq_Entry( void *stack_p ){
        uint32_t vector = 0;
-       uint32_t *stack;
 
        Irq_Disable();
-       stack = (uint32_t *)stack_p;
 
        /* 0. Set the default handler here....
         * 1. Grab the vector from the interrupt controller
@@ -111,9 +102,10 @@ void *Irq_Entry( void *stack_p )
 
        vector = NVIC_GetActiveVector();
 
-       stack = Os_Isr(stack, (void *)Irq_VectorTable[vector]);
+       Os_Isr_cm3((void *)Irq_VectorTable[vector]);
        Irq_Enable();
-       return stack;
+
+       return stack_p;
 }
 
 /**
@@ -130,22 +122,22 @@ void Irq_AttachIsr1( void (*entry)(void), void *int_ctrl, uint32_t vector, uint8
 }
 
 /**
- * NVIC prio have priority 0-15, 0-highest priority.
+ * NVIC prio have priority 0-31, 0-highest priority.
  * Autosar does it the other way around, 0-Lowest priority
+ * NOTE: prio 255 is reserved for SVC and PendSV
  *
  * Autosar    NVIC
  *   31        0
- *   30        0
+ *   30        1
  *   ..
- *   0         15
- *   0         15
+ *   0         31
  * @param prio
  * @return
  */
 static inline int osPrioToCpuPio( uint8_t prio ) {
        assert(prio<32);
        prio = 31 - prio;
-       return (prio>>1);
+       return prio;
 }
 
 /**
index e64ced1e7f9ca0265edc27b308308df7ef87a447..923057b6de7b8b59d9410a32dafb5282f61ef96c 100644 (file)
@@ -93,6 +93,8 @@ Infinite_Loop:
        .size   g_pfnVectors, .-g_pfnVectors\r
 \r
        .extern Irq_Handler\r
+       .extern SVC_Handler\r
+       .extern PendSV_Handler\r
 \r
        .word   _estack\r
        .word   Reset_Handler\r
index 553ef61cce4e52d67c618393898d1b088f30d150..b600dd245e1075fdf4de64d1048abb7fd90b733e 100644 (file)
@@ -45,9 +45,6 @@ void Os_SysTickStart(uint32_t period_ticks) {
 \r
        SysTick_Config(period_ticks);\r
 \r
-        /* Set SysTick Priority to 3 */\r
-       NVIC_SetPriority(SysTick_IRQn, 0x0C);\r
-\r
 #if 0\r
        // SysTick interrupt each 250ms with counter clock equal to 9MHz\r
        if (SysTick_Config((SystemFrequency / 8) / 4)) {\r
index 0a937c3adabda71d5bb5b9b4dd3273b879b9aba0..146db2c5e6524e587b66197e4b49e088fe6b88c4 100644 (file)
@@ -31,6 +31,7 @@ SECTIONS
 \r
     .text :\r
        {\r
+        . = ALIGN(4);\r
        *(.text .text.* );\r
        *(.glue_7)              /* TODO */\r
        *(.glue_7t)     /* TODO */\r
@@ -41,6 +42,7 @@ SECTIONS
        SORT(*)(.test_etask);\r
        \r
        /* ST/ARM special variable to initialize .data */\r
+           . = ALIGN(4);\r
        _etext = .;\r
        } > flash\r
 \r
@@ -61,20 +63,27 @@ SECTIONS
 \r
        /* Read-only data section. */\r
        .rodata :       { \r
+           . = ALIGN(4);\r
                *(.rodata .rodata.* .gnu.linkonce.r.*)\r
+           . = ALIGN(4);\r
                _sidata = .;\r
        } > flash\r
 \r
-       .data : AT(ALIGN(LOADADDR(.rodata)+SIZEOF(.rodata),4)) {\r
+       .data : AT ( _sidata )\r
+       {\r
+           . = ALIGN(4);\r
                _sdata = .; \r
                *(.data .data.* .gnu.linkonce.d.* .gnu.linkonce.r.* .eh_frame)\r
+           . = ALIGN(4);\r
                _edata = .;             \r
        } > ram\r
 \r
        .t32_outport ALIGN(0x10): { *(.t32_outport); } > ram\r
        .bss : {\r
+           . = ALIGN(4);\r
                _sbss = ., \r
                *(.bss .bss.* COMMON .gnu.linkonce.b.*);\r
+           . = ALIGN(4);\r
                _ebss = .; \r
        }       > ram\r
        \r
index d2c18ec93f93bd797d8df0274af8f94f804452bd..2c3c8acb29efcf56e83164e2e6866ef7b39f9e1a 100644 (file)
@@ -198,6 +198,10 @@ obj-$(USE_TCF) += streams.o
 inc-$(USE_TCF) += $(ROOTDIR)/common/tcf\r
 vpath-$(USE_TCF) += $(ROOTDIR)/common/tcf\r
 \r
+#SLEEP\r
+obj-$(USE_SLEEP) += sleep.o\r
+\r
+\r
 # Newlib overrides (overridden by default)\r
 ifneq ($(CFG_STANDARD_NEWLIB),y)\r
 obj-y += xtoa.o\r
index 88bcede3771db22ac5db6975acc9a32ab787899c..d221a668a9d72a8ce2c0cb1fcf78542a7b7d9fd6 100644 (file)
@@ -29,7 +29,7 @@ MOD_AVAIL+=ADC CAN DIO MCU FLS PORT PWM
 # System + Communication + Diagnostic\r
 MOD_AVAIL+=CANIF CANTP COM DCM DEM DET ECUM IOHWAB KERNEL PDUR WDGM RTE\r
 # Additional\r
-MOD_AVAIL+=RAMLOG TCF LWIP\r
+MOD_AVAIL+=RAMLOG TCF LWIP SLEEP RTE\r
 \r
 #\r
 # Extra defines \r
index c2cfaa643905a4c78fc7267b1bd5a2a5d56f4191..eea16368e1e4310f5f78c1dc81f0939b97e82e42 100644 (file)
@@ -131,7 +131,7 @@ typedef enum
         DIO_CHANNEL_F14,\r
         DIO_CHANNEL_F15,\r
 \r
-} Dio_ChannelType;\r
+} Dio_Hw_ChannelType;\r
 //@}\r
 \r
 /** HW specific DIO port definitions. */\r
@@ -144,22 +144,7 @@ typedef enum {
        DIO_PORT_D,\r
        DIO_PORT_E,\r
        DIO_PORT_F,\r
-} Dio_PortType;\r
-\r
-/** @req DIO021 */\r
-/** @req DIO022 */\r
-typedef struct\r
-{\r
-  Dio_PortType port;\r
-  uint16 offset;\r
-  uint16 mask;\r
-} Dio_ChannelGroupType;\r
-\r
-/** @req DIO023 */\r
-typedef uint16 Dio_LevelType;\r
-\r
-/** @req DIO024 */\r
-typedef uint16 Dio_PortLevelType;\r
+} Dio_Hw_PortType;\r
 \r
 #define LED_CHANNEL1 (DIO_CHANNEL_D3)\r
 #define LED_CHANNEL2 (DIO_CHANNEL_D4)\r
index be5978065341f33a95904562a0fbc7f16813433f..11b90b86920f53011f7fcf9a1051a2a303a0e9d8 100644 (file)
@@ -27,6 +27,7 @@ typedef enum {
 const u32 remaps[] = {\r
                GPIO_Remap_ETH,\r
                GPIO_Remap2_CAN1,\r
+               GPIO_Remap_CAN2,\r
 };\r
 \r
 const Port_PortConfigType porta = {\r
@@ -53,13 +54,25 @@ const Port_PortConfigType porta = {
 \r
 const Port_PortConfigType portb = {\r
   .port = GPIOB,\r
-  .pinCount = 2,\r
+  .pinCount = 4,\r
   .pins = {\r
        {\r
-         .GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13,\r
+         .GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13,\r
          .GPIO_Mode = GPIO_Mode_AF_PP,\r
          .GPIO_Speed = GPIO_Speed_50MHz\r
        },\r
+       /* PB5 is CAN2_RX, remapped: */\r
+       {\r
+         .GPIO_Pin = GPIO_Pin_5,\r
+         .GPIO_Mode = GPIO_Mode_IPU,\r
+         .GPIO_Speed = GPIO_Speed_10MHz\r
+       },\r
+       /* PB6 is CAN2_TX, remapped: */\r
+       {\r
+         .GPIO_Pin = GPIO_Pin_6,\r
+         .GPIO_Mode = GPIO_Mode_AF_PP,\r
+         .GPIO_Speed = GPIO_Speed_10MHz\r
+       },\r
        {\r
          .GPIO_Pin = GPIO_Pin_10,\r
          .GPIO_Mode = GPIO_Mode_IN_FLOATING,\r
index 8c13a80e240b33fda2772d924bb17846224374ea..179d6f111224b1bb3489a0bd78281c67b72f8cc0 100644 (file)
 
 /* TODO: Not threadsafe, add DisableAllInterrts()/EnableAllInterrupts() */
 
+CirqBufferType CirqBuffStatCreate(void *buffer, int maxCnt, size_t dataSize) {
+       CirqBufferType cirqbuffer;
+       cirqbuffer.bufStart = buffer;
+       cirqbuffer.maxCnt = maxCnt;
+       cirqbuffer.bufEnd = (char *)cirqbuffer.bufStart + dataSize*maxCnt;
+       cirqbuffer.head = cirqbuffer.bufStart;
+       cirqbuffer.tail = cirqbuffer.bufStart;
+       cirqbuffer.dataSize = dataSize;
+       cirqbuffer.currCnt = 0;
+       return cirqbuffer;
+}
 
-CirqBufferDynType *CirqBuffDynCreate( size_t size, size_t dataSize ) {
-       CirqBufferDynType *cPtr;
-       cPtr = malloc(sizeof(CirqBufferDynType));
+CirqBufferType *CirqBuffDynCreate( size_t size, size_t dataSize ) {
+       CirqBufferType *cPtr;
+       cPtr = malloc(sizeof(CirqBufferType));
        if( cPtr == NULL ) {
                return NULL;
        }
@@ -63,13 +74,15 @@ CirqBufferDynType *CirqBuffDynCreate( size_t size, size_t dataSize ) {
        return cPtr;
 }
 
-int CirqBuffDynDestroy(CirqBufferDynType *cPtr ) {
+
+
+int CirqBuffDynDestroy(CirqBufferType *cPtr ) {
        free(cPtr->bufStart);
        free(cPtr);
        return 0;
 }
 
-int CirqBuffDynPush( CirqBufferDynType *cPtr, void *dataPtr ) {
+int CirqBuffPush( CirqBufferType *cPtr, void *dataPtr ) {
        uint32_t flags;
        Irq_Save(flags);
        if( (cPtr->currCnt == cPtr->maxCnt) || (cPtr==NULL) ) {
@@ -87,7 +100,7 @@ int CirqBuffDynPush( CirqBufferDynType *cPtr, void *dataPtr ) {
        return 0;
 }
 
-int CirqBuffDynPop(CirqBufferDynType *cPtr, void *dataPtr ) {
+int CirqBuffPop(CirqBufferType *cPtr, void *dataPtr ) {
        uint32_t flags;
        Irq_Save(flags);
        if( (cPtr->currCnt == 0) || (cPtr==NULL) ) {
@@ -104,9 +117,11 @@ int CirqBuffDynPop(CirqBufferDynType *cPtr, void *dataPtr ) {
        return 0;
 }
 
+
+
 #ifdef _TEST_CIRQ_BUFFER_DYN_
 int main( void ) {
-       CirqBufferDynType *cPtr;
+       CirqBufferType *cPtr;
        uint8_t *dataPtr;
        int rv;
 
@@ -116,24 +131,24 @@ int main( void ) {
 
        dataPtr = malloc(DATA_SIZE);
        dataPtr[0] = 1;
-       rv  = CirqBuffDynPush(cPtr,dataPtr);
+       rv  = CirqBuffPush(cPtr,dataPtr);
        assert(rv == 0);
        free(dataPtr);
 
        dataPtr = malloc(DATA_SIZE);
        dataPtr[0] = 2;
-       rv  = CirqBuffDynPush(cPtr,dataPtr);
+       rv  = CirqBuffPush(cPtr,dataPtr);
        assert(rv == 0);
        free(dataPtr);
 
        dataPtr = malloc(DATA_SIZE);
-       rv = CirqBuffDynPop(cPtr,dataPtr);
+       rv = CirqBuffPop(cPtr,dataPtr);
        assert( dataPtr[0] == 1);
        assert(rv == 0);
        free(dataPtr);
 
        dataPtr = malloc(DATA_SIZE);
-       rv = CirqBuffDynPop(cPtr,dataPtr);
+       rv = CirqBuffPop(cPtr,dataPtr);
        assert( dataPtr[0] == 2);
        assert(rv == 0);
        free(dataPtr);
index 9723d15330ea6e53383b127a7ddfec755b66ad8b..08c6edbdcb7c0c712a3d85e9fa8e088bccbdf361 100644 (file)
@@ -122,8 +122,8 @@ static Std_ReturnType parse_id(char* msg, TCF_Streams_Command* command, uint16_t
        return E_OK;\r
 }\r
 \r
+char tmp_stream[200] = "";\r
 uint16_t handle_StreamsCommand(TCF_Command* command, char* buf) {\r
-       char tmp[200] = "";\r
        TCF_Streams_Command streams_cmd;\r
 \r
        /* Start building return message */\r
@@ -138,25 +138,28 @@ uint16_t handle_StreamsCommand(TCF_Command* command, char* buf) {
                }\r
 \r
                /* Add data field */\r
-               strcat(buf, JSON_Stringify);\r
-               int len = TCF_TTY_ReadString(tmp, 199);\r
-               tmp[len] = '\0'; /* Terminate to be sure */\r
-               strcat(buf, tmp);\r
-               strcat(buf, JSON_Stringify);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_Stringify);\r
+               int len = TCF_TTY_ReadString(tmp_stream, 199);\r
+        if(len >= 200){\r
+            return 0;\r
+        }\r
+               tmp_stream[len] = '\0'; /* Terminate to be sure */\r
+               mystrcat(buf, tmp_stream);\r
+               mystrcat(buf, JSON_Stringify);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
 \r
                /* Add error field */\r
-               strcat(buf, JSON_null);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_null);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
 \r
-               //strcat(buf, Streams_LostSize);\r
-               ultoa(0,tmp,10);\r
-               strcat(buf,tmp);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               //mystrcat(buf, Streams_LostSize);\r
+               ultoa(0,tmp_stream,10);\r
+               mystrcat(buf,tmp_stream);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
 \r
-               //strcat(buf, Streams_EOS);\r
-               strcat(buf, Streams_false);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               //mystrcat(buf, Streams_EOS);\r
+               mystrcat(buf, Streams_false);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
        } else if (strcmp(command->commandName, Streams_Write) == 0) {\r
                /* C \95 <token> \95 Streams \95 write \95 <string: stream ID> \95 <int: size> \95 <string: data> \95 */\r
                /* R \95 <token> \95 <error report> */\r
@@ -165,40 +168,40 @@ uint16_t handle_StreamsCommand(TCF_Command* command, char* buf) {
                }\r
 \r
                /* Add error field */\r
-               strcat(buf, JSON_null);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_null);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
        } else if (strcmp(command->commandName, Streams_Subscribe) == 0) {\r
                /* R \95 <token> \95 <error report> */\r
                if(parse_id(command->arguments,&streams_cmd,command->args_len) != E_OK){\r
                        return 0;\r
                }\r
                /* Add error field */\r
-               strcat(buf, JSON_null);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_null);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
        }else if (strcmp(command->commandName, Streams_Unsubscribe) == 0) {\r
                /* R \95 <token> \95 <error report> */\r
                if(parse_id(command->arguments,&streams_cmd,command->args_len) != E_OK){\r
                        return 0;\r
                }\r
                /* Add error field */\r
-               strcat(buf, JSON_null);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_null);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
        }else if (strcmp(command->commandName, Streams_Connect) == 0) {\r
                /* R \95 <token> \95 <error report> */\r
                if(parse_id(command->arguments,&streams_cmd,command->args_len) != E_OK){\r
                        return 0;\r
                }\r
                /* Add error field */\r
-               strcat(buf, JSON_null);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_null);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
        }else if (strcmp(command->commandName, Streams_Disconnect) == 0) {\r
                /* R \95 <token> \95 <error report> */\r
                if(parse_id(command->arguments,&streams_cmd,command->args_len) != E_OK){\r
                        return 0;\r
                }\r
                /* Add error field */\r
-               strcat(buf, JSON_null);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_null);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
        }\r
 \r
        convert_to_tcf_message(buf);\r
index 6bc5017ebe63f4c2c2dc62abaccfe1f4968dabf5..92b7368dc3cd54a9903051fbe27973b3d804230c 100644 (file)
@@ -31,19 +31,19 @@ static void AddState(char *buf, state_t state)
        switch(state)\r
        {\r
        case ST_READY:\r
-               strcat(buf,"\"D\"");\r
+               mystrcat(buf,"\"D\"");\r
                break;\r
        case ST_WAITING:\r
-               strcat(buf,"\"S\"");\r
+               mystrcat(buf,"\"S\"");\r
                break;\r
        case ST_SUSPENDED:\r
-               strcat(buf,"\"T\"");\r
+               mystrcat(buf,"\"T\"");\r
                break;\r
        case ST_RUNNING:\r
-               strcat(buf,"\"R\"");\r
+               mystrcat(buf,"\"R\"");\r
                break;\r
        case ST_NOT_STARTED:\r
-               strcat(buf,"\"T\"");\r
+               mystrcat(buf,"\"T\"");\r
                break;\r
        }\r
 }\r
@@ -64,33 +64,33 @@ uint16_t handle_SysMonCommand(TCF_Command* command, char* buf) {
                boolean first = TRUE;\r
 \r
                /* Add error field */\r
-               strcat(buf, JSON_null);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_null);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
 \r
                /* Add data field */\r
-               strcat(buf, JSON_ListStart);\r
+               mystrcat(buf, JSON_ListStart);\r
                TAILQ_FOREACH(iterPcbPtr,& os_sys.pcb_head,pcb_list) {\r
                        if(iterPcbPtr->proc_type < 4)\r
                        {\r
                                if(first){\r
                                        first = FALSE;\r
                                }else{\r
-                                       strcat(buf, JSON_Separator);\r
+                                       mystrcat(buf, JSON_Separator);\r
                                }\r
-                               strcat(buf, JSON_Stringify);\r
-                               strcat(buf, iterPcbPtr->name);\r
-                               strcat(buf, JSON_Stringify);\r
+                               mystrcat(buf, JSON_Stringify);\r
+                               mystrcat(buf, iterPcbPtr->name);\r
+                               mystrcat(buf, JSON_Stringify);\r
                        }\r
                }\r
-               strcat(buf, JSON_ListEnd);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_ListEnd);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
 \r
        } else if (strcmp(command->commandName, TCF_getContext) == 0) {\r
                char tmp[20] = "";\r
 \r
                /* Add error field */\r
-               strcat(buf, JSON_null);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_null);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
 \r
                /* Add data field */\r
                char *arg = command->arguments + 1; /* add 1 for " */\r
@@ -100,45 +100,45 @@ uint16_t handle_SysMonCommand(TCF_Command* command, char* buf) {
                                break;\r
                        }\r
                }\r
-               strcat(buf, JSON_ObjStart);\r
-           strcat(buf, TCF_ID);\r
-               strcat(buf, command->arguments);\r
+               mystrcat(buf, JSON_ObjStart);\r
+           mystrcat(buf, TCF_ID);\r
+               mystrcat(buf, command->arguments);\r
 \r
-               strcat(buf, JSON_Separator);\r
-               strcat(buf, TCF_File);\r
-               strcat(buf, command->arguments);\r
+               mystrcat(buf, JSON_Separator);\r
+               mystrcat(buf, TCF_File);\r
+               mystrcat(buf, command->arguments);\r
 \r
-               strcat(buf, JSON_Separator);\r
-               strcat(buf, SysMon_PID);\r
+               mystrcat(buf, JSON_Separator);\r
+               mystrcat(buf, SysMon_PID);\r
                ultoa(iterPcbPtr->pid,tmp,10);\r
-               strcat(buf, tmp);\r
+               mystrcat(buf, tmp);\r
 \r
-               strcat(buf, JSON_Separator);\r
-               strcat(buf, SysMon_Prio);\r
+               mystrcat(buf, JSON_Separator);\r
+               mystrcat(buf, SysMon_Prio);\r
                ultoa(iterPcbPtr->prio,tmp,10);\r
-               strcat(buf, tmp);\r
+               mystrcat(buf, tmp);\r
 \r
-               strcat(buf, JSON_Separator);\r
-               strcat(buf, SysMon_Stackstart);\r
+               mystrcat(buf, JSON_Separator);\r
+               mystrcat(buf, SysMon_Stackstart);\r
                ultoa((uint32_t)iterPcbPtr->stack.top,tmp,10);\r
-               strcat(buf, tmp);\r
+               mystrcat(buf, tmp);\r
 \r
-/*             strcat(buf, JSON_Separator);\r
-               strcat(buf, SysMon_Stackend);\r
+/*             mystrcat(buf, JSON_Separator);\r
+               mystrcat(buf, SysMon_Stackend);\r
                ultoa((uint32_t)iterPcbPtr->stack.top + iterPcbPtr->stack.size,tmp,10);\r
-               strcat(buf, tmp);\r
+               mystrcat(buf, tmp);\r
 \r
-               strcat(buf, JSON_Separator);\r
-               strcat(buf, SysMon_Stackcurr);\r
+               mystrcat(buf, JSON_Separator);\r
+               mystrcat(buf, SysMon_Stackcurr);\r
                ultoa((uint32_t)iterPcbPtr->stack.curr,tmp,10);\r
-               strcat(buf, tmp);\r
+               mystrcat(buf, tmp);\r
 */\r
-               strcat(buf, JSON_Separator);\r
-               strcat(buf, SysMon_State);\r
+               mystrcat(buf, JSON_Separator);\r
+               mystrcat(buf, SysMon_State);\r
                AddState(buf,iterPcbPtr->state);\r
 \r
-               strcat(buf, JSON_ObjEnd);\r
-               strcat(buf, TCF_S_EOFIELD_MARKER);\r
+               mystrcat(buf, JSON_ObjEnd);\r
+               mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
        }\r
 \r
        convert_to_tcf_message(buf);\r
index b01a21e06ac99aa906dea97cfdec5c10d12bd627..f40aca9b0d1722722547c316c2c78d9affa0573e 100644 (file)
@@ -45,6 +45,21 @@ struct tcf_tcp_state
     int num;\r
 };\r
 \r
+char *mystrcat(char *s1, const char *s2)\r
+{\r
+  char *s;\r
+\r
+  for(s = s1;*s;++s)\r
+    ;\r
+\r
+  while(*s2)\r
+    *s++ = *s2++;\r
+  *s = '\0';\r
+\r
+  return s1;\r
+}\r
+\r
+\r
 uint16_t message_length(const char* msg, uint16_t max_length) {\r
        uint16_t i;\r
        for (i = 0; i < max_length; ++i) {\r
@@ -57,16 +72,16 @@ uint16_t message_length(const char* msg, uint16_t max_length) {
 \r
 void start_tcf_field(char* start, char* field) {\r
        strcpy(start, field);\r
-       strcat(start, TCF_S_EOFIELD_MARKER);\r
+       mystrcat(start, TCF_S_EOFIELD_MARKER);\r
 }\r
 \r
 void append_tcf_field(char* start, char* field) {\r
-       strcat(start, field);\r
-       strcat(start, TCF_S_EOFIELD_MARKER);\r
+       mystrcat(start, field);\r
+       mystrcat(start, TCF_S_EOFIELD_MARKER);\r
 }\r
 \r
 void convert_to_tcf_message(char* start) {\r
-       strcat(start, TCF_S_EOM);\r
+       mystrcat(start, TCF_S_EOM);\r
        size_t length = strlen(start);\r
        int i;\r
        for (i = 0; i < length; ++i) {\r
@@ -164,18 +179,18 @@ uint16_t handle_FileSystemCommand(TCF_Command* command, char* buf) {
        append_tcf_field(buf, command->token);  /* Token */\r
 \r
        /* Add error field */\r
-       strcat(buf, JSON_ObjStart);\r
+       mystrcat(buf, JSON_ObjStart);\r
 \r
-       strcat(buf, TCF_Code);\r
+       mystrcat(buf, TCF_Code);\r
        ultoa(TCF_UNSUPPORTED,tmp,10);\r
-       strcat(buf, tmp);\r
+       mystrcat(buf, tmp);\r
 \r
-       strcat(buf, JSON_ObjEnd);\r
-       strcat(buf, TCF_S_EOFIELD_MARKER);\r
+       mystrcat(buf, JSON_ObjEnd);\r
+       mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
 \r
        /* Add data field */\r
-       strcat(buf, JSON_null);\r
-       strcat(buf, TCF_S_EOFIELD_MARKER);\r
+       mystrcat(buf, JSON_null);\r
+       mystrcat(buf, TCF_S_EOFIELD_MARKER);\r
 \r
        convert_to_tcf_message(buf);\r
        uint16_t len = message_length(buf, TCF_MAX_FIELD_LENGTH);\r
@@ -188,7 +203,7 @@ uint16_t handle_FileSystemEvent(TCF_Event* event, char* buf) {
 }\r
 \r
 /* Not reentrant so buffers can be static */\r
-static char outbuf[TCF_MAX_FIELD_LENGTH] = "";\r
+char outbuf[TCF_MAX_FIELD_LENGTH] = "";\r
 \r
 static void handle_event(char *buf, uint16_t len)\r
 {\r
@@ -250,18 +265,20 @@ static void handle_command(char *buf, uint16_t len)
 \r
 static void handle_incoming(const void* buf, uint16_t len) {\r
        char *msg = (char *)buf;\r
-\r
        if(len > 0){\r
                do{\r
-                       char c = msg[0];\r
-                       if (c == 'C') {\r
+                       if ((msg[0] == 'C') && (msg[1] == '\0')) {\r
                                handle_command(msg, len);\r
-                       } else if (c == 'E') {\r
+                       } else if ((msg[0] == 'E') && (msg[1] == '\0')) {\r
                                handle_event(msg, len);\r
-                       }\r
+                       }else{\r
+                len=0;\r
+            }\r
 \r
                        /* Check if more than one message in buffer */\r
-                       msg = get_next_tcf_msg(msg, &len);\r
+            if(len > 0){\r
+                msg = get_next_tcf_msg(msg, &len);\r
+            }\r
                }while((msg != NULL) && (len > 0));\r
        }\r
 }\r
index f77cbf8f194a6329b3dfc155dc7a98c36bb47736..a7e43c18e3c9e25b71c71806ed0c840a6b4d521f 100644 (file)
@@ -105,4 +105,6 @@ uint16_t handle_LocatorEvent(TCF_Event* event, char* buf);
 uint16_t handle_FileSystemCommand(TCF_Command* command, char* buf);\r
 uint16_t handle_FileSystemEvent(TCF_Event* event, char* buf);\r
 \r
+char *mystrcat(char *s1, const char *s2);\r
+\r
 #endif /* TCF_H_ */\r
index a2670e41a3377ccc6008ea51da3e4deb2eedf116..4644c759ebdcbe0050e0b14c53ffd2a45fe9e92a 100644 (file)
  * @brief Configuration of the Cortex-M3 Processor and Core Peripherals \r
  */\r
 #define __MPU_PRESENT             0 /*!< STM32 does not provide an MPU */\r
-#define __NVIC_PRIO_BITS          4 /*!< STM32 uses 4 Bits for the Priority Levels    */\r
+\r
+/* NOTE We use 7 bits preemption since 8 bits premtion isn't configurable */\r
+#define __NVIC_PRIO_BITS          7 /*!< STM32 uses 7 Bits for the Priority Levels    */\r
 #define __Vendor_SysTickConfig    0 /*!< Set to 1 if different SysTick Config is used */\r
 \r
 /**\r
index c4c0e093c5eeb8c1b2583d6a4dd81d0f3887d05e..9119fe3957fe7aea50380223b53c9257772f0dbb 100644 (file)
@@ -32,16 +32,16 @@ typedef struct {
        /* Buffer start/stop */
        void *bufStart;
        void *bufEnd;
-} CirqBufferDynType;
-
-CirqBufferDynType *CirqBuffDynCreate( size_t size, size_t dataSize );
-int CirqBuffDynDestroy(CirqBufferDynType *cPtr );
-int CirqBuffDynPush( CirqBufferDynType *cPtr, void *dataPtr );
-int CirqBuffDynPop(CirqBufferDynType *cPtr, void *dataPtr );
-
-/* TODO: Static implementation */
+} CirqBufferType;
 
+/* Dynamic implementation */
+CirqBufferType *CirqBuffDynCreate( size_t size, size_t dataSize );
+int CirqBuffDynDestroy(CirqBufferType *cPtr );
 
+/* Static implementation */
+CirqBufferType CirqBuffStatCreate(void *buffer, int maxCnt, size_t dataSize);
 
+int CirqBuffPush( CirqBufferType *cPtr, void *dataPtr );
+int CirqBuffPop(CirqBufferType *cPtr, void *dataPtr );
 
 #endif /* CIRQ_BUFFER_H_ */
index 0de279d4a14b22a7c2d96e0fd47af6ecc0d93ee6..3c0ecf5db4eec2469d509dbb61e99bf93be0fd3b 100644 (file)
 \r
 #define SLEEP(_x_) \\r
 do{ \\r
-       uint32_t pval = McuE_EnterCriticalSection(); \\r
        TaskType task; \\r
        GetTaskID(&task); \\r
-       Sleep(_x_, task, EVENT_MASK_EVENT_SLEEP_ALARM ); \\r
-    McuE_ExitCriticalSection(pval); \\r
-       WaitEvent(EVENT_MASK_EVENT_SLEEP_ALARM); \\r
-       ClearEvent(EVENT_MASK_EVENT_SLEEP_ALARM); \\r
+       Sleep(_x_, task, EVENT_MASK_SLEEP_ALARM ); \\r
+       WaitEvent(EVENT_MASK_SLEEP_ALARM); \\r
+       ClearEvent(EVENT_MASK_SLEEP_ALARM); \\r
 }while(0);\r
 \r
 void Sleep(uint32_t nofTicks, TaskType TaskID, EventMaskType Mask );\r
+void SleepInit();\r
 \r
 #endif /* SLEEP_H_ */\r
index 85479cc5e6dbc951c59c1f2deda01ed7d9dc2334..36ff57db7da53c20a909b2465a3388be2e662a4f 100644 (file)
@@ -280,6 +280,11 @@ void os_dispatch(void);
 \r
 void OsTick( void );\r
 \r
+#if defined(CFG_ARM_CM3)\r
+void Os_Isr_cm3( void *isr_p );\r
+void TailChaining(void *stack);\r
+#endif\r
+\r
 void *Os_Isr( void *stack, void *pcb_p );\r
 void Os_Dispatch( uint32_t op );\r
 \r
index 7a7560151ae0615f1f792bbca0b9f2c892f2fb62..1fcf30fec3f8e53c9a419ce4ddd0ef7063bb2652 100644 (file)
@@ -103,8 +103,80 @@ StatusType Os_IsrAddResource( TaskType isr, ResourceType resource ) {
 
 #if defined(CFG_ARM_CM3)
 extern void Irq_EOI2( void );
-#endif
 
+void TailChaining(void *stack)
+{
+       struct OsPcb *pPtr = NULL;
+
+       POSTTASKHOOK();
+
+       /* Save info for preempted pcb */
+       pPtr = get_curr_pcb();
+       pPtr->stack.curr = stack;
+       pPtr->state = ST_READY;
+       OS_DEBUG(D_TASK,"Preempted %s\n",pPtr->name);
+
+       Os_StackPerformCheck(pPtr);
+
+       /* We interrupted a task */
+       OsPcbType *new_pcb  = Os_TaskGetTop();
+
+       Os_StackPerformCheck(new_pcb);
+
+       if(     (new_pcb == os_sys.curr_pcb) ||
+                       (os_sys.curr_pcb->scheduling == NON) ||
+                       !Os_SchedulerResourceIsFree() )
+       {
+               /* Just bring the preempted task back to running */
+               Os_TaskSwapContextTo(NULL,os_sys.curr_pcb);
+       } else {
+               OS_DEBUG(D_TASK,"Found candidate %s\n",new_pcb->name);
+               Os_TaskSwapContextTo(NULL,new_pcb);
+       }
+}
+
+void Os_Isr_cm3( void *isr_p ) {
+
+       struct OsPcb *isrPtr;
+
+       os_sys.int_nest_cnt++;
+
+       /* Grab the ISR "pcb" */
+       isrPtr = (struct OsPcb *)isr_p;
+       isrPtr->state = ST_RUNNING;
+
+       if( isrPtr->proc_type & ( PROC_EXTENDED | PROC_BASIC ) ) {
+               assert(0);
+       }
+
+       Irq_Enable();
+       isrPtr->entry();
+       Irq_Disable();
+
+       /* Check so that ISR2 haven't disabled the interrupts */
+       /** @req OS368 */
+       if( Os_IrqAnyDisabled() ) {
+               Os_IrqClearAll();
+               ERRORHOOK(E_OS_DISABLEDINT);
+       }
+
+       /* Check so that the ISR2 have called ReleaseResource() for each GetResource() */
+       /** @req OS369 */
+       if( Os_TaskOccupiesResources(isrPtr) ) {
+               Os_ResourceFreeAll(isrPtr);
+               ERRORHOOK(E_OS_RESOURCE);
+       }
+
+       isrPtr->state = ST_SUSPENDED;
+
+       Irq_EOI();
+
+       --os_sys.int_nest_cnt;
+
+       /* Scheduling is done in PendSV handler for ARM CM3 */
+       *((uint32_t volatile *)0xE000ED04) = 0x10000000; // PendSV
+}
+#endif
 
 /**
  * Handle ISR type 2 interrupts from interrupt controller.
@@ -170,9 +242,12 @@ void *Os_Isr( void *stack, void *isr_p ) {
 
        --os_sys.int_nest_cnt;
 
+#if defined(CFG_ARM_CM3)
+               /* Scheduling is done in PendSV handler for ARM CM3 */
+               *((uint32_t volatile *)0xE000ED04) = 0x10000000; // PendSV
+#else
        // We have preempted a task
        if( (os_sys.int_nest_cnt == 0) ) {
-
                OsPcbType *new_pcb  = Os_TaskGetTop();
 
                Os_StackPerformCheck(new_pcb);
@@ -186,14 +261,12 @@ void *Os_Isr( void *stack, void *isr_p ) {
                        PRETASKHOOK();
                } else {
                        OS_DEBUG(D_TASK,"Found candidate %s\n",new_pcb->name);
-#if defined(CFG_ARM_CM3)
-                       Irq_EOI2();
-#endif
                        Os_TaskSwapContextTo(NULL,new_pcb);
                }
        } else {
                /* We have a nested interrupt, do nothing */
        }
+#endif
 
        return stack;
 }