Re-add in simple scheduler for compatibility with legacy code, mark all scheduler related files as deprecated.

pull/1469/head
Dean Camera 16 years ago
parent 8bc3a91c1f
commit 0d8679cf6b

@ -42,9 +42,17 @@
*/
USB_ClassInfo_CDC_Host_t VirtualSerial_CDC_Interface =
{
.DataINPipeNumber = 1,
.DataOUTPipeNumber = 2,
.NotificationPipeNumber = 3,
.Config =
{
.DataINPipeNumber = 1,
.DataOUTPipeNumber = 2,
.NotificationPipeNumber = 3,
},
.State =
{
// Leave all state values to their defaults
}
};
/** Main program entry point. This routine configures the hardware required by the application, then

File diff suppressed because one or more lines are too long

@ -34,7 +34,7 @@
#define INCLUDE_FROM_CDC_CLASS_HOST_C
#include "CDC.h"
static uint8_t CDC_Host_ProcessConfigDescriptor(void)
static uint8_t CDC_Host_ProcessConfigDescriptor(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
{
uint8_t* ConfigDescriptorData;
uint16_t ConfigDescriptorSize;
@ -59,13 +59,13 @@ static uint8_t CDC_Host_ProcessConfigDescriptor(void)
return CDC_ENUMERROR_NoCDCInterfaceFound;
}
while (FoundEndpoints != ((1 << CDC_NOTIFICATIONPIPE) | (1 << CDC_DATAPIPE_IN) | (1 << CDC_DATAPIPE_OUT)))
while (FoundEndpoints != (CDC_FOUND_DATAPIPE_IN | CDC_FOUND_DATAPIPE_OUT | CDC_FOUND_DATAPIPE_NOTIFICATION))
{
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
DComp_CDC_Host_NextInterfaceCDCDataEndpoint) != DESCRIPTOR_SEARCH_COMP_Found)
{
/* Check to see if the control interface's notification pipe has been found, if so search for the data interface */
if (FoundEndpoints & (1 << CDC_NOTIFICATIONPIPE))
if (FoundEndpoints & CDC_FOUND_DATAPIPE_NOTIFICATION)
{
/* Get the next CDC data interface from the configuration descriptor (CDC class has two CDC interfaces) */
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
@ -79,11 +79,11 @@ static uint8_t CDC_Host_ProcessConfigDescriptor(void)
{
FoundEndpoints = 0;
Pipe_SelectPipe(CDC_NOTIFICATIONPIPE);
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataINPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(CDC_DATAPIPE_IN);
Pipe_SelectPipe(CDCInterfaceInfo->Config.DataOUTPipeNumber);
Pipe_DisablePipe();
Pipe_SelectPipe(CDC_DATAPIPE_OUT);
Pipe_SelectPipe(CDCInterfaceInfo->Config.NotificationPipeNumber);
Pipe_DisablePipe();
if (USB_GetNextDescriptorComp(&ConfigDescriptorSize, &ConfigDescriptorData,
@ -106,35 +106,38 @@ static uint8_t CDC_Host_ProcessConfigDescriptor(void)
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(CDC_NOTIFICATIONPIPE, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.NotificationPipeNumber, EP_TYPE_INTERRUPT, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.NotificationPipeSize = EndpointData->EndpointSize;
Pipe_SetInfiniteINRequests();
Pipe_SetInterruptPeriod(EndpointData->PollingIntervalMS);
FoundEndpoints |= (1 << CDC_NOTIFICATIONPIPE);
FoundEndpoints |= CDC_FOUND_DATAPIPE_NOTIFICATION;
}
}
else
{
if (EndpointData->EndpointAddress & ENDPOINT_DESCRIPTOR_DIR_IN)
{
Pipe_ConfigurePipe(CDC_DATAPIPE_IN, EP_TYPE_BULK, PIPE_TOKEN_IN,
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataINPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_IN,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.DataINPipeSize = EndpointData->EndpointSize;
Pipe_SetInfiniteINRequests();
Pipe_Unfreeze();
FoundEndpoints |= (1 << CDC_DATAPIPE_IN);
FoundEndpoints |= CDC_FOUND_DATAPIPE_IN;
}
else
{
Pipe_ConfigurePipe(CDC_DATAPIPE_OUT, EP_TYPE_BULK, PIPE_TOKEN_OUT,
Pipe_ConfigurePipe(CDCInterfaceInfo->Config.DataOUTPipeNumber, EP_TYPE_BULK, PIPE_TOKEN_OUT,
EndpointData->EndpointAddress, EndpointData->EndpointSize, PIPE_BANK_SINGLE);
CDCInterfaceInfo->State.DataOUTPipeSize = EndpointData->EndpointSize;
Pipe_Unfreeze();
FoundEndpoints |= (1 << CDC_DATAPIPE_OUT);
FoundEndpoints |= CDC_FOUND_DATAPIPE_OUT;
}
}
}
@ -199,7 +202,7 @@ void CDC_Host_USBTask(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo)
switch (USB_HostState)
{
case HOST_STATE_Addressed:
if ((ErrorCode = CDC_Host_ProcessConfigDescriptor()) != SuccessfulConfigRead)
if ((ErrorCode = CDC_Host_ProcessConfigDescriptor(CDCInterfaceInfo)) != CDC_ENUMERROR_NoError)
{
USB_HostState = HOST_STATE_Unattached;
}

@ -50,18 +50,22 @@
#endif
/* Public Interface - May be used in end-application: */
/* Type Defines: */
/* Type Defines: */
/** Configuration information structure for \ref USB_ClassInfo_CDC_Host_t CDC host interface structures. */
typedef struct
{
uint8_t DataINPipeNumber; /**< Pipe number of the CDC interface's IN data pipe */
uint8_t DataOUTPipeNumber; /**< Pipe number of the CDC interface's OUT data pipe */
uint8_t NotificationPipeNumber; /**< Pipe number of the CDC interface's IN notification endpoint, if used */
} USB_ClassInfo_CDC_Host_Config_t;
/** Current State information structure for \ref USB_ClassInfo_CDC_Host_t CDC host interface structures. */
typedef struct
{
uint8_t ControlInterfaceNumber; /**< Interface number of the CDC control interface within the device */
uint8_t DataINPipeNumber; /**< Pipe number of the CDC interface's IN data pipe */
uint16_t DataINPipeSize; /**< Size in bytes of the CDC interface's IN data pipe */
uint8_t DataOUTPipeNumber; /**< Pipe number of the CDC interface's OUT data pipe */
uint16_t DataOUTPipeSize; /**< Size in bytes of the CDC interface's OUT data pipe */
uint8_t NotificationPipeNumber; /**< Pipe number of the CDC interface's IN notification endpoint, if used */
uint16_t NotificationPipeSize; /**< Size in bytes of the CDC interface's IN notification endpoint, if used */
uint8_t ControlLineState; /**< Current control line states */
@ -76,7 +80,27 @@
* CDCDevice_LineCodingParity_t enum
*/
uint8_t DataBits; /**< Bits of data per character of the virtual serial port */
} LineEncoding;
} LineEncoding;
} USB_ClassInfo_CDC_Host_State_t;
/** Class state structure. An instance of this structure should be made within the user application,
* and passed to each of the CDC class driver functions as the CDCInterfaceInfo parameter. This
* stores each CDC interface's configuration and state information.
*/
typedef struct
{
const USB_ClassInfo_CDC_Host_Config_t Config; /**< Config data for the USB class interface within
* the device. All elements in this section
* <b>must</b> be set or the interface will fail
* to enumerate and operate correctly.
*/
USB_ClassInfo_CDC_Host_State_t State; /**< State data for the USB class interface within
* the device. All elements in this section
* <b>may</b> be set to initial values, but may
* also be ignored to default to sane values when
* the interface is enumerated.
*/
} USB_ClassInfo_CDC_Host_t;
/* Enums: */
@ -96,16 +120,20 @@
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define CDC_CONTROL_CLASS 0x02
#define CDC_CONTROL_SUBCLASS 0x02
#define CDC_CONTROL_PROTOCOL 0x01
#define CDC_DATA_CLASS 0x0A
#define CDC_DATA_SUBCLASS 0x00
#define CDC_DATA_PROTOCOL 0x00
#define CDC_CONTROL_CLASS 0x02
#define CDC_CONTROL_SUBCLASS 0x02
#define CDC_CONTROL_PROTOCOL 0x01
#define CDC_DATA_CLASS 0x0A
#define CDC_DATA_SUBCLASS 0x00
#define CDC_DATA_PROTOCOL 0x00
#define CDC_FOUND_DATAPIPE_IN (1 << 0)
#define CDC_FOUND_DATAPIPE_OUT (1 << 1)
#define CDC_FOUND_DATAPIPE_NOTIFICATION (1 << 2)
/* Function Prototypes: */
#if defined(INCLUDE_FROM_CDC_CLASS_HOST_C)
static uint8_t CDC_Host_ProcessConfigDescriptor(void);
static uint8_t CDC_Host_ProcessConfigDescriptor(USB_ClassInfo_CDC_Host_t* CDCInterfaceInfo);
static uint8_t DComp_CDC_Host_NextCDCControlInterface(void* CurrentDescriptor);
static uint8_t DComp_CDC_Host_NextCDCDataInterface(void* CurrentDescriptor);
static uint8_t DComp_CDC_Host_NextInterfaceCDCDataEndpoint(void* CurrentDescriptor);

@ -17,5 +17,6 @@
* - \subpage Page_VIDPID Allocated USB VID and PID Values
* - \subpage Page_BuildLibrary Building as a Linkable Library
* - \subpage Page_WritingBoardDrivers How to Write Custom Board Drivers
* - \subpage Page_SchedulerOverview Overview of the Simple LUFA Scheduler (Deprecated)
*/

@ -13,8 +13,9 @@
* \section Sec_MigrationXXXXXX Migrating from 090605 to XXXXXX
*
* <b>All</b>
* - The "simple scheduler" has been removed, as it was little more than an abtracted loop and caused much confusion. User
* applications using the scheduler should switch to regular loops instead.
* - The "Simple Scheduler" has been deprecated, as it was little more than an abtracted loop and caused much confusion. User
* applications using the scheduler should switch to regular loops instead. The scheduler code will be removed in a future
* release.
* - The "Dynamic Memory Block Allocator" has been removed, as it was unused in (and unrelated to) the LUFA library and never
* used in user applications. The library is available from the author's website for those wishing to still use it in their
* applications.

@ -0,0 +1,95 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
#include "Scheduler.h"
volatile SchedulerDelayCounter_t Scheduler_TickCounter;
volatile uint8_t Scheduler_TotalTasks;
bool Scheduler_HasDelayElapsed(const uint16_t Delay, SchedulerDelayCounter_t* const DelayCounter)
{
SchedulerDelayCounter_t CurrentTickValue_LCL;
SchedulerDelayCounter_t DelayCounter_LCL;
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
CurrentTickValue_LCL = Scheduler_TickCounter;
}
DelayCounter_LCL = *DelayCounter;
if (CurrentTickValue_LCL >= DelayCounter_LCL)
{
if ((CurrentTickValue_LCL - DelayCounter_LCL) >= Delay)
{
*DelayCounter = CurrentTickValue_LCL;
return true;
}
}
else
{
if (((MAX_DELAYCTR_COUNT - DelayCounter_LCL) + CurrentTickValue_LCL) >= Delay)
{
*DelayCounter = CurrentTickValue_LCL;
return true;
}
}
return false;
}
void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus)
{
TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])
{
if (CurrTask->Task == Task)
{
CurrTask->TaskStatus = TaskStatus;
break;
}
CurrTask++;
}
}
void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus)
{
TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
while (CurrTask != &Scheduler_TaskList[Scheduler_TotalTasks])
{
if (CurrTask->GroupID == GroupID)
CurrTask->TaskStatus = TaskStatus;
CurrTask++;
}
}

