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
#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
/* 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
*/\r
os_sc_restore:\r
add.w sp,sp,#C_SIZE\r
-\r
pop {REG_SAVE,lr}\r
bx lr\r
\r
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
*/\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
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
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 ) {
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);
-}
/**
*
* 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
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;
}
/**
}
/**
- * 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;
}
/**
.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
\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
\r
.text :\r
{\r
+ . = ALIGN(4);\r
*(.text .text.* );\r
*(.glue_7) /* TODO */\r
*(.glue_7t) /* TODO */\r
SORT(*)(.test_etask);\r
\r
/* ST/ARM special variable to initialize .data */\r
+ . = ALIGN(4);\r
_etext = .;\r
} > flash\r
\r
\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
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
# 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
DIO_CHANNEL_F14,\r
DIO_CHANNEL_F15,\r
\r
-} Dio_ChannelType;\r
+} Dio_Hw_ChannelType;\r
//@}\r
\r
/** HW specific DIO port definitions. */\r
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
const u32 remaps[] = {\r
GPIO_Remap_ETH,\r
GPIO_Remap2_CAN1,\r
+ GPIO_Remap_CAN2,\r
};\r
\r
const Port_PortConfigType porta = {\r
\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
/* 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;
}
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) ) {
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) ) {
return 0;
}
+
+
#ifdef _TEST_CIRQ_BUFFER_DYN_
int main( void ) {
- CirqBufferDynType *cPtr;
+ CirqBufferType *cPtr;
uint8_t *dataPtr;
int rv;
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);
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
}\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
}\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
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
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
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
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
\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
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
}\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
\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
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
* @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
/* 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_ */
\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
\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
#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.
--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);
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;
}