diff --git a/example/example.uvoptx b/example/example.uvoptx
index 15b1e38..6b030b1 100644
--- a/example/example.uvoptx
+++ b/example/example.uvoptx
@@ -130,7 +130,7 @@
0
DbgFM
- -I -S"System Generator:cpu_core" -L"armcortexm0ct" -O4102 -C0 -MC".\VHT\VHT_MPS2_Cortex-M0.exe" -MF -PF -MA
+ -I -S"System Generator:FVP_MPS2_Cortex_M0" -L"armcortexm0ct" -O4102 -C0 -MC".\avh-fvp\bin\models\FVP_MPS2_Cortex-M0.exe" -MF -PF -MA
0
@@ -204,7 +204,7 @@
0
1
- 1
+ 0
0
0
0
@@ -221,7 +221,7 @@
0
0
0
- 0
+ 1
0
0
0
@@ -817,7 +817,7 @@
::Device
- 1
+ 0
0
0
1
diff --git a/example/example.uvprojx b/example/example.uvprojx
index 85de1cf..704fbd8 100644
--- a/example/example.uvprojx
+++ b/example/example.uvprojx
@@ -10,7 +10,7 @@
example_arm_compiler_6
0x4
ARM-ADS
- 6220000::V6.22::ARMCLANG
+ 6230000::V6.23::.\ArmCompilerforEmbedded6.24
1
@@ -134,11 +134,11 @@
0
1
0
- -1
+ 4096
1
BIN\UL2CM3.DLL
-
+ "" ()
@@ -449,7 +449,7 @@
library
0x4
ARM-ADS
- 6210000::V6.21::ARMCLANG
+ 6230000::V6.23::.\ArmCompilerforEmbedded6.24
1
diff --git a/example/gcc_example.uvoptx b/example/gcc_example.uvoptx
index 521d24a..1be2004 100644
--- a/example/gcc_example.uvoptx
+++ b/example/gcc_example.uvoptx
@@ -75,7 +75,7 @@
1
0
- 1
+ 0
7
@@ -280,7 +280,7 @@
1
0
- 0
+ 1
7
diff --git a/example/main.c b/example/main.c
index 24ee20f..a5e87a0 100644
--- a/example/main.c
+++ b/example/main.c
@@ -19,6 +19,7 @@
#include
#include
#include "perf_counter.h"
+#include
#ifndef __PERF_CNT_USE_LONG_CLOCK__
@@ -126,6 +127,47 @@ uint32_t calculate_stack_usage_bottomup(void)
/*----------------------------------------------------------------------------
Main function
*----------------------------------------------------------------------------*/
+
+typedef struct {
+ uint8_t chPT;
+ void *ptResource;
+} pt_led_flash_cb_t;
+
+#undef this
+#define this (*ptThis)
+
+fsm_rt_t pt_example_led_flash(pt_led_flash_cb_t *ptThis)
+{
+
+PERFC_PT_BEGIN(this.chPT)
+
+ do {
+
+ PERFC_PT_WAIT_RESOURCE_UNTIL(
+ (this.ptResource != NULL), /* quit condition */
+ this.ptResource = malloc(100); /* try to allocate memory */
+ )
+
+ printf("LED ON [%lld]\r\n", get_system_ms());
+
+ PERFC_PT_DELAY_MS(500);
+
+ printf("LED OFF [%lld]\r\n", get_system_ms());
+
+ PERFC_PT_DELAY_MS(500);
+
+ free(this.ptResource);
+
+ } while(1);
+
+PERFC_PT_END()
+
+ return fsm_rt_cpl;
+
+}
+
+static pt_led_flash_cb_t s_tExamplePT = {0};
+
int main (void)
{
int32_t iCycleResult = 0;
@@ -205,10 +247,9 @@ int main (void)
}) {
delay_us(50000);
}
-
-
-
- delay_us(20000);
+ delay_us(20000);
+
+ pt_example_led_flash(&s_tExamplePT);
}
}
diff --git a/perf_counter.c b/perf_counter.c
index ec2b58f..a452771 100644
--- a/perf_counter.c
+++ b/perf_counter.c
@@ -64,9 +64,10 @@ struct __task_cycle_info_t {
/*============================ GLOBAL VARIABLES ==============================*/
/*============================ LOCAL VARIABLES ===============================*/
-volatile int64_t g_lLastTimeStamp = 0;
+
volatile static int64_t s_lOldTimestamp;
-volatile int32_t g_nOffset = 0;
+volatile static int64_t s_lOldTimestampUS;
+volatile static int64_t s_lOldTimestampMS;
volatile static uint32_t s_wUSUnit = 1;
volatile static uint32_t s_wMSUnit = 1;
volatile static uint32_t s_wMSResidule = 0;
@@ -76,6 +77,9 @@ volatile static int64_t s_lSystemUS = 0;
volatile static int64_t s_lSystemClockCounts = 0;
+volatile int32_t g_nOffset = 0;
+volatile int64_t g_lLastTimeStamp = 0;
+
/*============================ PROTOTYPES ====================================*/
/* low level interface for porting */
@@ -112,22 +116,23 @@ void perfc_port_insert_to_system_timer_insert_ovf_handler(void)
// update system ms counter
do {
int64_t lTemp = s_wMSResidule + lLoad;
-
+
int64_t lMS = lTemp / s_wMSUnit;
s_lSystemMS += lMS;
s_wMSResidule = (uint32_t)((int64_t)lTemp - (int64_t)lMS * s_wMSUnit);
} while(0);
+ }
+ __IRQ_SAFE {
// update system us counter
do {
int64_t lTemp = s_wUSResidule + lLoad;
-
+
int64_t lUS = lTemp / s_wUSUnit;
s_lSystemUS += lUS;
s_wUSResidule = (uint32_t)((int64_t)lTemp - (int64_t)lUS * s_wUSUnit);
-
} while(0);
}
}
@@ -169,6 +174,8 @@ bool init_cycle_counter(bool bIsSysTickOccupied)
s_lSystemMS = 0; // reset system millisecond counter
s_lSystemUS = 0; // reset system microsecond counter
s_lOldTimestamp = 0;
+ s_lOldTimestampUS = 0;
+ s_lOldTimestampMS = 0;
__perf_os_patch_init();
@@ -322,7 +329,15 @@ int64_t get_system_ms(void)
int64_t lTemp = 0;
__IRQ_SAFE {
- lTemp = s_lSystemMS + ((check_systick() + (int64_t)s_wMSResidule) / s_wMSUnit);
+ lTemp = s_lSystemMS
+ + ( (check_systick()
+ + (int64_t)s_wMSResidule) / s_wMSUnit);
+
+ if (lTemp < s_lOldTimestampMS) {
+ lTemp = s_lOldTimestampMS;
+ } else {
+ s_lOldTimestampMS = lTemp;
+ }
}
return lTemp;
@@ -333,7 +348,16 @@ int64_t get_system_us(void)
int64_t lTemp = 0;
__IRQ_SAFE {
- lTemp = s_lSystemUS + ((check_systick() + (int64_t)s_wUSResidule) / s_wUSUnit);
+ lTemp = s_lSystemUS
+ + ( (check_systick()
+ + (int64_t)s_wUSResidule) / s_wUSUnit);
+
+ if (lTemp < s_lOldTimestampUS) {
+ lTemp = s_lOldTimestampUS;
+ } else {
+ s_lOldTimestampUS = lTemp;
+ }
+
}
return lTemp;
@@ -370,7 +394,6 @@ bool __perfc_is_time_out(int64_t lPeriod, int64_t *plTimestamp, bool bAutoReload
int64_t lTimestamp = get_system_ticks();
-
if (0 == *plTimestamp) {
*plTimestamp = lPeriod;
*plTimestamp += lTimestamp;
@@ -411,8 +434,6 @@ uint32_t EventRecorderTimerGetCount (void)
return get_system_ticks();
}
-
-
__WEAK
task_cycle_info_t * get_rtos_task_cycle_info(void)
{
diff --git a/perf_counter.h b/perf_counter.h
index 7e46627..91ad5e5 100644
--- a/perf_counter.h
+++ b/perf_counter.h
@@ -39,8 +39,8 @@ extern "C" {
* @{
*/
#define __PERF_COUNTER_VER_MAJOR__ 2
-#define __PERF_COUNTER_VER_MINOR__ 3
-#define __PERF_COUNTER_VER_REVISE__ 3
+#define __PERF_COUNTER_VER_MINOR__ 4
+#define __PERF_COUNTER_VER_REVISE__ 0
#define __PERF_COUNTER_VER_STR__ ""
@@ -275,7 +275,8 @@ extern "C" {
#endif
-#define SAFE_NAME(__NAME) CONNECT3(__,__NAME,__LINE__)
+#define SAFE_NAME(__NAME) CONNECT3(__,__NAME,__LINE__)
+#define PERFC_SAFE_NAME(__name) CONNECT3(__,__name,__LINE__)
#undef foreach2
#undef foreach3
@@ -283,23 +284,23 @@ extern "C" {
#define foreach1(__array) \
using(__typeof__(__array[0]) *_ = __array) \
- for ( uint_fast32_t SAFE_NAME(count) = dimof(__array); \
- SAFE_NAME(count) > 0; \
- _++, SAFE_NAME(count)-- \
+ for ( uint_fast32_t PERFC_SAFE_NAME(count) = dimof(__array); \
+ PERFC_SAFE_NAME(count) > 0; \
+ _++, PERFC_SAFE_NAME(count)-- \
)
#define foreach2(__type, __array) \
using(__type *_ = __array) \
- for ( uint_fast32_t SAFE_NAME(count) = dimof(__array); \
- SAFE_NAME(count) > 0; \
- _++, SAFE_NAME(count)-- \
+ for ( uint_fast32_t PERFC_SAFE_NAME(count) = dimof(__array); \
+ PERFC_SAFE_NAME(count) > 0; \
+ _++, PERFC_SAFE_NAME(count)-- \
)
#define foreach3(__type, __array, __item) \
using(__type *_ = __array, *__item = _, _ = _, _ = _ ) \
- for ( uint_fast32_t SAFE_NAME(count) = dimof(__array); \
- SAFE_NAME(count) > 0; \
- _++, __item = _, SAFE_NAME(count)-- \
+ for ( uint_fast32_t PERFC_SAFE_NAME(count) = dimof(__array); \
+ PERFC_SAFE_NAME(count) > 0; \
+ _++, __item = _, PERFC_SAFE_NAME(count)-- \
)
#define foreach(...) \
@@ -415,29 +416,30 @@ __asm(".global __ensure_systick_wrapper\n\t");
\endcode
*/
#define __cpu_usage__(__CNT, ...) \
- static int64_t SAFE_NAME(s_lTimestamp) = 0, SAFE_NAME(s_lTotal) = 0; \
- static uint32_t SAFE_NAME(s_wLoopCounter) = (__CNT); \
+ static int64_t PERFC_SAFE_NAME(s_lTimestamp) = 0, \
+ PERFC_SAFE_NAME(s_lTotal) = 0; \
+ static uint32_t PERFC_SAFE_NAME(s_wLoopCounter) = (__CNT); \
using(float __usage__ = 0, ({ \
- if (0 == SAFE_NAME(s_wLoopCounter)) { \
- __usage__ = (float)((double)SAFE_NAME(s_lTotal) \
+ if (0 == PERFC_SAFE_NAME(s_wLoopCounter)) { \
+ __usage__ = (float)((double)PERFC_SAFE_NAME(s_lTotal) \
/ (double)( get_system_ticks() \
- - SAFE_NAME(s_lTimestamp))); \
+ - PERFC_SAFE_NAME(s_lTimestamp))); \
__usage__ *= 100.0f; \
- SAFE_NAME(s_lTimestamp) = 0; \
- SAFE_NAME(s_lTotal) = 0; \
+ PERFC_SAFE_NAME(s_lTimestamp) = 0; \
+ PERFC_SAFE_NAME(s_lTotal) = 0; \
if (__PLOOC_VA_NUM_ARGS(__VA_ARGS__) == 0) { \
__perf_counter_printf__("CPU Usage %3.2f%%\r\n", (double)__usage__);\
} else { \
__VA_ARGS__ \
} \
} \
- if (0 == SAFE_NAME(s_lTimestamp)) { \
- SAFE_NAME(s_lTimestamp) = get_system_ticks(); \
- SAFE_NAME(s_wLoopCounter) = (__CNT); \
+ if (0 == PERFC_SAFE_NAME(s_lTimestamp)) { \
+ PERFC_SAFE_NAME(s_lTimestamp) = get_system_ticks(); \
+ PERFC_SAFE_NAME(s_wLoopCounter) = (__CNT); \
} \
start_task_cycle_counter();}), \
- ({SAFE_NAME(s_lTotal) += stop_task_cycle_counter(); \
- SAFE_NAME(s_wLoopCounter)--;}))
+ ({PERFC_SAFE_NAME(s_lTotal) += stop_task_cycle_counter(); \
+ PERFC_SAFE_NAME(s_wLoopCounter)--;}))
#define __cpu_time__ __cpu_usage__
@@ -462,7 +464,8 @@ __asm(".global __ensure_systick_wrapper\n\t");
* \return bool whether it is timeout
*/
#define perfc_is_time_out_ms3(__ms, __timestamp_ptr, __auto_reload) \
- ({ static int64_t SAFE_NAME(s_lTimestamp); (void)SAFE_NAME(s_lTimestamp); \
+ ({ static int64_t PERFC_SAFE_NAME(s_lTimestamp); \
+ (void)PERFC_SAFE_NAME(s_lTimestamp); \
__perfc_is_time_out(perfc_convert_ms_to_ticks(__ms), \
(__timestamp_ptr), (__auto_reload));})
@@ -487,7 +490,7 @@ __asm(".global __ensure_systick_wrapper\n\t");
* \return bool whether it is timeout
*/
#define perfc_is_time_out_ms1(__ms) \
- perfc_is_time_out_ms3((__ms), &SAFE_NAME(s_lTimestamp), true)
+ perfc_is_time_out_ms3((__ms), &PERFC_SAFE_NAME(s_lTimestamp), true)
/*!
* \brief set an alarm with given period in ms and check the status
@@ -512,7 +515,8 @@ __asm(".global __ensure_systick_wrapper\n\t");
* \return bool whether it is timeout
*/
#define perfc_is_time_out_us3(__us, __timestamp_ptr, __auto_reload) \
- ({ static int64_t SAFE_NAME(s_lTimestamp); (void)SAFE_NAME(s_lTimestamp); \
+ ({ static int64_t PERFC_SAFE_NAME(s_lTimestamp); \
+ (void)PERFC_SAFE_NAME(s_lTimestamp); \
__perfc_is_time_out(perfc_convert_us_to_ticks(__us), \
(__timestamp_ptr), (__auto_reload));})
@@ -568,9 +572,9 @@ __asm(".global __ensure_systick_wrapper\n\t");
int64_t lTaskUsedCycles; \
int64_t lTimeElapsed; \
} __cpu_usage__ = {.lStart = get_system_ticks()}) \
- using(int SAFE_NAME(cnt) = (__N)) \
+ using(int PERFC_SAFE_NAME(cnt) = (__N)) \
for(start_task_cycle_counter();; ({ \
- if (!(--SAFE_NAME(cnt))) { \
+ if (!(--PERFC_SAFE_NAME(cnt))) { \
__cpu_usage__.lTimeElapsed \
= get_system_ticks() - __cpu_usage__.lStart - g_nOffset; \
__cpu_usage__.lTaskUsedCycles = stop_task_cycle_counter(); \
@@ -583,13 +587,142 @@ __asm(".global __ensure_systick_wrapper\n\t");
} else { \
__VA_ARGS__; \
} \
- SAFE_NAME(cnt) = (__N); \
+ PERFC_SAFE_NAME(cnt) = (__N); \
__cpu_usage__.lStart = get_system_ticks(); \
start_task_cycle_counter(); \
}; \
}))
+/*----------------------------------------------------------------------------*
+ * PT Operations *
+ *----------------------------------------------------------------------------*/
+/*
+Protothreads open source BSD-style license
+The protothreads library is released under an open source license that allows
+both commercial and non-commercial use without restrictions. The only
+requirement is that credits is given in the source code and in the documentation
+for your product.
+
+The full license text follows.
+
+Copyright (c) 2004-2005, Swedish Institute of Computer Science.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+3. Neither the name of the Institute nor the names of its contributors
+may be used to endorse or promote products derived from this software
+without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS `AS IS' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
+Author: Adam Dunkels
+*/
+
+#define PERFC_PT_BEGIN(__state) \
+ enum { \
+ count_offset = __COUNTER__ + 1, \
+ }; \
+ uint8_t *ptPTState = &(__state); \
+ switch (__state) { \
+ case __COUNTER__ - count_offset:
+
+#define PERFC_PT_ENTRY(...) \
+ (*ptPTState) = (__COUNTER__ - count_offset + 1) >> 1; \
+ __VA_ARGS__ \
+ case (__COUNTER__ - count_offset) >> 1: (void)(*ptPTState);
+
+#define PERFC_PT_YIELD(...) \
+ PERFC_PT_ENTRY(return __VA_ARGS__;)
+
+#define PERFC_PT_END() \
+ (*ptPTState) = 0; \
+ break;}
+
+#define PERFC_PT_GOTO_PREV_ENTRY(...) return __VA_ARGS__;
+
+#define PERFC_PT_WAIT_UNTIL(__CONDITION, ...) \
+ PERFC_PT_ENTRY() \
+ __VA_ARGS__; \
+ if (!(__CONDITION)) { \
+ PERFC_PT_GOTO_PREV_ENTRY(fsm_rt_on_going); \
+ }
+
+#define PERFC_PT_WAIT_OBJ_UNTIL(__CONDITION, ...) \
+ perfc_pt__ENTRY() \
+ __VA_ARGS__; \
+ if (!(__CONDITION)) { \
+ PERFC_PT_GOTO_PREV_ENTRY(fsm_rt_wait_for_obj); \
+ }
+
+#define PERFC_PT_WAIT_RESOURCE_UNTIL(__CONDITION, ...) \
+ PERFC_PT_ENTRY() \
+ __VA_ARGS__; \
+ if (!(__CONDITION)) { \
+ PERFC_PT_GOTO_PREV_ENTRY(fsm_rt_wait_for_res); \
+ }
+
+#define PERFC_PT_DELAY_MS(__ms, ...) \
+ PERFC_PT_ENTRY( \
+ static int64_t PERFC_SAFE_NAME(s_lTimestamp); \
+ UNUSED_PARAM(PERFC_SAFE_NAME(s_lTimestamp)); \
+ int64_t *PERFC_SAFE_NAME(plTimestamp) \
+ = (&PERFC_SAFE_NAME(s_lTimestamp), ##__VA_ARGS__); \
+ *PERFC_SAFE_NAME(plTimestamp) = get_system_ms(); \
+ ) \
+ do { \
+ PERFC_SAFE_NAME(plTimestamp) \
+ = (&PERFC_SAFE_NAME(s_lTimestamp), ##__VA_ARGS__); \
+ int64_t PERFC_SAFE_NAME(lElapsedMs) = \
+ get_system_ms() - *PERFC_SAFE_NAME(plTimestamp); \
+ if (PERFC_SAFE_NAME(lElapsedMs) < (__ms)) { \
+ PERFC_PT_GOTO_PREV_ENTRY(fsm_rt_on_going); \
+ } \
+ } while(0)
+
+
+#define PERFC_PT_REPORT_STATUS(...) \
+ PERFC_PT_ENTRY( \
+ return __VA_ARGS__; \
+ )
+
+#define PERFC_PT_RETURN(...) \
+ (*ptPTState) = 0; \
+ return __VA_ARGS__;
+
/*============================ TYPES =========================================*/
+
+#ifndef __FSM_RT_TYPE__
+# define __FSM_RT_TYPE__
+//! \name finit state machine state
+//! @{
+typedef enum {
+ fsm_rt_err = -1, //!< fsm error, error code can be get from other interface
+ fsm_rt_cpl = 0, //!< fsm complete
+ fsm_rt_on_going = 1, //!< fsm on-going
+ fsm_rt_wait_for_obj = 2, //!< fsm wait for object
+ fsm_rt_asyn = 3, //!< fsm asynchronose complete, you can check it later.
+ fsm_rt_wait_for_res = 4, //!< fsm wait for resource
+} fsm_rt_t;
+//! @}
+#endif
+
typedef struct {
int64_t lStart;
int64_t lUsedTotal;
diff --git a/systick_wrapper_gcc.S b/systick_wrapper_gcc.S
index 948ce28..6e29df4 100644
--- a/systick_wrapper_gcc.S
+++ b/systick_wrapper_gcc.S
@@ -15,15 +15,15 @@
;* *
;****************************************************************************/
- .syntax unified
- .arch armv6-m
+ .syntax unified
+ .arch armv6-m
.text
.thumb
.thumb_func
- .align 2
- .globl __wrap_SysTick_Handler
- .type __wrap_SysTick_Handler, %function
+ .align 2
+ .globl __wrap_SysTick_Handler
+ .type __wrap_SysTick_Handler, %function
__wrap_SysTick_Handler:
push {r4, r5}
@@ -41,4 +41,4 @@ __wrap_SysTick_Handler:
.type __ensure_systick_wrapper, %function
__ensure_systick_wrapper:
- bx lr
\ No newline at end of file
+ bx lr