diff options
| author | Yuval Adam <yuv.adm@gmail.com> | 2014-03-16 14:41:11 +0200 |
|---|---|---|
| committer | Yuval Adam <yuv.adm@gmail.com> | 2014-03-16 14:41:11 +0200 |
| commit | 990090a4cc9070837d31e66b58d40f0c3d038741 (patch) | |
| tree | cf1b905082c364e9b223e0c5058566103138dae5 /utils/scheduler.c | |
| parent | 7f4da522479c0f00126219f0c23b804c3a93d7a6 (diff) | |
Add usblib and utils
Diffstat (limited to 'utils/scheduler.c')
| -rw-r--r-- | utils/scheduler.c | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/utils/scheduler.c b/utils/scheduler.c new file mode 100644 index 0000000..bb66c4e --- /dev/null +++ b/utils/scheduler.c @@ -0,0 +1,310 @@ +//*****************************************************************************
+//
+// scheduler.c - A simple task scheduler
+//
+// Copyright (c) 2010-2014 Texas Instruments Incorporated. All rights reserved.
+// Software License Agreement
+//
+// Texas Instruments (TI) is supplying this software for use solely and
+// exclusively on TI's microcontroller products. The software is owned by
+// TI and/or its suppliers, and is protected under applicable copyright
+// laws. You may not combine this software with "viral" open-source
+// software in order to form a larger program.
+//
+// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
+// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
+// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
+// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+// DAMAGES, FOR ANY REASON WHATSOEVER.
+//
+// This is part of revision 2.1.0.12573 of the Tiva Utility Library.
+//
+//*****************************************************************************
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "inc/hw_types.h"
+#include "inc/hw_ints.h"
+#include "driverlib/systick.h"
+#include "driverlib/sysctl.h"
+#include "driverlib/interrupt.h"
+#include "driverlib/debug.h"
+#include "utils/scheduler.h"
+
+//*****************************************************************************
+//
+//! \addtogroup scheduler_api
+//! @{
+//
+//*****************************************************************************
+
+static volatile uint32_t g_ui32SchedulerTickCount;
+
+//*****************************************************************************
+//
+//! Handles the SysTick interrupt on behalf of the scheduler module.
+//!
+//! Applications using the scheduler module must ensure that this function is
+//! hooked to the SysTick interrupt vector.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SchedulerSysTickIntHandler(void)
+{
+ g_ui32SchedulerTickCount++;
+}
+
+//*****************************************************************************
+//
+//! Initializes the task scheduler.
+//!
+//! \param ui32TicksPerSecond sets the basic frequency of the SysTick interrupt
+//! used by the scheduler to determine when to run the various task functions.
+//!
+//! This function must be called during application startup to configure the
+//! SysTick timer. This is used by the scheduler module to determine when each
+//! of the functions provided in the g_psSchedulerTable array is called.
+//!
+//! The caller is responsible for ensuring that SchedulerSysTickIntHandler()
+//! has previously been installed in the SYSTICK vector in the vector table
+//! and must also ensure that interrupts are enabled at the CPU level.
+//!
+//! Note that this call does not start the scheduler calling the configured
+//! functions. All function calls are made in the context of later calls to
+//! SchedulerRun(). This call merely configures the SysTick interrupt that is
+//! used by the scheduler to determine what the current system time is.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SchedulerInit(uint32_t ui32TicksPerSecond)
+{
+ ASSERT(ui32TicksPerSecond);
+
+ //
+ // Configure SysTick for a periodic interrupt.
+ //
+ SysTickPeriodSet(SysCtlClockGet() / ui32TicksPerSecond);
+ SysTickEnable();
+ SysTickIntEnable();
+}
+
+//*****************************************************************************
+//
+//! Instructs the scheduler to update its task table and make calls to
+//! functions needing called.
+//!
+//! This function must be called periodically by the client to allow the
+//! scheduler to make calls to any configured task functions if it is their
+//! time to be called. The call must be made at least as frequently as the
+//! most frequent task configured in the g_psSchedulerTable array.
+//!
+//! Although the scheduler makes use of the SysTick interrupt, all calls to
+//! functions configured in \e g_psSchedulerTable are made in the context of
+//! SchedulerRun().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SchedulerRun(void)
+{
+ uint32_t ui32Loop;
+ tSchedulerTask *pi16Task;
+
+ //
+ // Loop through each task in the task table.
+ //
+ for(ui32Loop = 0; ui32Loop < g_ui32SchedulerNumTasks; ui32Loop++)
+ {
+ //
+ // Get a pointer to the task information.
+ //
+ pi16Task = &g_psSchedulerTable[ui32Loop];
+
+ //
+ // Is this task active and, if so, is it time to call it's function?
+ //
+ if(pi16Task->bActive &&
+ (SchedulerElapsedTicksGet(pi16Task->ui32LastCall) >=
+ pi16Task->ui32FrequencyTicks))
+ {
+ //
+ // Remember the timestamp at which we make the function call.
+ //
+ pi16Task->ui32LastCall = g_ui32SchedulerTickCount;
+
+ //
+ // Call the task function, passing the provided parameter.
+ //
+ pi16Task->pfnFunction(pi16Task->pvParam);
+ }
+ }
+}
+
+//*****************************************************************************
+//
+//! Enables a task and allows the scheduler to call it periodically.
+//!
+//! \param ui32Index is the index of the task which is to be enabled in the
+//! global \e g_psSchedulerTable array.
+//! \param bRunNow is \b true if the task is to be run on the next call to
+//! SchedulerRun() or \b false if one whole period is to elapse before the task
+//! is run.
+//!
+//! This function marks one of the configured tasks as enabled and causes
+//! SchedulerRun() to call that task periodically. The caller may choose to
+//! have the enabled task run for the first time on the next call to
+//! SchedulerRun() or to wait one full task period before making the first
+//! call.
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SchedulerTaskEnable(uint32_t ui32Index, bool bRunNow)
+{
+ //
+ // Is the task index passed valid?
+ //
+ if(ui32Index < g_ui32SchedulerNumTasks)
+ {
+ //
+ // Yes - mark the task as active.
+ //
+ g_psSchedulerTable[ui32Index].bActive = true;
+
+ //
+ // Set the last call time to ensure that the function is called either
+ // next time the scheduler is run or after the desired number of ticks
+ // depending upon the value of the bRunNow parameter.
+ //
+ if(bRunNow)
+ {
+ //
+ // Cause the task to run on the next call to SchedulerRun().
+ //
+ g_psSchedulerTable[ui32Index].ui32LastCall =
+ (g_ui32SchedulerTickCount -
+ g_psSchedulerTable[ui32Index].ui32FrequencyTicks);
+ }
+ else
+ {
+ //
+ // Cause the task to run after one full time period.
+ //
+ g_psSchedulerTable[ui32Index].ui32LastCall =
+ g_ui32SchedulerTickCount;
+ }
+ }
+}
+
+//*****************************************************************************
+//
+//! Disables a task and prevents the scheduler from calling it.
+//!
+//! \param ui32Index is the index of the task which is to be disabled in the
+//! global \e g_psSchedulerTable array.
+//!
+//! This function marks one of the configured tasks as inactive and prevents
+//! SchedulerRun() from calling it. The task may be reenabled by calling
+//! SchedulerTaskEnable().
+//!
+//! \return None.
+//
+//*****************************************************************************
+void
+SchedulerTaskDisable(uint32_t ui32Index)
+{
+ //
+ // Is the task index passed valid?
+ //
+ if(ui32Index < g_ui32SchedulerNumTasks)
+ {
+ //
+ // Yes - mark the task as inactive.
+ //
+ g_psSchedulerTable[ui32Index].bActive = false;
+ }
+}
+
+//*****************************************************************************
+//
+//! Returns the current system time in ticks since power on.
+//!
+//! This function may be called by a client to retrieve the current system
+//! time. The value returned is a count of ticks elapsed since the system
+//! last booted.
+//!
+//! \return Tick count since last boot.
+//
+//*****************************************************************************
+uint32_t
+SchedulerTickCountGet(void)
+{
+ return(g_ui32SchedulerTickCount);
+}
+
+//*****************************************************************************
+//
+//! Returns the number of ticks elapsed since the provided tick count.
+//!
+//! \param ui32TickCount is the tick count from which to determine the elapsed
+//! time.
+//!
+//! This function may be called by a client to determine how much time has
+//! passed since a particular tick count provided in the \e ui32TickCount
+//! parameter. This function takes into account wrapping of the global tick
+//! counter and assumes that the provided tick count always represents a time
+//! in the past. The returned value will, of course, be wrong if the tick
+//! counter has wrapped more than once since the passed \e ui32TickCount. As a
+//! result, please do not use this function if you are dealing with timeouts
+//! of 497 days or longer (assuming you use a 10mS tick period).
+//!
+//! \return The number of ticks elapsed since the provided tick count.
+//
+//*****************************************************************************
+uint32_t
+SchedulerElapsedTicksGet(uint32_t ui32TickCount)
+{
+ //
+ // Determine the calculation based upon whether the global tick count has
+ // wrapped since the passed ui32TickCount.
+ //
+ return(SchedulerElapsedTicksCalc(ui32TickCount, g_ui32SchedulerTickCount));
+}
+
+//*****************************************************************************
+//
+//! Returns the number of ticks elapsed between two times.
+//!
+//! \param ui32TickStart is the system tick count for the start of the period.
+//! \param ui32TickEnd is the system tick count for the end of the period.
+//!
+//! This function may be called by a client to determine the number of ticks
+//! which have elapsed between provided starting and ending tick counts. The
+//! function takes into account wrapping cases where the end tick count is
+//! lower than the starting count assuming that the ending tick count always
+//! represents a later time than the starting count.
+//!
+//! \return The number of ticks elapsed between the provided start and end
+//! counts.
+//
+//*****************************************************************************
+uint32_t
+SchedulerElapsedTicksCalc(uint32_t ui32TickStart, uint32_t ui32TickEnd)
+{
+ return((ui32TickEnd > ui32TickStart) ? (ui32TickEnd - ui32TickStart) :
+ ((0xFFFFFFFF - ui32TickStart) + ui32TickEnd + 1));
+}
+
+//*****************************************************************************
+//
+// Close the Doxygen group.
+//! @}
+//
+//*****************************************************************************
|
