Commit 0e949aab authored by Colin González's avatar Colin González
Browse files

Firs attempts at porting FreeRTOS to AT91SAM9G20

parent 73904c4c
# Generic makefile
#-------------------------------------------------------------------------------
# User set options
#-------------------------------------------------------------------------------
CHIP = at91sam9g20
BOARD = at91sam9g20-ek
# Trace level used for compilation
# (can be overriden by adding TRACE_LEVEL=#number to the command-line)
# TRACE_LEVEL_DEBUG 5
# TRACE_LEVEL_INFO 4
# TRACE_LEVEL_WARNING 3
# TRACE_LEVEL_ERROR 2
# TRACE_LEVEL_FATAL 1
# TRACE_LEVEL_NO_TRACE 0
TRACE_LEVEL = 5
AT91LIB = src/at91lib
FREERTOS = src/freertos
# Output file basename
OUTPUT = img
# Compile with specific chip features
CHIP_CORE = arm926ej_s
CHIP_IP_MCI = MCI_PDC
CHIP_IP_UDP = USB_UDP
CHIP_IP_UHP = USB_OHCI
# Compile for all available memories
MEMORIES = sdram
# Output directories
BIN = bin
OBJ = obj
#-------------------------------------------------------------------------------
# Tools
#-------------------------------------------------------------------------------
# Tools suffix when cross-compiling
CROSS_COMPILE=arm-none-eabi-
# Compilation tools
CC = $(CROSS_COMPILE)gcc
SIZE = $(CROSS_COMPILE)size
STRIP = $(CROSS_COMPILE)strip
OBJCOPY = $(CROSS_COMPILE)objcopy
# Flags
INCLUDES = -I$(AT91LIB)/boards/$(BOARD)
INCLUDES += -I$(AT91LIB)/peripherals
INCLUDES += -I$(AT91LIB)/components
INCLUDES += -I$(AT91LIB)
INCLUDES += -I$(FREERTOS)/portable/GCC/ARM9_AT91SAM9G20
INCLUDES += -I$(FREERTOS)/portable/MemMang
INCLUDES += -I$(FREERTOS)/portable/
INCLUDES += -I$(FREERTOS)/include
INCLUDES += -I$(FREERTOS)
INCLUDES += -Isrc/
CFLAGS = -Wall -mlong-calls -ffunction-sections
#CFLAGS += -mthumb-interwork -D THUMB_INTERWORK
CFLAGS += -g $(INCLUDES) -D$(CHIP) -DTRACE_LEVE=$(TRACE_LEVEL)
ASFLAGS = -Wall -g $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__
LDFLAGS = -g -nostartfiles -Wl,--gc-sections
#-------------------------------------------------------------------------------
# FILES
#-------------------------------------------------------------------------------
# Directories where source files can be found
UTILITY = $(AT91LIB)/utility
PERIPH = $(AT91LIB)/peripherals
BOARDS = $(AT91LIB)/boards
PORT = $(FREERTOS)/portable/GCC/ARM9_AT91SAM9G20
MEM_MGT = $(FREERTOS)/portable/MemMang
VPATH = src/
VPATH += $(UTILITY)
VPATH += $(PERIPH)/dbgu
VPATH += $(PERIPH)/irq
VPATH += $(PERIPH)/pio
VPATH += $(PERIPH)/pit
VPATH += $(PERIPH)/tc
VPATH += $(PERIPH)/pmc
VPATH += $(PERIPH)/cp15
VPATH += $(PERIPH)/systicks
VPATH += $(BOARDS)/$(BOARD)
VPATH += $(BOARDS)/$(BOARD)/$(CHIP)
VPATH += $(MEM_MGT)
VPATH += $(PORT)
VPATH += $(FREERTOS)
# Objects build from C source files
C_OBJECTS = main.o
C_OBJECTS += led.o
C_OBJECTS += stdio.o
C_OBJECTS += dbgu.o
C_OBJECTS += pio.o
C_OBJECTS += pio_it.o
C_OBJECTS += tc.o
C_OBJECTS += pmc.o
C_OBJECTS += board_lowlevel.o
C_OBJECTS += trace.o
C_OBJECTS += board_memories.o
C_OBJECTS += aic.o
C_OBJECTS += cp15.o
C_OBJECTS += pit.o
C_OBJECTS += port.o
C_OBJECTS += tasks.o
C_OBJECTS += queue.o
C_OBJECTS += event_groups.o
C_OBJECTS += list.o
C_OBJECTS += stream_buffer.o
C_OBJECTS += timers.o
C_OBJECTS += heap_2.o
# Objects build with ARM instruction set from C source files
ARM_OBJECTS = portISR.o
# Objects build form assembly source files
ASM_OBJECTS = board_cstartup.o
ASM_OBJECTS += cp15_asm_gcc.o
#Append OBJ and BIN directories to output filename
OUTPUT := $(BIN)/$(OUTPUT)
#-------------------------------------------------------------------------------
# Rules
#-------------------------------------------------------------------------------
all: $(BIN) $(OBJ) $(MEMORIES)
phony: flash clean
$(BIN) $(OBJ):
mkdir $@
define RULES
ARM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ARM_OBJECTS))
C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS))
ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS))
$(1): $$(ARM_OBJECTS_$(1)) $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1))
$(CC) $(LDFLAGS) -T"$(AT91LIB)/boards/$(BOARD)/$(CHIP)/$$@.lds" \
-o $(OUTPUT)-$$@.elf $$^
$(OBJCOPY) -O binary $(OUTPUT)-$$@.elf $(OUTPUT)-$$@.bin
$(SIZE) $$^ $(OUTPUT)-$$@.elf
$$(ARM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
$(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
$$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(OBJ) $(BIN)
$(CC) $(CFLAGS) -D$(1) -c -o $$@ $$<
$$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(OBJ) $(BIN)
$(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$<
debug_$(1): $(1)
perl ../resources/gdb/debug.pl $(OUTPUT)-$(1).elf
endef
$(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY))))
flash:
./src/flashing/flash.sh
clean:
-rm -f $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf flash.log
#+STARTUP: overview
#+STARTUP: hidestars
#+TODO: TODO(t!) FOCUSED (f@/!) STARTED(s@/!) WAITING(w@/!) SOMEDAY(S@/!) URGENT (u!) | DONE(d!) CANCELED(c@!)
#+PRIORITIES: A C B
* Template for software developpment with AT91SAM9G20-EK based on FreeRTOS
** TODO Blink a led using high level functions
*** TODO Specification
**** Abstract
Our goal is to make a led blink on the AT91SAM9G20-EK board using
FreeRTOS high level functions.
In order to achieve this we need to obtain a port of the FreeRTOS
realtime operating system, write a blinky program, compile it,
flash it and verify our software.
Our standard programming language is the C programming language
with the current standard.
**** TODO Porting FreeRTOs
The FreeRTOS real time operating system is widely used and
documentation on it is extensive. FreeRTOS is not entirely
architecture indepent this is why we need to port some specific
file to work with our particular μ-controller.
Fortunately many ports of FreeRTOS are available including one
for the AT91SAM9XE, which is very similar to the microcontroller
of the AT91SAM9G20-EK, ie. AT91SAM9G20.
We rely on the FreeRTOS documentation and the FreeRTOS port for
the AT91SAM9XE to port FreeRTOS to our μ-controller.
The porting specification is dependent on the porting guide which
can be found on the following web site:
https://www.freertos.org/FreeRTOS-porting-guide.html.
In particular we need to port two files of the source directory.
Thos files are: Source/portable/port.c and
Source/portable/portmacro.h.
*** TODO Test
**** TODO Porting FreeRTOS
To the correctness of the port is somewhat difficult as the are
no specifications available.
Therefore we will be partiucarly carefull on compiler errors and
communicate with FreeRTOS community to seek for advice.
*** TODO Programming
**** TODO Porting FreeRTOS
We will use the official port to AT91SAM9XE for reference and the
atmel demo software, however we will implement everything form
scratch.
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
#define configCPU_CLOCK_HZ ( ( unsigned long ) BOARD_MCK )
#define configTICK_RATE_HZ ( (TickType_t) 1000 )
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configMAX_PRIORITIES ( 6 )
#define configMINIMAL_STACK_SIZE ( (unsigned short) 128 )
#define configTOTAL_HEAP_SIZE ( (size_t) (42 * 1024) )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 0
#define configUSE_APPLICATION_TASK_TAG 1
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
/* #define configYIELD_INTERRUPT_VECTOR 16UL */
/* #define configKERNEL_INTERRUPT_PRIORITY 1 */
/* #define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 */
/* void vApplicationSetupInterrupts( void ); */
#endif
/home/colin/Documents/apc/at91lib/
\ No newline at end of file
#! /bin/sh
sam-ba /dev/ttyACM0 at91sam9g20-ek src/flashing/nand-flash.tcl > flash.log 2>&1
true
set bootstrap "/home/colin/Documents/apc/at91bootstrap/binaries/at91sam9g20ek-nandflashboot--3.8.10.bin"
set img "/home/colin/Documents/apc/template-freertos/bin/img-sdram.bin"
NANDFLASH::Init
NANDFLASH::EraseAll
NANDFLASH::sendBootFile $bootstrap
send_file {NandFlash} "$img" 0x40000 0
set img "/home/colin/Documents/apc/template-freertos/bin/img-sdram.bin"
GENERIC::Init $RAM::appletAddr $RAM::appletMailboxAddr $RAM::appletFileName [list $::target(comType) $::target(traceLevel) $BOARD::extRamVdd $BOARD::extRamType $BOARD::extRamDataBusWidth $BOARD::extDDRamModel]
send_file {SDRAM} "$img" 0x20000000 0
go 0x20000000
/*
* FreeRTOS Kernel V10.0.1
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
#include "FreeRTOS.h"
#include "task.h"
#include "croutine.h"
/* Remove the whole file is co-routines are not being used. */
#if( configUSE_CO_ROUTINES != 0 )
/*
* Some kernel aware debuggers require data to be viewed to be global, rather
* than file scope.
*/
#ifdef portREMOVE_STATIC_QUALIFIER
#define static
#endif
/* Lists for ready and blocked co-routines. --------------------*/
static List_t pxReadyCoRoutineLists[ configMAX_CO_ROUTINE_PRIORITIES ]; /*< Prioritised ready co-routines. */
static List_t xDelayedCoRoutineList1; /*< Delayed co-routines. */
static List_t xDelayedCoRoutineList2; /*< Delayed co-routines (two lists are used - one for delays that have overflowed the current tick count. */
static List_t * pxDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used. */
static List_t * pxOverflowDelayedCoRoutineList; /*< Points to the delayed co-routine list currently being used to hold co-routines that have overflowed the current tick count. */
static List_t xPendingReadyCoRoutineList; /*< Holds co-routines that have been readied by an external event. They cannot be added directly to the ready lists as the ready lists cannot be accessed by interrupts. */
/* Other file private variables. --------------------------------*/
CRCB_t * pxCurrentCoRoutine = NULL;
static UBaseType_t uxTopCoRoutineReadyPriority = 0;
static TickType_t xCoRoutineTickCount = 0, xLastTickCount = 0, xPassedTicks = 0;
/* The initial state of the co-routine when it is created. */
#define corINITIAL_STATE ( 0 )
/*
* Place the co-routine represented by pxCRCB into the appropriate ready queue
* for the priority. It is inserted at the end of the list.
*
* This macro accesses the co-routine ready lists and therefore must not be
* used from within an ISR.
*/
#define prvAddCoRoutineToReadyQueue( pxCRCB ) \
{ \
if( pxCRCB->uxPriority > uxTopCoRoutineReadyPriority ) \
{ \
uxTopCoRoutineReadyPriority = pxCRCB->uxPriority; \
} \
vListInsertEnd( ( List_t * ) &( pxReadyCoRoutineLists[ pxCRCB->uxPriority ] ), &( pxCRCB->xGenericListItem ) ); \
}
/*
* Utility to ready all the lists used by the scheduler. This is called
* automatically upon the creation of the first co-routine.
*/
static void prvInitialiseCoRoutineLists( void );
/*
* Co-routines that are readied by an interrupt cannot be placed directly into
* the ready lists (there is no mutual exclusion). Instead they are placed in
* in the pending ready list in order that they can later be moved to the ready
* list by the co-routine scheduler.
*/
static void prvCheckPendingReadyList( void );
/*
* Macro that looks at the list of co-routines that are currently delayed to
* see if any require waking.
*
* Co-routines are stored in the queue in the order of their wake time -
* meaning once one co-routine has been found whose timer has not expired
* we need not look any further down the list.
*/
static void prvCheckDelayedList( void );
/*-----------------------------------------------------------*/
BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPriority, UBaseType_t uxIndex )
{
BaseType_t xReturn;
CRCB_t *pxCoRoutine;
/* Allocate the memory that will store the co-routine control block. */
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
if( pxCoRoutine )
{
/* If pxCurrentCoRoutine is NULL then this is the first co-routine to
be created and the co-routine data structures need initialising. */
if( pxCurrentCoRoutine == NULL )
{
pxCurrentCoRoutine = pxCoRoutine;
prvInitialiseCoRoutineLists();
}
/* Check the priority is within limits. */
if( uxPriority >= configMAX_CO_ROUTINE_PRIORITIES )
{
uxPriority = configMAX_CO_ROUTINE_PRIORITIES - 1;
}
/* Fill out the co-routine control block from the function parameters. */
pxCoRoutine->uxState = corINITIAL_STATE;
pxCoRoutine->uxPriority = uxPriority;
pxCoRoutine->uxIndex = uxIndex;
pxCoRoutine->pxCoRoutineFunction = pxCoRoutineCode;
/* Initialise all the other co-routine control block parameters. */
vListInitialiseItem( &( pxCoRoutine->xGenericListItem ) );
vListInitialiseItem( &( pxCoRoutine->xEventListItem ) );
/* Set the co-routine control block as a link back from the ListItem_t.
This is so we can get back to the containing CRCB from a generic item
in a list. */
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xGenericListItem ), pxCoRoutine );
listSET_LIST_ITEM_OWNER( &( pxCoRoutine->xEventListItem ), pxCoRoutine );
/* Event lists are always in priority order. */
listSET_LIST_ITEM_VALUE( &( pxCoRoutine->xEventListItem ), ( ( TickType_t ) configMAX_CO_ROUTINE_PRIORITIES - ( TickType_t ) uxPriority ) );
/* Now the co-routine has been initialised it can be added to the ready
list at the correct priority. */
prvAddCoRoutineToReadyQueue( pxCoRoutine );
xReturn = pdPASS;
}
else
{
xReturn = errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY;
}
return xReturn;
}
/*-----------------------------------------------------------*/
void vCoRoutineAddToDelayedList( TickType_t xTicksToDelay, List_t *pxEventList )
{
TickType_t xTimeToWake;
/* Calculate the time to wake - this may overflow but this is
not a problem. */
xTimeToWake = xCoRoutineTickCount + xTicksToDelay;
/* We must remove ourselves from the ready list before adding
ourselves to the blocked list as the same list item is used for
both lists. */
( void ) uxListRemove( ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
/* The list item will be inserted in wake time order. */
listSET_LIST_ITEM_VALUE( &( pxCurrentCoRoutine->xGenericListItem ), xTimeToWake );
if( xTimeToWake < xCoRoutineTickCount )
{
/* Wake time has overflowed. Place this item in the
overflow list. */
vListInsert( ( List_t * ) pxOverflowDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
}
else
{
/* The wake time has not overflowed, so we can use the
current block list. */
vListInsert( ( List_t * ) pxDelayedCoRoutineList, ( ListItem_t * ) &( pxCurrentCoRoutine->xGenericListItem ) );
}
if( pxEventList )
{
/* Also add the co-routine to an event list. If this is done then the
function must be called with interrupts disabled. */
vListInsert( pxEventList, &( pxCurrentCoRoutine->xEventListItem ) );
}
}
/*-----------------------------------------------------------*/
static void prvCheckPendingReadyList( void )
{
/* Are there any co-routines waiting to get moved to the ready list? These
are co-routines that have been readied by an ISR. The ISR cannot access
the ready lists itself. */
while( listLIST_IS_EMPTY( &xPendingReadyCoRoutineList ) == pdFALSE )
{
CRCB_t *pxUnblockedCRCB;
/* The pending ready list can be accessed by an ISR. */
portDISABLE_INTERRUPTS();
{
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( (&xPendingReadyCoRoutineList) );
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
}
portENABLE_INTERRUPTS();
( void ) uxListRemove( &( pxUnblockedCRCB->xGenericListItem ) );
prvAddCoRoutineToReadyQueue( pxUnblockedCRCB );
}
}
/*-----------------------------------------------------------*/
static void prvCheckDelayedList( void )
{
CRCB_t *pxCRCB;
xPassedTicks = xTaskGetTickCount() - xLastTickCount;
while( xPassedTicks )
{
xCoRoutineTickCount++;
xPassedTicks--;
/* If the tick count has overflowed we need to swap the ready lists. */
if( xCoRoutineTickCount == 0 )
{
List_t * pxTemp;
/* Tick count has overflowed so we need to swap the delay lists. If there are
any items in pxDelayedCoRoutineList here then there is an error! */
pxTemp = pxDelayedCoRoutineList;
pxDelayedCoRoutineList = pxOverflowDelayedCoRoutineList;
pxOverflowDelayedCoRoutineList = pxTemp;
}
/* See if this tick has made a timeout expire. */
while( listLIST_IS_EMPTY( pxDelayedCoRoutineList ) == pdFALSE )
{
pxCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxDelayedCoRoutineList );
if( xCoRoutineTickCount < listGET_LIST_ITEM_VALUE( &( pxCRCB->xGenericListItem ) ) )
{
/* Timeout not yet expired. */
break;
}
portDISABLE_INTERRUPTS();
{
/* The event could have occurred just before this critical
section. If this is the case then the generic list item will
have been moved to the pending ready list and the following
line is still valid. Also the pvContainer parameter will have
been set to NULL so the following lines are also valid. */
( void ) uxListRemove( &( pxCRCB->xGenericListItem ) );
/* Is the co-routine waiting on an event also? */
if( pxCRCB->xEventListItem.pvContainer )
{
( void ) uxListRemove( &( pxCRCB->xEventListItem ) );
}
}
portENABLE_INTERRUPTS();
prvAddCoRoutineToReadyQueue( pxCRCB );
}
}
xLastTickCount = xCoRoutineTickCount;
}
/*-----------------------------------------------------------*/
void vCoRoutineSchedule( void )
{
/* See if any co-routines readied by events need moving to the ready lists. */
prvCheckPendingReadyList();
/* See if any delayed co-routines have timed out. */
prvCheckDelayedList();
/* Find the highest priority queue that contains ready co-routines. */
while( listLIST_IS_EMPTY( &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) ) )
{
if( uxTopCoRoutineReadyPriority == 0 )
{
/* No more co-routines to check. */
return;
}
--uxTopCoRoutineReadyPriority;
}
/* listGET_OWNER_OF_NEXT_ENTRY walks through the list, so the co-routines
of the same priority get an equal share of the processor time. */
listGET_OWNER_OF_NEXT_ENTRY( pxCurrentCoRoutine, &( pxReadyCoRoutineLists[ uxTopCoRoutineReadyPriority ] ) );
/* Call the co-routine. */
( pxCurrentCoRoutine->pxCoRoutineFunction )( pxCurrentCoRoutine, pxCurrentCoRoutine->uxIndex );
return;
}
/*-----------------------------------------------------------*/
static void prvInitialiseCoRoutineLists( void )
{
UBaseType_t uxPriority;
for( uxPriority = 0; uxPriority < configMAX_CO_ROUTINE_PRIORITIES; uxPriority++ )
{
vListInitialise( ( List_t * ) &( pxReadyCoRoutineLists[ uxPriority ] ) );
}
vListInitialise( ( List_t * ) &xDelayedCoRoutineList1 );
vListInitialise( ( List_t * ) &xDelayedCoRoutineList2 );
vListInitialise( ( List_t * ) &xPendingReadyCoRoutineList );
/* Start with pxDelayedCoRoutineList using list1 and the
pxOverflowDelayedCoRoutineList using list2. */
pxDelayedCoRoutineList = &xDelayedCoRoutineList1;
pxOverflowDelayedCoRoutineList = &xDelayedCoRoutineList2;
}
/*-----------------------------------------------------------*/
BaseType_t xCoRoutineRemoveFromEventList( const List_t *pxEventList )
{
CRCB_t *pxUnblockedCRCB;
BaseType_t xReturn;
/* This function is called from within an interrupt. It can only access
event lists and the pending ready list. This function assumes that a
check has already been made to ensure pxEventList is not empty. */
pxUnblockedCRCB = ( CRCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxEventList );
( void ) uxListRemove( &( pxUnblockedCRCB->xEventListItem ) );
vListInsertEnd( ( List_t * ) &( xPendingReadyCoRoutineList ), &( pxUnblockedCRCB->xEventListItem ) );