@ -0,0 +1,289 @@
/*
LUFA Library
Copyright (C) Dean Camera, 2009.
dean [at] fourwalledcubicle [dot] com
www.fourwalledcubicle.com
*/
/*
Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the name of the author not be used in
advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
The author disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall the author be liable for any
special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
*/
/** \file
*
* Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need
* to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.
*
* \deprecated This module is deprecated and will be removed in a future library release.
*/
/** @defgroup Group_Scheduler Simple Task Scheduler - LUFA/Scheduler/Scheduler.h
*
* \deprecated This module is deprecated and will be removed in a future library release.
*
* \section Sec_Dependencies Module Source Dependencies
* The following files must be built with any user project that uses this module:
* - LUFA/Scheduler/Scheduler.c
*
* \section Module Description
* Simple round-robbin cooperative scheduler for use in basic projects where non real-time tasks need
* to be executed. Each task is executed in sequence, and can be enabled or disabled individually or as a group.
*
* For a task to yield it must return, thus each task should have persistent data marked with the static attribute.
*
* Usage Example:
* \code
* #include <LUFA/Scheduler/Scheduler.h>
*
* TASK(MyTask1);
* TASK(MyTask2);
*
* TASK_LIST
* {
* { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },
* { .Task = MyTask2, .TaskStatus = TASK_RUN, .GroupID = 1 },
* }
*
* int main(void)
* {
* Scheduler_Start();
* }
*
* TASK(MyTask1)
* {
* // Implementation Here
* }
*
* TASK(MyTask2)
* {
* // Implementation Here
* }
* \endcode
*
* @{
*/
#ifndef __SCHEDULER_H__
#define __SCHEDULER_H__
/* Includes: */
#include <avr/io.h>
#include <stdbool.h>
#include <util/atomic.h>
#include "../Common/Common.h"
/* Enable C linkage for C++ Compilers: */
#if defined(__cplusplus)
extern "C" {
#endif
/* Public Interface - May be used in end-application: */
/* Macros: */
/** Creates a new scheduler task body or prototype. Should be used in the form:
* \code
* TASK(TaskName); // Prototype
*
* TASK(TaskName)
* {
* // Task body
* }
* \endcode
*/
#define TASK(name) void name (void)
/** Defines a task list array, containing one or more task entries of the type TaskEntry_t. Each task list
* should be encased in curly braces and ended with a comma.
*
* Usage Example:
* \code
* TASK_LIST
* {
* { .Task = MyTask1, .TaskStatus = TASK_RUN, .GroupID = 1 },
* // More task entries here
* }
* \endcode
*/
#define TASK_LIST TaskEntry_t Scheduler_TaskList[] =
/** Constant, giving the maximum delay in scheduler ticks which can be stored in a variable of type
* SchedulerDelayCounter_t.
*/
#define TASK_MAX_DELAY (MAX_DELAYCTR_COUNT - 1)
/** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */
#define TASK_RUN true
/** Task status mode constant, for passing to Scheduler_SetTaskMode() or Scheduler_SetGroupTaskMode(). */
#define TASK_STOP false
/* Pseudo-Function Macros: */
#if defined(__DOXYGEN__)
/** Starts the scheduler in its infinite loop, executing running tasks. This should be placed at the end
* of the user application's main() function, as it can never return to the calling function.
*/
void Scheduler_Start(void);
/** Initializes the scheduler so that the scheduler functions can be called before the scheduler itself
* is started. This must be executed before any scheduler function calls other than Scheduler_Start(),
* and can be omitted if no such functions could be called before the scheduler is started.
*/
void Scheduler_Init(void);
#else
#define Scheduler_Start() Scheduler_GoSchedule(TOTAL_TASKS);
#define Scheduler_Init() Scheduler_InitScheduler(TOTAL_TASKS);
#endif
/* Type Defines: */
/** Type define for a pointer to a scheduler task. */
typedef void (*TaskPtr_t)(void);
/** Type define for a variable which can hold a tick delay value for the scheduler up to the maximum delay
* possible.
*/
typedef uint16_t SchedulerDelayCounter_t;
/** Structure for holding a single task's information in the scheduler task list. */
typedef struct
{
TaskPtr_t Task; /**< Pointer to the task to execute. */
bool TaskStatus; /**< Status of the task (either TASK_RUN or TASK_STOP). */
uint8_t GroupID; /**< Group ID of the task so that its status can be changed as a group. */
} TaskEntry_t;
/* Global Variables: */
/** Task entry list, containing the scheduler tasks, task statuses and group IDs. Each entry is of type
* TaskEntry_t and can be manipulated as desired, although it is preferential that the proper Scheduler
* functions should be used instead of direct manipulation.
*/
extern TaskEntry_t Scheduler_TaskList[];
/** Contains the total number of tasks in the task list, irrespective of if the task's status is set to
* TASK_RUN or TASK_STOP.
*
* \note This value should be treated as read-only, and never altered in user-code.
*/
extern volatile uint8_t Scheduler_TotalTasks;
/** Contains the current scheduler tick count, for use with the delay functions. If the delay functions
* are used in the user code, this should be incremented each tick period so that the delays can be
* calculated.
*/
extern volatile SchedulerDelayCounter_t Scheduler_TickCounter;
/* Inline Functions: */
/** Resets the delay counter value to the current tick count. This should be called to reset the period
* for a delay in a task which is dependant on the current tick value.
*
* \param DelayCounter Counter which is storing the starting tick count for a given delay.
*/
static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
ATTR_NON_NULL_PTR_ARG(1) ATTR_ALWAYS_INLINE;
static inline void Scheduler_ResetDelay(SchedulerDelayCounter_t* const DelayCounter)
{
ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
{
*DelayCounter = Scheduler_TickCounter;
}
}
/* Function Prototypes: */
/** Determines if the given tick delay has elapsed, based on the given .
*
* \param Delay The delay to test for, measured in ticks
* \param DelayCounter The counter which is storing the starting tick value for the delay
*
* \return Boolean true if the delay has elapsed, false otherwise
*
* Usage Example:
* \code
* static SchedulerDelayCounter_t DelayCounter = 10000; // Force immediate run on start-up
*
* // Task runs every 10000 ticks, 10 seconds for this demo
* if (Scheduler_HasDelayElapsed(10000, &DelayCounter))
* {
* // Code to execute after delay interval elapsed here
* }
* \endcode
*/
bool Scheduler_HasDelayElapsed(const uint16_t Delay,
SchedulerDelayCounter_t* const DelayCounter)
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(2);
/** Sets the task mode for a given task.
*
* \param Task Name of the task whose status is to be changed
* \param TaskStatus New task status for the task (TASK_RUN or TASK_STOP)
*/
void Scheduler_SetTaskMode(const TaskPtr_t Task, const bool TaskStatus);
/** Sets the task mode for a given task group ID, allowing for an entire group of tasks to have their
* statuses changed at once.
*
* \param GroupID Value of the task group ID whose status is to be changed
* \param TaskStatus New task status for tasks in the specified group (TASK_RUN or TASK_STOP)
*/
void Scheduler_SetGroupTaskMode(const uint8_t GroupID, const bool TaskStatus);
/* Private Interface - For use in library only: */
#if !defined(__DOXYGEN__)
/* Macros: */
#define TOTAL_TASKS (sizeof(Scheduler_TaskList) / sizeof(TaskEntry_t))
#define MAX_DELAYCTR_COUNT 0xFFFF
/* Inline Functions: */
static inline void Scheduler_InitScheduler(const uint8_t TotalTasks) ATTR_ALWAYS_INLINE;
static inline void Scheduler_InitScheduler(const uint8_t TotalTasks)
{
Scheduler_TotalTasks = TotalTasks;
}
static inline void Scheduler_GoSchedule(const uint8_t TotalTasks) ATTR_NO_RETURN ATTR_ALWAYS_INLINE;
static inline void Scheduler_GoSchedule(const uint8_t TotalTasks)
{
Scheduler_InitScheduler(TotalTasks);
for (;;)
{
TaskEntry_t* CurrTask = &Scheduler_TaskList[0];
while (CurrTask != &Scheduler_TaskList[TotalTasks])
{
if (CurrTask->TaskStatus == TASK_RUN)
CurrTask->Task();
CurrTask++;
}
}
}
#endif
/* Disable C linkage for C++ Compilers: */
#if defined(__cplusplus)
}
#endif
#endif
/** @} */
Loading…
Cancel
Save