Reload feature added to RT virtual timers.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14333 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
5b3566706a
commit
6411cd50b4
|
@ -5,7 +5,7 @@
|
|||
|
||||
# Compiler options here.
|
||||
ifeq ($(USE_OPT),)
|
||||
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
|
||||
USE_OPT = -Og -ggdb -fomit-frame-pointer -falign-functions=16
|
||||
endif
|
||||
|
||||
# C specific options here (added to USE_OPT).
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "rt_test_root.h"
|
||||
#include "oslib_test_root.h"
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Green LED blinker thread, times are in milliseconds.
|
||||
*/
|
||||
|
@ -34,6 +35,14 @@ static THD_FUNCTION(Thread1, arg) {
|
|||
chThdSleepMilliseconds(500);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
virtual_timer_t vt1;
|
||||
void vtfunc(void *par) {
|
||||
|
||||
(void)par;
|
||||
palToggleLine(LINE_LED_GREEN);
|
||||
}
|
||||
|
||||
/*
|
||||
* Application entry point.
|
||||
|
@ -60,7 +69,8 @@ int main(void) {
|
|||
/*
|
||||
* Creates the blinker thread.
|
||||
*/
|
||||
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
|
||||
// chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL);
|
||||
chVTSetContinuous(&vt1, TIME_MS2I(500), vtfunc, NULL);
|
||||
|
||||
/*
|
||||
* Normal main() thread activity, in this demo it does nothing except
|
||||
|
|
|
@ -98,6 +98,14 @@ typedef struct ch_virtual_timer {
|
|||
* @brief Timer callback function parameter.
|
||||
*/
|
||||
void *par;
|
||||
/**
|
||||
* @brief Time of the last activation.
|
||||
*/
|
||||
systime_t last;
|
||||
/**
|
||||
* @brief Current reload interval.
|
||||
*/
|
||||
sysinterval_t reload;
|
||||
} virtual_timer_t;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,520 +0,0 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
|
||||
2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation version 3 of the License.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file chobjects.h
|
||||
* @brief Operating System Objects macros and structures.
|
||||
*
|
||||
* @addtogroup os_structures
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef CHOBJECTS_H
|
||||
#define CHOBJECTS_H
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Global state of the operating system.
|
||||
*/
|
||||
typedef enum {
|
||||
ch_sys_uninit = 0,
|
||||
ch_sys_initializing = 1,
|
||||
ch_sys_running = 2,
|
||||
ch_sys_halted = 3
|
||||
} system_state_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a Virtual Timer callback function.
|
||||
*/
|
||||
typedef void (*vtfunc_t)(void *p);
|
||||
|
||||
/**
|
||||
* @brief Type of a Virtual Timer structure.
|
||||
*/
|
||||
typedef struct ch_delta_list delta_list_t;
|
||||
|
||||
/**
|
||||
* @brief Virtual Timer delta list element and header structure.
|
||||
*/
|
||||
struct ch_delta_list {
|
||||
/**
|
||||
* @brief Next timer in the list.
|
||||
*/
|
||||
delta_list_t *next;
|
||||
/**
|
||||
* @brief Previous timer in the list.
|
||||
*/
|
||||
delta_list_t *prev;
|
||||
/**
|
||||
* @brief Time delta before timeout.
|
||||
*/
|
||||
sysinterval_t delta;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Type of a Virtual Timer.
|
||||
*/
|
||||
typedef struct ch_virtual_timer {
|
||||
/**
|
||||
* @brief Delta list element.
|
||||
*/
|
||||
delta_list_t dlist;
|
||||
/**
|
||||
* @brief Timer callback function pointer.
|
||||
*/
|
||||
vtfunc_t func;
|
||||
/**
|
||||
* @brief Timer callback function parameter.
|
||||
*/
|
||||
void *par;
|
||||
/**
|
||||
* @brief Time of the last activation.
|
||||
*/
|
||||
systime_t last;
|
||||
/**
|
||||
* @brief Current reload interval.
|
||||
*/
|
||||
sysinterval_t reload;
|
||||
} virtual_timer_t;
|
||||
|
||||
/**
|
||||
* @brief Type of virtual timers list header.
|
||||
* @note The timers list is implemented as a double link bidirectional list
|
||||
* in order to make the unlink time constant, the reset of a virtual
|
||||
* timer is often used in the code.
|
||||
*/
|
||||
typedef struct ch_virtual_timers_list {
|
||||
/**
|
||||
* @brief Delta list header.
|
||||
*/
|
||||
delta_list_t dlist;
|
||||
#if (CH_CFG_ST_TIMEDELTA == 0) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief System Time counter.
|
||||
*/
|
||||
volatile systime_t systime;
|
||||
#endif
|
||||
#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief System time of the last tick event.
|
||||
*/
|
||||
systime_t lasttime;
|
||||
#endif
|
||||
#if (CH_CFG_USE_TIMESTAMP == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Last generated time stamp.
|
||||
*/
|
||||
volatile uint64_t laststamp;
|
||||
#endif
|
||||
} virtual_timers_list_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a registry structure.
|
||||
*/
|
||||
typedef struct ch_registry {
|
||||
/**
|
||||
* @brief Registry queue header.
|
||||
*/
|
||||
ch_queue_t queue;
|
||||
} registry_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a thread reference.
|
||||
*/
|
||||
typedef thread_t * thread_reference_t;
|
||||
|
||||
/**
|
||||
* @brief Type of a threads queue.
|
||||
*/
|
||||
typedef struct ch_threads_queue {
|
||||
/**
|
||||
* @brief Threads queue header.
|
||||
*/
|
||||
ch_queue_t queue;
|
||||
} threads_queue_t;
|
||||
|
||||
/**
|
||||
* @brief Structure representing a thread.
|
||||
* @note Not all the listed fields are always needed, by switching off some
|
||||
* not needed ChibiOS/RT subsystems it is possible to save RAM space
|
||||
* by shrinking this structure.
|
||||
*/
|
||||
struct ch_thread {
|
||||
/**
|
||||
* @brief Shared list headers.
|
||||
*/
|
||||
union {
|
||||
/**
|
||||
* @brief Threads lists element.
|
||||
*/
|
||||
ch_list_t list;
|
||||
/**
|
||||
* @brief Threads queues element.
|
||||
*/
|
||||
ch_queue_t queue;
|
||||
/**
|
||||
* @brief Threads ordered queues element.
|
||||
*/
|
||||
ch_priority_queue_t pqueue;
|
||||
} hdr;
|
||||
/**
|
||||
* @brief Processor context.
|
||||
*/
|
||||
struct port_context ctx;
|
||||
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Registry queue element.
|
||||
*/
|
||||
ch_queue_t rqueue;
|
||||
#endif
|
||||
/**
|
||||
* @brief OS instance owner of this thread.
|
||||
*/
|
||||
os_instance_t *owner;
|
||||
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Thread name or @p NULL.
|
||||
*/
|
||||
const char *name;
|
||||
#endif
|
||||
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
|
||||
defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Working area base address.
|
||||
* @note This pointer is used for stack overflow checks and for
|
||||
* dynamic threading.
|
||||
*/
|
||||
stkalign_t *wabase;
|
||||
#endif
|
||||
/**
|
||||
* @brief Current thread state.
|
||||
*/
|
||||
tstate_t state;
|
||||
/**
|
||||
* @brief Various thread flags.
|
||||
*/
|
||||
tmode_t flags;
|
||||
#if (CH_CFG_USE_REGISTRY == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief References to this thread.
|
||||
*/
|
||||
trefs_t refs;
|
||||
#endif
|
||||
/**
|
||||
* @brief Number of ticks remaining to this thread.
|
||||
*/
|
||||
#if (CH_CFG_TIME_QUANTUM > 0) || defined(__DOXYGEN__)
|
||||
tslices_t ticks;
|
||||
#endif
|
||||
#if (CH_DBG_THREADS_PROFILING == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Thread consumed time in ticks.
|
||||
* @note This field can overflow.
|
||||
*/
|
||||
volatile systime_t time;
|
||||
#endif
|
||||
/**
|
||||
* @brief State-specific fields.
|
||||
* @note All the fields declared in this union are only valid in the
|
||||
* specified state or condition and are thus volatile.
|
||||
*/
|
||||
union {
|
||||
/**
|
||||
* @brief Thread wakeup code.
|
||||
* @note This field contains the low level message sent to the thread
|
||||
* by the waking thread or interrupt handler. The value is valid
|
||||
* after exiting the @p chSchWakeupS() function.
|
||||
*/
|
||||
msg_t rdymsg;
|
||||
/**
|
||||
* @brief Thread exit code.
|
||||
* @note The thread termination code is stored in this field in order
|
||||
* to be retrieved by the thread performing a @p chThdWait() on
|
||||
* this thread.
|
||||
*/
|
||||
msg_t exitcode;
|
||||
/**
|
||||
* @brief Pointer to a generic "wait" object.
|
||||
* @note This field is used to get a generic pointer to a synchronization
|
||||
* object and is valid when the thread is in one of the wait
|
||||
* states.
|
||||
*/
|
||||
void *wtobjp;
|
||||
/**
|
||||
* @brief Pointer to a generic thread reference object.
|
||||
* @note This field is used to get a pointer to a synchronization
|
||||
* object and is valid when the thread is in @p CH_STATE_SUSPENDED
|
||||
* state.
|
||||
*/
|
||||
thread_reference_t *wttrp;
|
||||
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Thread sent message.
|
||||
*/
|
||||
msg_t sentmsg;
|
||||
#endif
|
||||
#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Pointer to a generic semaphore object.
|
||||
* @note This field is used to get a pointer to a synchronization
|
||||
* object and is valid when the thread is in @p CH_STATE_WTSEM
|
||||
* state.
|
||||
*/
|
||||
struct ch_semaphore *wtsemp;
|
||||
#endif
|
||||
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Pointer to a generic mutex object.
|
||||
* @note This field is used to get a pointer to a synchronization
|
||||
* object and is valid when the thread is in @p CH_STATE_WTMTX
|
||||
* state.
|
||||
*/
|
||||
struct ch_mutex *wtmtxp;
|
||||
#endif
|
||||
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Enabled events mask.
|
||||
* @note This field is only valid while the thread is in the
|
||||
* @p CH_STATE_WTOREVT or @p CH_STATE_WTANDEVT states.
|
||||
*/
|
||||
eventmask_t ewmask;
|
||||
#endif
|
||||
} u;
|
||||
#if (CH_CFG_USE_WAITEXIT == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Termination waiting list.
|
||||
*/
|
||||
ch_list_t waiting;
|
||||
#endif
|
||||
#if (CH_CFG_USE_MESSAGES == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Messages queue.
|
||||
*/
|
||||
ch_queue_t msgqueue;
|
||||
#endif
|
||||
#if (CH_CFG_USE_EVENTS == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Pending events mask.
|
||||
*/
|
||||
eventmask_t epending;
|
||||
#endif
|
||||
#if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief List of the mutexes owned by this thread.
|
||||
* @note The list is terminated by a @p NULL in this field.
|
||||
*/
|
||||
struct ch_mutex *mtxlist;
|
||||
/**
|
||||
* @brief Thread's own, non-inherited, priority.
|
||||
*/
|
||||
tprio_t realprio;
|
||||
#endif
|
||||
#if ((CH_CFG_USE_DYNAMIC == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE)) || \
|
||||
defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Memory Pool where the thread workspace is returned.
|
||||
*/
|
||||
void *mpool;
|
||||
#endif
|
||||
#if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Thread statistics.
|
||||
*/
|
||||
time_measurement_t stats;
|
||||
#endif
|
||||
#if defined(CH_CFG_THREAD_EXTRA_FIELDS)
|
||||
/* Extra fields defined in chconf.h.*/
|
||||
CH_CFG_THREAD_EXTRA_FIELDS
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Type of a ready list header.
|
||||
*/
|
||||
typedef struct ch_ready_list {
|
||||
/**
|
||||
* @brief Threads ordered queues header.
|
||||
* @note The priority field must be initialized to zero.
|
||||
*/
|
||||
ch_priority_queue_t pqueue;
|
||||
/**
|
||||
* @brief The currently running thread.
|
||||
*/
|
||||
thread_t *current;
|
||||
} ready_list_t;
|
||||
|
||||
/**
|
||||
* @brief Type of an system instance configuration.
|
||||
*/
|
||||
typedef struct ch_os_instance_config {
|
||||
/**
|
||||
* @brief Instance name.
|
||||
*/
|
||||
const char *name;
|
||||
#if (CH_DBG_ENABLE_STACK_CHECK == TRUE) || (CH_CFG_USE_DYNAMIC == TRUE) || \
|
||||
defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Lower limit of the main function thread stack.
|
||||
*/
|
||||
stkalign_t *mainthread_base;
|
||||
/**
|
||||
* @brief Upper limit of the main function thread stack.
|
||||
*/
|
||||
stkalign_t *mainthread_end;
|
||||
#endif
|
||||
#if (CH_CFG_NO_IDLE_THREAD == FALSE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Lower limit of the dedicated idle thread stack.
|
||||
*/
|
||||
stkalign_t *idlethread_base;
|
||||
/**
|
||||
* @brief Upper limit of the dedicated idle thread stack.
|
||||
*/
|
||||
stkalign_t *idlethread_end;
|
||||
#endif
|
||||
} os_instance_config_t;
|
||||
|
||||
/**
|
||||
* @brief System instance data structure.
|
||||
*/
|
||||
struct ch_os_instance {
|
||||
/**
|
||||
* @brief Ready list header.
|
||||
*/
|
||||
ready_list_t rlist;
|
||||
/**
|
||||
* @brief Virtual timers delta list header.
|
||||
*/
|
||||
virtual_timers_list_t vtlist;
|
||||
#if ((CH_CFG_USE_REGISTRY == TRUE) && (CH_CFG_SMP_MODE == FALSE)) || \
|
||||
defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Registry header.
|
||||
* @note This field is present only if the SMP mode is disabled.
|
||||
*/
|
||||
registry_t reglist;
|
||||
#endif
|
||||
/**
|
||||
* @brief Core associated to this instance.
|
||||
*/
|
||||
core_id_t core_id;
|
||||
/**
|
||||
* @brief Pointer to the instance configuration data.
|
||||
*/
|
||||
const os_instance_config_t *config;
|
||||
/**
|
||||
* @brief Main thread descriptor.
|
||||
*/
|
||||
thread_t mainthread;
|
||||
/**
|
||||
* @brief System debug.
|
||||
*/
|
||||
system_debug_t dbg;
|
||||
#if (CH_DBG_TRACE_MASK != CH_DBG_TRACE_MASK_DISABLED) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Trace buffer.
|
||||
*/
|
||||
trace_buffer_t trace_buffer;
|
||||
#endif
|
||||
#if (CH_DBG_STATISTICS == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Global kernel statistics.
|
||||
*/
|
||||
kernel_stats_t kernel_stats;
|
||||
#endif
|
||||
#if defined(PORT_INSTANCE_EXTRA_FIELDS) || defined(__DOXYGEN__)
|
||||
/* Extra fields from port layer.*/
|
||||
PORT_INSTANCE_EXTRA_FIELDS
|
||||
#endif
|
||||
/* Extra fields from configuration.*/
|
||||
CH_CFG_OS_INSTANCE_EXTRA_FIELDS
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Type of system data structure.
|
||||
*/
|
||||
typedef struct ch_system {
|
||||
/**
|
||||
* @brief Operating system state.
|
||||
*/
|
||||
system_state_t state;
|
||||
/**
|
||||
* @brief Initialized OS instances or @p NULL.
|
||||
*/
|
||||
os_instance_t *instances[PORT_CORES_NUMBER];
|
||||
#if (CH_CFG_USE_TM == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Time measurement calibration data.
|
||||
*/
|
||||
tm_calibration_t tmc;
|
||||
#endif
|
||||
#if ((CH_CFG_USE_REGISTRY == TRUE) && (CH_CFG_SMP_MODE == TRUE)) || \
|
||||
defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Registry header.
|
||||
* @note This field is present only if the SMP mode is enabled.
|
||||
*/
|
||||
registry_t reglist;
|
||||
#endif
|
||||
#if defined(PORT_SYSTEM_EXTRA_FIELDS) || defined(__DOXYGEN__)
|
||||
/* Extra fields from port layer.*/
|
||||
PORT_SYSTEM_EXTRA_FIELDS
|
||||
#endif
|
||||
/* Extra fields from configuration.*/
|
||||
CH_CFG_SYSTEM_EXTRA_FIELDS
|
||||
} ch_system_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#endif /* CHOBJECTS_H */
|
||||
|
||||
/** @} */
|
|
@ -73,6 +73,8 @@ extern "C" {
|
|||
#endif
|
||||
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par);
|
||||
void chVTDoSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par);
|
||||
void chVTDoResetI(virtual_timer_t *vtp);
|
||||
void chVTDoTickI(void);
|
||||
#if CH_CFG_USE_TIMESTAMP == TRUE
|
||||
|
@ -100,7 +102,7 @@ extern "C" {
|
|||
*/
|
||||
static inline void chVTObjectInit(virtual_timer_t *vtp) {
|
||||
|
||||
vtp->func = NULL;
|
||||
vtp->dlist.next = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,7 +248,7 @@ static inline bool chVTIsArmedI(const virtual_timer_t *vtp) {
|
|||
|
||||
chDbgCheckClassI();
|
||||
|
||||
return (bool)(vtp->func != NULL);
|
||||
return (bool)(vtp->dlist.next != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,7 +306,7 @@ static inline void chVTReset(virtual_timer_t *vtp) {
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a virtual timer.
|
||||
* @brief Enables a one-shot virtual timer.
|
||||
* @details If the virtual timer was already enabled then it is re-enabled
|
||||
* using the new parameters.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
|
@ -333,7 +335,7 @@ static inline void chVTSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a virtual timer.
|
||||
* @brief Enables a one-shot virtual timer.
|
||||
* @details If the virtual timer was already enabled then it is re-enabled
|
||||
* using the new parameters.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
|
@ -362,6 +364,121 @@ static inline void chVTSet(virtual_timer_t *vtp, sysinterval_t delay,
|
|||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a continuous virtual timer.
|
||||
* @details If the virtual timer was already enabled then it is re-enabled
|
||||
* using the new parameters.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void chVTSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
|
||||
chVTResetI(vtp);
|
||||
chVTDoSetContinuousI(vtp, delay, vtfunc, par);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a continuous virtual timer.
|
||||
* @details If the virtual timer was already enabled then it is re-enabled
|
||||
* using the new parameters.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void chVTSetContinuous(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
|
||||
chSysLock();
|
||||
chVTSetContinuousI(vtp, delay, vtfunc, par);
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the current reload value.
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @return The reload value.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline sysinterval_t chVTGetReloadIntervalX(virtual_timer_t *vtp) {
|
||||
|
||||
return vtp->reload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes a timer reload time interval.
|
||||
* @note This function is meant to be called from a timer callback, it
|
||||
* does nothing in any other context.
|
||||
* @note Calling this function from a one-shot timer callback turns it
|
||||
* into a continuous timer.
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] reload the new reload value, zero means no reload
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline void chVTSetReloadIntervalX(virtual_timer_t *vtp,
|
||||
sysinterval_t reload) {
|
||||
|
||||
vtp->reload = reload;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the remaining time interval before next timer trigger.
|
||||
* @note This function can be called while the timer is active or
|
||||
* after stopping it.
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @return The remaining time interval.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline sysinterval_t chVTGetRemainingIntervalX(virtual_timer_t *vtp) {
|
||||
sysinterval_t elapsed_time;
|
||||
|
||||
/* Time elapsed since last triggering or 1st activation.*/
|
||||
elapsed_time = chTimeDiffX(vtp->last, chVTGetSystemTimeX());
|
||||
|
||||
/* Current time could have slipped past the next deadline, compensating.*/
|
||||
if (elapsed_time > vtp->reload) {
|
||||
elapsed_time = vtp->reload;
|
||||
}
|
||||
|
||||
/* Returning the remaining time interval.*/
|
||||
return vtp->reload - elapsed_time;
|
||||
}
|
||||
|
||||
#if (CH_CFG_USE_TIMESTAMP == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Generates a monotonic time stamp.
|
||||
|
|
|
@ -1,519 +0,0 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
|
||||
2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation version 3 of the License.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file rt/include/chvt.h
|
||||
* @brief Time and Virtual Timers module macros and structures.
|
||||
*
|
||||
* @addtogroup time
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef CHVT_H
|
||||
#define CHVT_H
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module constants. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module pre-compile time settings. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Derived constants and error checks. */
|
||||
/*===========================================================================*/
|
||||
|
||||
#if (CH_CFG_ST_TIMEDELTA < 0) || (CH_CFG_ST_TIMEDELTA == 1)
|
||||
#error "invalid CH_CFG_ST_TIMEDELTA specified, must " \
|
||||
"be zero or greater than one"
|
||||
#endif
|
||||
|
||||
#if (CH_CFG_ST_TIMEDELTA > 0) && (CH_CFG_TIME_QUANTUM > 0)
|
||||
#error "CH_CFG_TIME_QUANTUM not supported in tickless mode"
|
||||
#endif
|
||||
|
||||
#if (CH_CFG_ST_TIMEDELTA > 0) && (CH_DBG_THREADS_PROFILING == TRUE)
|
||||
#error "CH_DBG_THREADS_PROFILING not supported in tickless mode"
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module data structures and types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module macros. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* External declarations. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*
|
||||
* Virtual Timers APIs.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par);
|
||||
void chVTDoSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par);
|
||||
void chVTDoResetI(virtual_timer_t *vtp);
|
||||
void chVTDoTickI(void);
|
||||
#if CH_CFG_USE_TIMESTAMP == TRUE
|
||||
systimestamp_t chVTGetTimeStampI(void);
|
||||
void chVTResetTimeStampI(void);
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module inline functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Initializes a @p virtual_timer_t object.
|
||||
* @note Initializing a timer object is not strictly required because
|
||||
* the function @p chVTSetI() initializes the object too. This
|
||||
* function is only useful if you need to perform a @p chVTIsArmed()
|
||||
* check before calling @p chVTSetI().
|
||||
*
|
||||
* @param[out] vtp the @p virtual_timer_t structure pointer
|
||||
*
|
||||
* @init
|
||||
*/
|
||||
static inline void chVTObjectInit(virtual_timer_t *vtp) {
|
||||
|
||||
vtp->dlist.next = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Current system time.
|
||||
* @details Returns the number of system ticks since the @p chSysInit()
|
||||
* invocation.
|
||||
* @note The counter can reach its maximum and then restart from zero.
|
||||
* @note This function can be called from any context but its atomicity
|
||||
* is not guaranteed on architectures whose word size is less than
|
||||
* @p systime_t size.
|
||||
*
|
||||
* @return The system time in ticks.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline systime_t chVTGetSystemTimeX(void) {
|
||||
|
||||
#if CH_CFG_ST_TIMEDELTA == 0
|
||||
return currcore->vtlist.systime;
|
||||
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
return port_timer_get_time();
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Current system time.
|
||||
* @details Returns the number of system ticks since the @p chSysInit()
|
||||
* invocation.
|
||||
* @note The counter can reach its maximum and then restart from zero.
|
||||
*
|
||||
* @return The system time in ticks.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline systime_t chVTGetSystemTime(void) {
|
||||
systime_t systime;
|
||||
|
||||
chSysLock();
|
||||
systime = chVTGetSystemTimeX();
|
||||
chSysUnlock();
|
||||
|
||||
return systime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the elapsed time since the specified start time.
|
||||
*
|
||||
* @param[in] start start time
|
||||
* @return The elapsed time.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline sysinterval_t chVTTimeElapsedSinceX(systime_t start) {
|
||||
|
||||
return chTimeDiffX(start, chVTGetSystemTimeX());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the current system time is within the specified time
|
||||
* window.
|
||||
* @note When start==end then the function returns always false because the
|
||||
* time window has zero size.
|
||||
*
|
||||
* @param[in] start the start of the time window (inclusive)
|
||||
* @param[in] end the end of the time window (non inclusive)
|
||||
* @retval true current time within the specified time window.
|
||||
* @retval false current time not within the specified time window.
|
||||
*
|
||||
* @xclass
|
||||
*/
|
||||
static inline bool chVTIsSystemTimeWithinX(systime_t start, systime_t end) {
|
||||
|
||||
return chTimeIsInRangeX(chVTGetSystemTimeX(), start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks if the current system time is within the specified time
|
||||
* window.
|
||||
* @note When start==end then the function returns always false because the
|
||||
* time window has zero size.
|
||||
*
|
||||
* @param[in] start the start of the time window (inclusive)
|
||||
* @param[in] end the end of the time window (non inclusive)
|
||||
* @retval true current time within the specified time window.
|
||||
* @retval false current time not within the specified time window.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline bool chVTIsSystemTimeWithin(systime_t start, systime_t end) {
|
||||
|
||||
return chTimeIsInRangeX(chVTGetSystemTime(), start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the time interval until the next timer event.
|
||||
* @note The return value is not perfectly accurate and can report values
|
||||
* in excess of @p CH_CFG_ST_TIMEDELTA ticks.
|
||||
* @note The interval returned by this function is only meaningful if
|
||||
* more timers are not added to the list until the returned time.
|
||||
*
|
||||
* @param[out] timep pointer to a variable that will contain the time
|
||||
* interval until the next timer elapses. This pointer
|
||||
* can be @p NULL if the information is not required.
|
||||
* @return The time, in ticks, until next time event.
|
||||
* @retval false if the timers list is empty.
|
||||
* @retval true if the timers list contains at least one timer.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline bool chVTGetTimersStateI(sysinterval_t *timep) {
|
||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||
delta_list_t *dlp = &vtlp->dlist;
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
if (dlp == dlp->next) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (timep != NULL) {
|
||||
#if CH_CFG_ST_TIMEDELTA == 0
|
||||
*timep = dlp->next->delta;
|
||||
#else
|
||||
*timep = (dlp->next->delta + (sysinterval_t)CH_CFG_ST_TIMEDELTA) -
|
||||
chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX());
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns @p true if the specified timer is armed.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @return true if the timer is armed.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline bool chVTIsArmedI(const virtual_timer_t *vtp) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
return (bool)(vtp->dlist.next != NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns @p true if the specified timer is armed.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @return true if the timer is armed.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline bool chVTIsArmed(const virtual_timer_t *vtp) {
|
||||
bool b;
|
||||
|
||||
chSysLock();
|
||||
b = chVTIsArmedI(vtp);
|
||||
chSysUnlock();
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a Virtual Timer.
|
||||
* @note The timer is first checked and disabled only if armed.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void chVTResetI(virtual_timer_t *vtp) {
|
||||
|
||||
if (chVTIsArmedI(vtp)) {
|
||||
chVTDoResetI(vtp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a Virtual Timer.
|
||||
* @note The timer is first checked and disabled only if armed.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void chVTReset(virtual_timer_t *vtp) {
|
||||
|
||||
chSysLock();
|
||||
chVTResetI(vtp);
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a one-shot virtual timer.
|
||||
* @details If the virtual timer was already enabled then it is re-enabled
|
||||
* using the new parameters.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void chVTSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
|
||||
chVTResetI(vtp);
|
||||
chVTDoSetI(vtp, delay, vtfunc, par);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a one-shot virtual timer.
|
||||
* @details If the virtual timer was already enabled then it is re-enabled
|
||||
* using the new parameters.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void chVTSet(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
|
||||
chSysLock();
|
||||
chVTSetI(vtp, delay, vtfunc, par);
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a continuous virtual timer.
|
||||
* @details If the virtual timer was already enabled then it is re-enabled
|
||||
* using the new parameters.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
static inline void chVTSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
|
||||
chVTResetI(vtp);
|
||||
chVTDoSetContinuousI(vtp, delay, vtfunc, par);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a continuous virtual timer.
|
||||
* @details If the virtual timer was already enabled then it is re-enabled
|
||||
* using the new parameters.
|
||||
* @pre The timer must have been initialized using @p chVTObjectInit()
|
||||
* or @p chVTDoSetI().
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void chVTContinuousSet(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
|
||||
chSysLock();
|
||||
chVTSetContinuousI(vtp, delay, vtfunc, par);
|
||||
chSysUnlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Changes a timer reload time interval.
|
||||
* @note This function is meant to be called from a timer callback, it
|
||||
* does nothing in any other context.
|
||||
* @note Calling this function from a one-shot timer callback turns it
|
||||
* into a continuous timer.
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] reload the new reload value, zero means no reload
|
||||
* @return The previous reload value
|
||||
*
|
||||
* @special
|
||||
*/
|
||||
static inline sysinterval_t chVTSetReload(virtual_timer_t *vtp,
|
||||
sysinterval_t reload) {
|
||||
sysinterval_t old_reload;
|
||||
|
||||
old_reload = vtp->reload;
|
||||
vtp->reload = reload;
|
||||
|
||||
return old_reload;
|
||||
}
|
||||
|
||||
#if (CH_CFG_USE_TIMESTAMP == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Generates a monotonic time stamp.
|
||||
* @details This function generates a monotonic time stamp synchronized with
|
||||
* the system time. The time stamp has the same resolution of
|
||||
* system time.
|
||||
* @note There is an assumption, this function must be called at
|
||||
* least once before the system time wraps back to zero or
|
||||
* synchronization is lost. You may use a periodic virtual timer with
|
||||
* a very large interval in order to keep time stamps synchronized
|
||||
* by calling this function.
|
||||
*
|
||||
* @return The time stamp.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline systimestamp_t chVTGetTimeStamp(void) {
|
||||
systimestamp_t stamp;
|
||||
|
||||
chSysLock();
|
||||
|
||||
stamp = chVTGetTimeStampI();
|
||||
|
||||
chSysUnlock();
|
||||
|
||||
return stamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets and re-synchronizes the time stamps monotonic counter.
|
||||
*
|
||||
* @api
|
||||
*/
|
||||
static inline void chVTResetTimeStamp(void) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
chSysLock();
|
||||
|
||||
chVTResetTimeStampI();
|
||||
|
||||
chSysUnlock();
|
||||
}
|
||||
#endif /* CH_CFG_USE_TIMESTAMP == TRUE */
|
||||
|
||||
/**
|
||||
* @brief Virtual Timers instance initialization.
|
||||
* @note Internal use only.
|
||||
*
|
||||
* @param[out] vtlp pointer to the @p virtual_timers_list_t structure
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline void __vt_object_init(virtual_timers_list_t *vtlp) {
|
||||
|
||||
vtlp->dlist.next = &vtlp->dlist;
|
||||
vtlp->dlist.prev = &vtlp->dlist;
|
||||
vtlp->dlist.delta = (sysinterval_t)-1;
|
||||
#if CH_CFG_ST_TIMEDELTA == 0
|
||||
vtlp->systime = (systime_t)0;
|
||||
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
vtlp->lasttime = (systime_t)0;
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
#if CH_CFG_USE_TIMESTAMP == TRUE
|
||||
currcore->vtlist.laststamp = (systimestamp_t)chVTGetSystemTimeX();
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* CHVT_H */
|
||||
|
||||
/** @} */
|
196
os/rt/src/chvt.c
196
os/rt/src/chvt.c
|
@ -129,47 +129,18 @@ static void vt_list_compress(virtual_timers_list_t *vtlp,
|
|||
}
|
||||
#endif
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables a virtual timer.
|
||||
* @details The timer is enabled and programmed to trigger after the delay
|
||||
* specified as parameter.
|
||||
* @pre The timer must not be already armed before calling this function.
|
||||
* @note The callback function is invoked from interrupt context.
|
||||
*
|
||||
* @param[out] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @iclass
|
||||
* @brief Enqueues a virtual timer in a virtual timers list.
|
||||
*/
|
||||
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||
static void vt_enqueue(virtual_timers_list_t *vtlp,
|
||||
virtual_timer_t *vtp,
|
||||
systime_t now,
|
||||
sysinterval_t delay) {
|
||||
delta_list_t *dlp;
|
||||
sysinterval_t delta;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE));
|
||||
|
||||
vtp->par = par;
|
||||
vtp->func = vtfunc;
|
||||
|
||||
#if CH_CFG_ST_TIMEDELTA > 0
|
||||
{
|
||||
systime_t now = chVTGetSystemTimeX();
|
||||
sysinterval_t deltanow;
|
||||
|
||||
/* If the requested delay is lower than the minimum safe delta then it
|
||||
|
@ -260,6 +231,96 @@ void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
|||
vtlp->dlist.delta = (sysinterval_t)-1;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables a one-shot virtual timer.
|
||||
* @details The timer is enabled and programmed to trigger after the delay
|
||||
* specified as parameter.
|
||||
* @pre The timer must not be already armed before calling this function.
|
||||
* @note The callback function is invoked from interrupt context.
|
||||
*
|
||||
* @param[out] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||
systime_t now;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE));
|
||||
|
||||
/* Current system time.*/
|
||||
now = chVTGetSystemTimeX();
|
||||
|
||||
/* Timer initialization.*/
|
||||
vtp->par = par;
|
||||
vtp->func = vtfunc;
|
||||
vtp->last = now;
|
||||
vtp->reload = (sysinterval_t)0;
|
||||
|
||||
/* Inserting the timer in the delta list.*/
|
||||
vt_enqueue(vtlp, vtp, vtp->last, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a continuous virtual timer.
|
||||
* @details The timer is enabled and programmed to trigger after the delay
|
||||
* specified as parameter.
|
||||
* @pre The timer must not be already armed before calling this function.
|
||||
* @note The callback function is invoked from interrupt context.
|
||||
*
|
||||
* @param[out] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void chVTDoSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||
systime_t now;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE));
|
||||
|
||||
/* Current system time.*/
|
||||
now = chVTGetSystemTimeX();
|
||||
|
||||
/* Timer initialization.*/
|
||||
vtp->par = par;
|
||||
vtp->func = vtfunc;
|
||||
vtp->last = now;
|
||||
vtp->reload = delay;
|
||||
|
||||
/* Inserting the timer in the delta list.*/
|
||||
vt_enqueue(vtlp, vtp, vtp->last, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a Virtual Timer.
|
||||
* @pre The timer must be in armed state before calling this function.
|
||||
|
@ -273,17 +334,17 @@ void chVTDoResetI(virtual_timer_t *vtp) {
|
|||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(vtp != NULL);
|
||||
chDbgAssert(vtp->func != NULL, "timer not set or already triggered");
|
||||
chDbgAssert(chVTIsArmedI(vtp), "timer not armed");
|
||||
|
||||
#if CH_CFG_ST_TIMEDELTA == 0
|
||||
|
||||
/* The delta of the timer is added to the next timer.*/
|
||||
vtp->dlist.next->delta += vtp->dlist.delta;
|
||||
|
||||
/* Removing the element from the delta list.*/
|
||||
/* Removing the element from the delta list, marking it as not armed.*/
|
||||
vtp->dlist.prev->next = vtp->dlist.next;
|
||||
vtp->dlist.next->prev = vtp->dlist.prev;
|
||||
vtp->func = NULL;
|
||||
vtp->dlist.next = NULL;
|
||||
|
||||
/* The above code changes the value in the header when the removed element
|
||||
is the last of the list, restoring it.*/
|
||||
|
@ -297,19 +358,21 @@ void chVTDoResetI(virtual_timer_t *vtp) {
|
|||
/* Removing the element from the delta list.*/
|
||||
vtp->dlist.prev->next = vtp->dlist.next;
|
||||
vtp->dlist.next->prev = vtp->dlist.prev;
|
||||
vtp->func = NULL;
|
||||
|
||||
/* Adding delta to the next element, if it is not the last one.*/
|
||||
if (is_timer(&vtlp->dlist, vtp->dlist.next))
|
||||
vtp->dlist.next->delta += vtp->dlist.delta;
|
||||
|
||||
/* Marking timer as not armed.*/
|
||||
vtp->dlist.next = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Removing the first timer from the list.*/
|
||||
/* Removing the first timer from the list, marking it as not armed.*/
|
||||
vtlp->dlist.next = vtp->dlist.next;
|
||||
vtlp->dlist.next->prev = &vtlp->dlist;
|
||||
vtp->func = NULL;
|
||||
vtp->dlist.next = NULL;
|
||||
|
||||
/* If the list become empty then the alarm timer is stopped and done.*/
|
||||
if (is_vtlist_empty(&vtlp->dlist)) {
|
||||
|
@ -378,29 +441,30 @@ void chVTDoTickI(void) {
|
|||
--vtlp->dlist.next->delta;
|
||||
while (vtlp->dlist.next->delta == (sysinterval_t)0) {
|
||||
virtual_timer_t *vtp;
|
||||
vtfunc_t fn;
|
||||
|
||||
/* Triggered timer.*/
|
||||
vtp = (virtual_timer_t *)vtlp->dlist.next;
|
||||
fn = vtp->func;
|
||||
vtp->func = NULL;
|
||||
|
||||
/* Removing the element from the delta list, marking it as not armed.*/
|
||||
vtp->dlist.next->prev = &vtlp->dlist;
|
||||
vtlp->dlist.next = vtp->dlist.next;
|
||||
vtp->dlist.next = NULL;
|
||||
|
||||
chSysUnlockFromISR();
|
||||
fn(vtp->par);
|
||||
vtp->func(vtp->par);
|
||||
chSysLockFromISR();
|
||||
}
|
||||
}
|
||||
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
delta_list_t *dlp;
|
||||
systime_t now;
|
||||
sysinterval_t delta, nowdelta;
|
||||
systime_t now = chVTGetSystemTimeX();
|
||||
|
||||
/* Looping through timers.*/
|
||||
dlp = vtlp->dlist.next;
|
||||
while (true) {
|
||||
|
||||
/* Getting the system time as reference.*/
|
||||
now = chVTGetSystemTimeX();
|
||||
/* Delta between current time and last execution time.*/
|
||||
nowdelta = chTimeDiffX(vtlp->lasttime, now);
|
||||
|
||||
/* The list scan is limited by the timers header having
|
||||
|
@ -412,32 +476,51 @@ void chVTDoTickI(void) {
|
|||
|
||||
/* Consuming all timers between "vtp->lasttime" and now.*/
|
||||
do {
|
||||
vtfunc_t fn;
|
||||
virtual_timer_t *vtp = (virtual_timer_t *)dlp;
|
||||
|
||||
/* The "last time" becomes this timer's expiration time.*/
|
||||
vtlp->lasttime += dlp->delta;
|
||||
nowdelta -= dlp->delta;
|
||||
|
||||
/* Removing the timer from the list.*/
|
||||
/* Removing the timer from the list, marking it as not armed.*/
|
||||
dlp->next->prev = &vtlp->dlist;
|
||||
vtlp->dlist.next = dlp->next;
|
||||
|
||||
/* Calling the associated function and then marking the timer as
|
||||
non active.*/
|
||||
fn = vtp->func;
|
||||
vtp->func = NULL;
|
||||
dlp->next = NULL;
|
||||
|
||||
/* If the list becomes empty then the timer is stopped.*/
|
||||
if (is_vtlist_empty(&vtlp->dlist)) {
|
||||
port_timer_stop_alarm();
|
||||
}
|
||||
|
||||
/* Now "last" marks the current deadline based on the stored
|
||||
reload value. It is done before calling the callback because
|
||||
the reload value could change. Note that "reload" could be
|
||||
zero, no harm.*/
|
||||
vtp->last = chTimeAddX(vtp->last, vtp->reload);
|
||||
|
||||
/* The callback is invoked outside the kernel critical zone.*/
|
||||
chSysUnlockFromISR();
|
||||
fn(vtp->par);
|
||||
vtp->func(vtp->par);
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Getting again the system time after executing the callback in
|
||||
order to reduce error.*/
|
||||
now = chVTGetSystemTimeX();
|
||||
|
||||
/* If a reload is defined the timer needs to be restarted.*/
|
||||
if (vtp->reload > (sysinterval_t)0) {
|
||||
sysinterval_t skipped_delta;
|
||||
|
||||
/* Calculating how much the real current time skipped past the
|
||||
hypothetical current deadline.*/
|
||||
skipped_delta = chTimeDiffX(vtp->last, now);
|
||||
|
||||
chDbgAssert(skipped_delta < vtp->reload, "skipped deadline");
|
||||
|
||||
/* Enqueuing the timer again using the calculated delta.*/
|
||||
vt_enqueue(vtlp, vtp, now, vtp->reload - skipped_delta);
|
||||
}
|
||||
|
||||
/* Next element in the list.*/
|
||||
dlp = vtlp->dlist.next;
|
||||
}
|
||||
|
@ -451,7 +534,8 @@ void chVTDoTickI(void) {
|
|||
|
||||
/* The "unprocessed nowdelta" time slice is added to "last time"
|
||||
and subtracted to next timer's delta.*/
|
||||
vtlp->lasttime += nowdelta;
|
||||
// vtlp->lasttime += nowdelta;
|
||||
vtlp->lasttime = chTimeAddX(vtlp->lasttime, nowdelta);
|
||||
vtlp->dlist.next->delta -= nowdelta;
|
||||
|
||||
/* Recalculating the next alarm time.*/
|
||||
|
|
|
@ -1,616 +0,0 @@
|
|||
/*
|
||||
ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
|
||||
2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
|
||||
|
||||
This file is part of ChibiOS.
|
||||
|
||||
ChibiOS is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation version 3 of the License.
|
||||
|
||||
ChibiOS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file rt/src/chvt.c
|
||||
* @brief Time and Virtual Timers module code.
|
||||
*
|
||||
* @addtogroup time
|
||||
* @details Time and Virtual Timers related APIs and services.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local definitions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local types. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local variables. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module local functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief List empty check.
|
||||
*
|
||||
* @param[in] dlhp pointer to the delta list header
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline bool is_vtlist_empty(delta_list_t *dlhp) {
|
||||
|
||||
return (bool)(dlhp == dlhp->next);
|
||||
}
|
||||
|
||||
#if (CH_CFG_ST_TIMEDELTA > 0) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Last timer in the list check.
|
||||
*
|
||||
* @param[in] dlhp pointer to the delta list header
|
||||
* @param[in] dlp pointer to the delta list element
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline bool is_last_timer(delta_list_t *dlhp, delta_list_t *dlp) {
|
||||
|
||||
return (bool)(dlp->next == dlhp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Fist timer in the list check.
|
||||
*
|
||||
* @param[in] dlhp pointer to the delta list header
|
||||
* @param[in] dlp pointer to the delta list element
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline bool is_first_timer(delta_list_t *dlhp, delta_list_t *dlp) {
|
||||
|
||||
return (bool)(dlhp->next == dlp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Timer check.
|
||||
*
|
||||
* @param[in] dlhp pointer to the delta list header
|
||||
* @param[in] dlp pointer to the delta list element
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static inline bool is_timer(delta_list_t *dlhp, delta_list_t *dlp) {
|
||||
|
||||
return (bool)(dlp != dlhp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Delta list compression.
|
||||
*
|
||||
* @param[in] vtlp pointer to the delta list to be compressed
|
||||
* @param[in] deltanow interval to be compacted starting from "lasttime"
|
||||
*
|
||||
* @notapi
|
||||
*/
|
||||
static void vt_list_compress(virtual_timers_list_t *vtlp,
|
||||
sysinterval_t deltanow) {
|
||||
delta_list_t *dlp = vtlp->dlist.next;
|
||||
|
||||
/* The loop is bounded because the delta list header has the delta field
|
||||
set to (sysinterval_t)-1 which is larger than all deltas.*/
|
||||
while (dlp->delta < deltanow) {
|
||||
deltanow -= dlp->delta;
|
||||
dlp->delta = (sysinterval_t)0;
|
||||
dlp = dlp->next;
|
||||
}
|
||||
|
||||
vtlp->lasttime = vtlp->lasttime + deltanow;
|
||||
|
||||
/* Adjusting next timer in the list, if any.*/
|
||||
if (is_timer(&vtlp->dlist, dlp)) {
|
||||
dlp->delta -= deltanow;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enqueues a virtual timer in a virtual timers list.
|
||||
*/
|
||||
static void vt_enqueue(virtual_timers_list_t *vtlp,
|
||||
virtual_timer_t *vtp,
|
||||
systime_t now,
|
||||
sysinterval_t delay) {
|
||||
delta_list_t *dlp;
|
||||
sysinterval_t delta;
|
||||
|
||||
#if CH_CFG_ST_TIMEDELTA > 0
|
||||
{
|
||||
sysinterval_t deltanow;
|
||||
|
||||
/* If the requested delay is lower than the minimum safe delta then it
|
||||
is raised to the minimum safe value.*/
|
||||
if (delay < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
|
||||
delay = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
|
||||
}
|
||||
|
||||
/* Special case where the timers list is empty.*/
|
||||
if (is_vtlist_empty(&vtlp->dlist)) {
|
||||
|
||||
/* The delta list is empty, the current time becomes the new
|
||||
delta list base time, the timer is inserted.*/
|
||||
vtlp->lasttime = now;
|
||||
vtlp->dlist.next = &vtp->dlist;
|
||||
vtlp->dlist.prev = &vtp->dlist;
|
||||
vtp->dlist.next = &vtlp->dlist;
|
||||
vtp->dlist.prev = &vtlp->dlist;
|
||||
vtp->dlist.delta = delay;
|
||||
|
||||
#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
|
||||
/* The delta could be too large for the physical timer to handle.*/
|
||||
if (delay > (sysinterval_t)TIME_MAX_SYSTIME) {
|
||||
delay = (sysinterval_t)TIME_MAX_SYSTIME;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Being the first element in the list the alarm timer is started.*/
|
||||
port_timer_start_alarm(chTimeAddX(vtlp->lasttime, delay));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Delay as delta from 'lasttime'. Note, it can overflow and the value
|
||||
becomes lower than 'deltanow'.*/
|
||||
deltanow = chTimeDiffX(vtlp->lasttime, now);
|
||||
delta = deltanow + delay;
|
||||
|
||||
/* Scenario where a very large delay exceeded the numeric range, it
|
||||
requires a special handling, the compression procedure.*/
|
||||
if (delta < deltanow) {
|
||||
vt_list_compress(vtlp, deltanow);
|
||||
delta -= deltanow;
|
||||
}
|
||||
else if (delta < vtlp->dlist.next->delta) {
|
||||
sysinterval_t deadline_delta;
|
||||
|
||||
/* A small delay that will become the first element in the delta list
|
||||
and next deadline.*/
|
||||
deadline_delta = delta;
|
||||
#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
|
||||
/* The delta could be too large for the physical timer to handle.*/
|
||||
if (deadline_delta > (sysinterval_t)TIME_MAX_SYSTIME) {
|
||||
deadline_delta = (sysinterval_t)TIME_MAX_SYSTIME;
|
||||
}
|
||||
#endif
|
||||
port_timer_set_alarm(chTimeAddX(vtlp->lasttime, deadline_delta));
|
||||
}
|
||||
}
|
||||
#else /* CH_CFG_ST_TIMEDELTA == 0 */
|
||||
/* Delta is initially equal to the specified delay.*/
|
||||
delta = delay;
|
||||
#endif /* CH_CFG_ST_TIMEDELTA == 0 */
|
||||
|
||||
/* The delta list is scanned in order to find the correct position for
|
||||
this timer. */
|
||||
dlp = vtlp->dlist.next;
|
||||
while (dlp->delta < delta) {
|
||||
/* Debug assert if the timer is already in the list.*/
|
||||
chDbgAssert(dlp != &vtp->dlist, "timer already armed");
|
||||
|
||||
delta -= dlp->delta;
|
||||
dlp = dlp->next;
|
||||
}
|
||||
|
||||
/* The timer is inserted in the delta list.*/
|
||||
vtp->dlist.next = dlp;
|
||||
vtp->dlist.prev = vtp->dlist.next->prev;
|
||||
vtp->dlist.prev->next = &vtp->dlist;
|
||||
dlp->prev = &vtp->dlist;
|
||||
vtp->dlist.delta = delta;
|
||||
|
||||
/* Calculate new delta for the following entry.*/
|
||||
dlp->delta -= delta;
|
||||
|
||||
/* Special case when the timer is in last position in the list, the
|
||||
value in the header must be restored.*/
|
||||
vtlp->dlist.delta = (sysinterval_t)-1;
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
/* Module exported functions. */
|
||||
/*===========================================================================*/
|
||||
|
||||
/**
|
||||
* @brief Enables a one-shot virtual timer.
|
||||
* @details The timer is enabled and programmed to trigger after the delay
|
||||
* specified as parameter.
|
||||
* @pre The timer must not be already armed before calling this function.
|
||||
* @note The callback function is invoked from interrupt context.
|
||||
*
|
||||
* @param[out] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void chVTDoSetI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||
systime_t now;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE));
|
||||
|
||||
/* Current system time.*/
|
||||
now = chVTGetSystemTimeX();
|
||||
|
||||
/* Timer initialization.*/
|
||||
vtp->par = par;
|
||||
vtp->func = vtfunc;
|
||||
vtp->last = now;
|
||||
vtp->reload = (sysinterval_t)0;
|
||||
|
||||
/* Inserting the timer in the delta list.*/
|
||||
vt_enqueue(vtlp, vtp, vtp->last, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enables a continuous virtual timer.
|
||||
* @details The timer is enabled and programmed to trigger after the delay
|
||||
* specified as parameter.
|
||||
* @pre The timer must not be already armed before calling this function.
|
||||
* @note The callback function is invoked from interrupt context.
|
||||
*
|
||||
* @param[out] vtp the @p virtual_timer_t structure pointer
|
||||
* @param[in] delay the number of ticks before the operation timeouts, the
|
||||
* special values are handled as follow:
|
||||
* - @a TIME_INFINITE is allowed but interpreted as a
|
||||
* normal time specification.
|
||||
* - @a TIME_IMMEDIATE this value is not allowed.
|
||||
* .
|
||||
* @param[in] vtfunc the timer callback function. After invoking the
|
||||
* callback the timer is disabled and the structure can
|
||||
* be disposed or reused.
|
||||
* @param[in] par a parameter that will be passed to the callback
|
||||
* function
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void chVTDoSetContinuousI(virtual_timer_t *vtp, sysinterval_t delay,
|
||||
vtfunc_t vtfunc, void *par) {
|
||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||
systime_t now;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (delay != TIME_IMMEDIATE));
|
||||
|
||||
/* Current system time.*/
|
||||
now = chVTGetSystemTimeX();
|
||||
|
||||
/* Timer initialization.*/
|
||||
vtp->par = par;
|
||||
vtp->func = vtfunc;
|
||||
vtp->last = now;
|
||||
vtp->reload = delay;
|
||||
|
||||
/* Inserting the timer in the delta list.*/
|
||||
vt_enqueue(vtlp, vtp, vtp->last, delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disables a Virtual Timer.
|
||||
* @pre The timer must be in armed state before calling this function.
|
||||
*
|
||||
* @param[in] vtp the @p virtual_timer_t structure pointer
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void chVTDoResetI(virtual_timer_t *vtp) {
|
||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||
|
||||
chDbgCheckClassI();
|
||||
chDbgCheck(vtp != NULL);
|
||||
chDbgAssert(chVTIsArmedI(vtp), "timer not armed");
|
||||
|
||||
#if CH_CFG_ST_TIMEDELTA == 0
|
||||
|
||||
/* The delta of the timer is added to the next timer.*/
|
||||
vtp->dlist.next->delta += vtp->dlist.delta;
|
||||
|
||||
/* Removing the element from the delta list, marking it as not armed.*/
|
||||
vtp->dlist.prev->next = vtp->dlist.next;
|
||||
vtp->dlist.next->prev = vtp->dlist.prev;
|
||||
vtp->dlist.next = NULL;
|
||||
|
||||
/* The above code changes the value in the header when the removed element
|
||||
is the last of the list, restoring it.*/
|
||||
vtlp->dlist.delta = (sysinterval_t)-1;
|
||||
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
sysinterval_t nowdelta, delta;
|
||||
|
||||
/* If the timer is not the first of the list then it is simply unlinked
|
||||
else the operation is more complex.*/
|
||||
if (!is_first_timer(&vtlp->dlist, &vtp->dlist)) {
|
||||
/* Removing the element from the delta list.*/
|
||||
vtp->dlist.prev->next = vtp->dlist.next;
|
||||
vtp->dlist.next->prev = vtp->dlist.prev;
|
||||
|
||||
/* Adding delta to the next element, if it is not the last one.*/
|
||||
if (is_timer(&vtlp->dlist, vtp->dlist.next))
|
||||
vtp->dlist.next->delta += vtp->dlist.delta;
|
||||
|
||||
/* Marking timer as not armed.*/
|
||||
vtp->dlist.next = NULL;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Removing the first timer from the list, marking it as not armed.*/
|
||||
vtlp->dlist.next = vtp->dlist.next;
|
||||
vtlp->dlist.next->prev = &vtlp->dlist;
|
||||
vtp->dlist.next = NULL;
|
||||
|
||||
/* If the list become empty then the alarm timer is stopped and done.*/
|
||||
if (is_vtlist_empty(&vtlp->dlist)) {
|
||||
port_timer_stop_alarm();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* The delta of the removed timer is added to the new first timer.*/
|
||||
vtlp->dlist.next->delta += vtp->dlist.delta;
|
||||
|
||||
/* If the new first timer has a delta of zero then the alarm is not
|
||||
modified, the already programmed alarm will serve it.*/
|
||||
/* if (vtlp->dlist.next->delta == 0) {
|
||||
return;
|
||||
}*/
|
||||
|
||||
/* Distance in ticks between the last alarm event and current time.*/
|
||||
nowdelta = chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX());
|
||||
|
||||
/* If the current time surpassed the time of the next element in list
|
||||
then the event interrupt is already pending, just return.*/
|
||||
if (nowdelta >= vtlp->dlist.next->delta) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Distance from the next scheduled event and now.*/
|
||||
delta = vtlp->dlist.next->delta - nowdelta;
|
||||
|
||||
/* Making sure to not schedule an event closer than CH_CFG_ST_TIMEDELTA
|
||||
ticks from now.*/
|
||||
if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
|
||||
delta = nowdelta + (sysinterval_t)CH_CFG_ST_TIMEDELTA;
|
||||
}
|
||||
else {
|
||||
delta = nowdelta + delta;
|
||||
#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
|
||||
/* The delta could be too large for the physical timer to handle.*/
|
||||
if (delta > (sysinterval_t)TIME_MAX_SYSTIME) {
|
||||
delta = (sysinterval_t)TIME_MAX_SYSTIME;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
port_timer_set_alarm(chTimeAddX(vtlp->lasttime, delta));
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Virtual timers ticker.
|
||||
* @note The system lock is released before entering the callback and
|
||||
* re-acquired immediately after. It is callback's responsibility
|
||||
* to acquire the lock if needed. This is done in order to reduce
|
||||
* interrupts jitter when many timers are in use.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void chVTDoTickI(void) {
|
||||
virtual_timers_list_t *vtlp = &currcore->vtlist;
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
#if CH_CFG_ST_TIMEDELTA == 0
|
||||
vtlp->systime++;
|
||||
if (!is_vtlist_empty(&vtlp->dlist)) {
|
||||
/* The list is not empty, processing elements on top.*/
|
||||
--vtlp->dlist.next->delta;
|
||||
while (vtlp->dlist.next->delta == (sysinterval_t)0) {
|
||||
virtual_timer_t *vtp;
|
||||
|
||||
/* Triggered timer.*/
|
||||
vtp = (virtual_timer_t *)vtlp->dlist.next;
|
||||
|
||||
/* Removing the element from the delta list, marking it as not armed.*/
|
||||
vtp->dlist.next->prev = &vtlp->dlist;
|
||||
vtlp->dlist.next = vtp->dlist.next;
|
||||
vtp->dlist.next = NULL;
|
||||
|
||||
chSysUnlockFromISR();
|
||||
vtp->func(vtp->par);
|
||||
chSysLockFromISR();
|
||||
}
|
||||
}
|
||||
#else /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
delta_list_t *dlp;
|
||||
sysinterval_t delta, nowdelta;
|
||||
systime_t now = chVTGetSystemTimeX();
|
||||
|
||||
/* Looping through timers.*/
|
||||
dlp = vtlp->dlist.next;
|
||||
while (true) {
|
||||
|
||||
/* Delta between current time and last execution time.*/
|
||||
nowdelta = chTimeDiffX(vtlp->lasttime, now);
|
||||
|
||||
/* The list scan is limited by the timers header having
|
||||
"vtlp->dlist.delta == (sysinterval_t)-1" which is
|
||||
greater than all deltas.*/
|
||||
if (nowdelta < dlp->delta) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Consuming all timers between "vtp->lasttime" and now.*/
|
||||
do {
|
||||
virtual_timer_t *vtp = (virtual_timer_t *)dlp;
|
||||
|
||||
/* The "last time" becomes this timer's expiration time.*/
|
||||
vtlp->lasttime += dlp->delta;
|
||||
nowdelta -= dlp->delta;
|
||||
|
||||
/* Removing the timer from the list, marking it as not armed.*/
|
||||
dlp->next->prev = &vtlp->dlist;
|
||||
vtlp->dlist.next = dlp->next;
|
||||
dlp->next = NULL;
|
||||
|
||||
/* If the list becomes empty then the timer is stopped.*/
|
||||
if (is_vtlist_empty(&vtlp->dlist)) {
|
||||
port_timer_stop_alarm();
|
||||
}
|
||||
|
||||
/* Now "last" marks the current deadline based on the stored
|
||||
reload value. It is done before calling the callback because
|
||||
the reload value could change. Note that "reload" could be
|
||||
zero, no harm.*/
|
||||
vtp->last = chTimeAddX(vtp->last, vtp->reload);
|
||||
|
||||
/* The callback is invoked outside the kernel critical zone.*/
|
||||
chSysUnlockFromISR();
|
||||
vtp->func(vtp->par);
|
||||
chSysLockFromISR();
|
||||
|
||||
/* Getting again the system time after executing the callback in
|
||||
order to reduce error.*/
|
||||
now = chVTGetSystemTimeX();
|
||||
|
||||
/* If a reload is defined the timer needs to be restarted.*/
|
||||
if (vtp->reload > (sysinterval_t)0) {
|
||||
sysinterval_t skipped_delta;
|
||||
|
||||
/* Calculating how much the real current time skipped past the
|
||||
hypothetical current deadline.*/
|
||||
skipped_delta = chTimeDiffX(vtp->last, now);
|
||||
|
||||
chDbgAssert(skipped_delta < vtp->reload, "skipped deadline");
|
||||
|
||||
/* Enqueuing the timer again using the calculated delta.*/
|
||||
vt_enqueue(vtlp, vtp, now, vtp->reload - skipped_delta);
|
||||
}
|
||||
|
||||
/* Next element in the list.*/
|
||||
dlp = vtlp->dlist.next;
|
||||
}
|
||||
while (dlp->delta <= nowdelta);
|
||||
}
|
||||
|
||||
/* If the list is empty, nothing else to do.*/
|
||||
if (is_vtlist_empty(&vtlp->dlist)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* The "unprocessed nowdelta" time slice is added to "last time"
|
||||
and subtracted to next timer's delta.*/
|
||||
// vtlp->lasttime += nowdelta;
|
||||
vtlp->lasttime = chTimeAddX(vtlp->lasttime, nowdelta);
|
||||
vtlp->dlist.next->delta -= nowdelta;
|
||||
|
||||
/* Recalculating the next alarm time.*/
|
||||
delta = dlp->delta - chTimeDiffX(vtlp->lasttime, now);
|
||||
if (delta < (sysinterval_t)CH_CFG_ST_TIMEDELTA) {
|
||||
delta = (sysinterval_t)CH_CFG_ST_TIMEDELTA;
|
||||
}
|
||||
#if CH_CFG_INTERVALS_SIZE > CH_CFG_ST_RESOLUTION
|
||||
/* The delta could be too large for the physical timer to handle.*/
|
||||
else if (delta > (sysinterval_t)TIME_MAX_SYSTIME) {
|
||||
delta = (sysinterval_t)TIME_MAX_SYSTIME;
|
||||
}
|
||||
#endif
|
||||
port_timer_set_alarm(chTimeAddX(now, delta));
|
||||
|
||||
chDbgAssert(chTimeDiffX(vtlp->lasttime, chVTGetSystemTimeX()) <=
|
||||
chTimeDiffX(vtlp->lasttime, chTimeAddX(now, delta)),
|
||||
"exceeding delta");
|
||||
#endif /* CH_CFG_ST_TIMEDELTA > 0 */
|
||||
}
|
||||
|
||||
#if (CH_CFG_USE_TIMESTAMP == TRUE) || defined(__DOXYGEN__)
|
||||
/**
|
||||
* @brief Generates a monotonic time stamp.
|
||||
* @details This function generates a monotonic time stamp synchronized with
|
||||
* the system time. The time stamp has the same resolution of
|
||||
* system time.
|
||||
* @note There is an assumption, this function must be called at
|
||||
* least once before the system time wraps back to zero or
|
||||
* synchronization is lost. You may use a periodic virtual timer with
|
||||
* a very large interval in order to keep time stamps synchronized
|
||||
* by calling this function.
|
||||
*
|
||||
* @return The time stamp.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
systimestamp_t chVTGetTimeStampI(void) {
|
||||
os_instance_t * oip = currcore;
|
||||
systimestamp_t last, stamp;
|
||||
systime_t now;
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
/* Current system time.*/
|
||||
now = chVTGetSystemTimeX();
|
||||
|
||||
/* Last time stamp generated.*/
|
||||
last = oip->vtlist.laststamp;
|
||||
|
||||
/* Interval between the last time stamp and current time used for a new
|
||||
time stamp. Note that this fails if the interval is larger than a
|
||||
systime_t type.*/
|
||||
stamp = last + (systimestamp_t)chTimeDiffX((systime_t)last, now);
|
||||
|
||||
chDbgAssert(oip->vtlist.laststamp <= stamp, "wrapped");
|
||||
|
||||
/* Storing the new stamp.*/
|
||||
oip->vtlist.laststamp = stamp;
|
||||
|
||||
return stamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets and re-synchronizes the time stamps monotonic counter.
|
||||
*
|
||||
* @iclass
|
||||
*/
|
||||
void chVTResetTimeStampI(void) {
|
||||
|
||||
chDbgCheckClassI();
|
||||
|
||||
currcore->vtlist.laststamp = (systimestamp_t)chVTGetSystemTimeX();
|
||||
}
|
||||
|
||||
#endif /* CH_CFG_USE_TIMESTAMP == TRUE */
|
||||
|
||||
/** @} */
|
|
@ -74,6 +74,7 @@
|
|||
*****************************************************************************
|
||||
|
||||
*** Next ***
|
||||
- NEW: Reload feature added to RT virtual timers.
|
||||
- NEW: Upgraded the clock initialization for STM32G0, STM32L4 and STM32L4++
|
||||
to the new standard (started with STM32G4).
|
||||
- NEW: Added support for STM32L422.
|
||||
|
|
|
@ -1,49 +1,42 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="3"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20 monitor reset init monitor sleep 50 "/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDeviceId" value="org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.OpenOCDSocket"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.REMOTE_TIMEOUT_ENABLED" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.REMOTE_TIMEOUT_VALUE" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
|
||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="build/stm32g474re_nucleo64/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TEST-RT-VT_STORM"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/TEST-RT-VT_STORM"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="reserved-for-future-use"/> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<launchConfiguration type="org.eclipse.cdt.debug.gdbjtag.launchConfigurationType">
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="3"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value="C:/_projects/chibios-trunk/testrt/VT_STORM/build/stm32g474re_nucleo64/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20 monitor reset init monitor sleep 50 "/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDeviceId" value="org.eclipse.cdt.debug.gdbjtag.core.jtagdevice.OpenOCDSocket"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.runCommands" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value="C:/_projects/chibios-trunk/testrt/VT_STORM/build/stm32g474re_nucleo64/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.REMOTE_TIMEOUT_ENABLED" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.REMOTE_TIMEOUT_VALUE" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
|
||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="C:/_projects/chibios-trunk/testrt/VT_STORM/build/stm32g474re_nucleo64/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TEST-RT-VT_STORM"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
</launchConfiguration>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.delay" value="3"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doHalt" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.doReset" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value="C:/_projects/chibios-trunk/testrt/VT_STORM/build/stm32g474re_nucleo64/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.initCommands" value="set remotetimeout 20 monitor reset init monitor sleep 50 "/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
|
||||
|
@ -17,12 +17,12 @@
|
|||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="main"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value="C:/_projects/chibios-trunk/testrt/VT_STORM/build/stm32g474re_nucleo64/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="arm-none-eabi-gdb"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.REMOTE_TIMEOUT_ENABLED" value="false"/>
|
||||
|
@ -31,18 +31,11 @@
|
|||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.DEBUGGER_START_MODE" value="remote"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="build/stm32g474re_nucleo64/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="C:/_projects/chibios-trunk/testrt/VT_STORM/build/stm32g474re_nucleo64/ch.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TEST-RT-VT_STORM"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="false"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/TEST-RT-VT_STORM"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
|
||||
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
|
||||
</listAttribute>
|
||||
</launchConfiguration>
|
||||
|
||||
|
|
Loading…
Reference in New Issue