From c8e31c4b2cc7ebbaddd79b9adf426737a80e0c54 Mon Sep 17 00:00:00 2001 From: richardbarry Date: Sun, 27 Aug 2006 14:12:15 +0000 Subject: [PATCH] Add Rowley CrossFire LPC2138 demo files. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@29 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- Demo/ARM7_LPC2138_Rowley/FreeRTOSConfig.h | 88 ++++++ Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzp | 54 ++++ Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzs | 84 ++++++ Demo/ARM7_LPC2138_Rowley/main.c | 330 ++++++++++++++++++++++ Demo/ARM7_LPC2138_Rowley/mainISR.c | 54 ++++ Demo/ARM7_LPC2138_Rowley/threads.js | 118 ++++++++ 6 files changed, 728 insertions(+) create mode 100644 Demo/ARM7_LPC2138_Rowley/FreeRTOSConfig.h create mode 100644 Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzp create mode 100644 Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzs create mode 100644 Demo/ARM7_LPC2138_Rowley/main.c create mode 100644 Demo/ARM7_LPC2138_Rowley/mainISR.c create mode 100644 Demo/ARM7_LPC2138_Rowley/threads.js diff --git a/Demo/ARM7_LPC2138_Rowley/FreeRTOSConfig.h b/Demo/ARM7_LPC2138_Rowley/FreeRTOSConfig.h new file mode 100644 index 000000000..fc3b3e084 --- /dev/null +++ b/Demo/ARM7_LPC2138_Rowley/FreeRTOSConfig.h @@ -0,0 +1,88 @@ +/* + FreeRTOS.org V4.0.5 - Copyright (C) 2003-2006 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org 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; either version 2 of the License, or + (at your option) any later version. + + FreeRTOS.org 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 FreeRTOS.org; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes FreeRTOS.org, without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details of how and when the exception + can be applied. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + *************************************************************************** +*/ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +#include +#define vPortYieldProcessor swi_handler + +/* For compatability with the LPC2106 header. */ +#define T0_IR T0IR +#define T0_PR T0PR +#define T0_MR0 T0MR0 +#define T0_MCR T0MCR +#define T0_TCR T0TCR + + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + *----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +/* In this case configCPU_CLOCK_HZ is actually set to the pclk frequency, not +the CPU frequency. */ +#define configCPU_CLOCK_HZ ( 58982400UL ) /* =14.7456MHz xtal multiplied by 4 using the PLL. */ +#define configTICK_RATE_HZ ( ( portTickType ) 1000 ) +#define configMAX_PRIORITIES ( ( unsigned portBASE_TYPE ) 6 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned portSHORT ) 128 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 18 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 15 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ + +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzp b/Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzp new file mode 100644 index 000000000..347ec08de --- /dev/null +++ b/Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzp @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzs b/Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzs new file mode 100644 index 000000000..9b458a753 --- /dev/null +++ b/Demo/ARM7_LPC2138_Rowley/RTOSDemo.hzs @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Demo/ARM7_LPC2138_Rowley/main.c b/Demo/ARM7_LPC2138_Rowley/main.c new file mode 100644 index 000000000..eb20551a1 --- /dev/null +++ b/Demo/ARM7_LPC2138_Rowley/main.c @@ -0,0 +1,330 @@ +/* + FreeRTOS.org V4.0.5 - Copyright (C) 2003-2006 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org 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; either version 2 of the License, or + (at your option) any later version. + + FreeRTOS.org 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 FreeRTOS.org; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes FreeRTOS.org, without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details of how and when the exception + can be applied. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + *************************************************************************** +*/ + +/* + * This file contains a demo created to execute on the Rowley Associates + * LPC2138 CrossFire development board. + * + * main() creates all the demo application tasks, then starts the scheduler. + * The WEB documentation provides more details of the standard demo application + * tasks. + * + * Main.c also creates a task called "Check". This only executes every few + * seconds but has a high priority so is guaranteed to get processor time. + * Its function is to check that all the other tasks are still operational. + * Each standard demo task maintains a unique count that is incremented each + * time the task successfully completes its function. Should any error occur + * within such a task the count is permanently halted. The check task inspects + * the count of each task to ensure it has changed since the last time the + * check task executed. If all the count variables have changed all the tasks + * are still executing error free, and the check task writes "PASS" to the + * CrossStudio terminal IO window. Should any task contain an error at any time + * the error is latched and "FAIL" written to the terminal IO window. + * + * Finally, main() sets up an interrupt service routine and task to handle + * pushes of the button that is built into the CrossFire board. When the button + * is pushed the ISR wakes the button task - which generates a table of task + * status information which is also displayed on the terminal IO window. + * + * A print task is defined to ensure exclusive and consistent access to the + * terminal IO. This is the only task that is allowed to access the terminal. + * The check and button task therefore do not access the terminal directly but + * instead pass a pointer to the message they wish to display to the print task. + */ + +/* Standard includes. */ +#include <__cross_studio_io.h> + +/* Scheduler includes. */ +#include "FreeRTOS.h" +#include "Task.h" +#include "queue.h" +#include "semphr.h" + +/* Demo app includes. */ +#include "BlockQ.h" +#include "death.h" +#include "dynamic.h" +#include "integer.h" +#include "PollQ.h" +#include "blocktim.h" + +/* Hardware configuration definitions. */ +#define mainBUS_CLK_FULL ( ( unsigned portCHAR ) 0x01 ) +#define mainLED_BIT 0x80000000 +#define mainP0_14__EINT_1 ( 2 << 28 ) +#define mainEINT_1_EDGE_SENSITIVE 2 +#define mainEINT_1_FALLING_EDGE_SENSITIVE 0 +#define mainEINT_1_CHANNEL 15 +#define mainEINT_1_VIC_CHANNEL_BIT ( 1 << mainEINT_1_CHANNEL ) +#define mainEINT_1_ENABLE_BIT ( 1 << 5 ) + +/* Demo application definitions. */ +#define mainQUEUE_SIZE ( 3 ) +#define mainLED_DELAY ( ( portTickType ) 500 / portTICK_RATE_MS ) +#define mainCHECK_DELAY ( ( portTickType ) 5000 / portTICK_RATE_MS ) +#define mainLIST_BUFFER_SIZE 2048 + +/* Task priorities. */ +#define mainLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainQUEUE_POLL_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainCHECK_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 ) +#define mainSEM_TEST_PRIORITY ( tskIDLE_PRIORITY + 1 ) +#define mainBLOCK_Q_PRIORITY ( tskIDLE_PRIORITY + 2 ) +#define mainPRINT_TASK_PRIORITY ( tskIDLE_PRIORITY + 0 ) + +/*-----------------------------------------------------------*/ + +/* The semaphore used to wake the button task from within the external interrupt +handler. */ +xSemaphoreHandle xButtonSemaphore; + +/* The queue that is used to send message to vPrintTask for display in the +terminal output window. */ +xQueueHandle xPrintQueue; + +/*-----------------------------------------------------------*/ + +/* + * Simply flashes the on board LED every mainLED_DELAY milliseconds. + */ +static void vLEDTask( void *pvParameters ); + +/* + * Checks the status of all the demo tasks then prints a message to the + * CrossStudio terminal IO windows. The message will be either PASS or FAIL + * depending on the status of the demo applications tasks. A FAIL status will + * be latched. + * + * Messages are not written directly to the terminal, but passed to vPrintTask + * via a queue. + */ +static void vCheckTask( void *pvParameters ); + +/* + * Controls all terminal output. If a task wants to send a message to the + * terminal IO it posts a pointer to the text to vPrintTask via a queue. This + * ensures serial access to the terminal IO. + */ +static void vPrintTask( void *pvParameter ); + +/* + * Simply waits for an interrupt to be generated from the built in button, then + * generates a table of tasks states that is then written by vPrintTask to the + * terminal output window within CrossStudio. + */ +static void vButtonHandlerTask( void *pvParameters ); + +/*-----------------------------------------------------------*/ + +int main( void ) +{ + /* Setup the peripheral bus to be the same as the PLL output. */ + VPBDIV = mainBUS_CLK_FULL; + + /* Create the queue used to pass message to vPrintTask. */ + xPrintQueue = xQueueCreate( mainQUEUE_SIZE, sizeof( portCHAR * ) ); + + /* Create the semaphore used to wake vButtonHandlerTask(). */ + vSemaphoreCreateBinary( xButtonSemaphore ); + xSemaphoreTake( xButtonSemaphore, 0 ); + + /* Start the standard demo tasks. */ + vStartIntegerMathTasks( tskIDLE_PRIORITY ); + vStartPolledQueueTasks( mainQUEUE_POLL_PRIORITY ); + vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); + vStartDynamicPriorityTasks(); + vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); + vCreateBlockTimeTasks(); + + /* Start the tasks defined within this file. */ + xTaskCreate( vLEDTask, "LED", configMINIMAL_STACK_SIZE, NULL, mainLED_TASK_PRIORITY, NULL ); + xTaskCreate( vCheckTask, "Check", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); + xTaskCreate( vPrintTask, "Print", configMINIMAL_STACK_SIZE, NULL, mainPRINT_TASK_PRIORITY, NULL ); + xTaskCreate( vButtonHandlerTask, "Button", configMINIMAL_STACK_SIZE, NULL, mainCHECK_TASK_PRIORITY, NULL ); + + /* Start the scheduler. */ + vTaskStartScheduler(); + + /* The scheduler should now running, so we will only ever reach here if we + ran out of heap space. */ + + return 0; +} +/*-----------------------------------------------------------*/ + +static void vLEDTask( void *pvParameters ) +{ + /* Configure IO. */ + IO0DIR |= mainLED_BIT; + IO0SET = mainLED_BIT; + + for( ;; ) + { + /* Not very exiting - just delay... */ + vTaskDelay( mainLED_DELAY ); + + /* ...set the IO ... */ + IO0CLR = mainLED_BIT; + + /* ...delay again... */ + vTaskDelay( mainLED_DELAY ); + + /* ...then clear the IO. */ + IO0SET = mainLED_BIT; + } +} +/*-----------------------------------------------------------*/ + +static void vCheckTask( void *pvParameters ) +{ +portBASE_TYPE xErrorOccurred = pdFALSE; +portTickType xLastExecutionTime; +const portCHAR * const pcPassMessage = "PASS\n"; +const portCHAR * const pcFailMessage = "FAIL\n"; + + /* Initialise xLastExecutionTime so the first call to vTaskDelayUntil() + works correctly. */ + xLastExecutionTime = xTaskGetTickCount(); + + for( ;; ) + { + /* Perform this check every mainCHECK_DELAY milliseconds. */ + vTaskDelayUntil( &xLastExecutionTime, mainCHECK_DELAY ); + + /* Has an error been found in any task? */ + + if( xAreIntegerMathsTaskStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + if( xArePollingQueuesStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + if( xAreSemaphoreTasksStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + if( xAreDynamicPriorityTasksStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + if( xAreBlockingQueuesStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + if( xAreBlockTimeTestTasksStillRunning() != pdTRUE ) + { + xErrorOccurred = pdTRUE; + } + + /* Send either a pass or fail message. If an error is found it is + never cleared again. */ + if( xErrorOccurred == pdTRUE ) + { + xQueueSend( xPrintQueue, &pcFailMessage, portMAX_DELAY ); + } + else + { + xQueueSend( xPrintQueue, &pcPassMessage, portMAX_DELAY ); + } + } +} +/*-----------------------------------------------------------*/ + +static void vPrintTask( void *pvParameters ) +{ +portCHAR *pcMessage; + + for( ;; ) + { + /* Wait for a message to arrive. */ + while( xQueueReceive( xPrintQueue, &pcMessage, portMAX_DELAY ) != pdPASS ); + + /* Write the message to the terminal IO. */ + debug_printf( "%s", pcMessage ); + } +} +/*-----------------------------------------------------------*/ + +static void vButtonHandlerTask( void *pvParameters ) +{ +static portCHAR cListBuffer[ mainLIST_BUFFER_SIZE ]; +const portCHAR *pcList = &( cListBuffer[ 0 ] ); +const portCHAR * const pcHeader = "\nTask State Priority Stack #\n************************************************"; +extern void (vButtonISR) ( void ); + + /* Configure the interrupt. */ + portENTER_CRITICAL(); + { + /* Configure P0.14 to generate interrupts. */ + PINSEL0 |= mainP0_14__EINT_1; + EXTMODE = mainEINT_1_EDGE_SENSITIVE; + EXTPOLAR = mainEINT_1_FALLING_EDGE_SENSITIVE; + + /* Setup the VIC for EINT 1. */ + VICIntSelect &= ~mainEINT_1_VIC_CHANNEL_BIT; + VICIntEnable |= mainEINT_1_VIC_CHANNEL_BIT; + VICVectAddr1 = ( portLONG ) vButtonISR; + VICVectCntl1 = mainEINT_1_ENABLE_BIT | mainEINT_1_CHANNEL; + } + portEXIT_CRITICAL(); + + for( ;; ) + { + /* Wait for an interrupt. */ + while( xSemaphoreTake( xButtonSemaphore, portMAX_DELAY ) != pdPASS ); + + /* Send the column headers to the print task for display. */ + xQueueSend( xPrintQueue, &pcHeader, portMAX_DELAY ); + + /* Create the list of task states. */ + vTaskList( cListBuffer ); + + /* Send the task status information to the print task for display. */ + xQueueSend( xPrintQueue, &pcList, portMAX_DELAY ); + } +} +/*-----------------------------------------------------------*/ + + + + + + + diff --git a/Demo/ARM7_LPC2138_Rowley/mainISR.c b/Demo/ARM7_LPC2138_Rowley/mainISR.c new file mode 100644 index 000000000..8ea683007 --- /dev/null +++ b/Demo/ARM7_LPC2138_Rowley/mainISR.c @@ -0,0 +1,54 @@ +/* + FreeRTOS.org V4.0.5 - Copyright (C) 2003-2006 Richard Barry. + + This file is part of the FreeRTOS.org distribution. + + FreeRTOS.org 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; either version 2 of the License, or + (at your option) any later version. + + FreeRTOS.org 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 FreeRTOS.org; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + A special exception to the GPL can be applied should you wish to distribute + a combined work that includes FreeRTOS.org, without being obliged to provide + the source code for any proprietary components. See the licensing section + of http://www.FreeRTOS.org for full details of how and when the exception + can be applied. + + *************************************************************************** + See http://www.FreeRTOS.org for documentation, latest information, license + and contact details. Please ensure to read the configuration and relevant + port sections of the online documentation. + *************************************************************************** +*/ +#include "FreeRTOS.h" +#include "semphr.h" + +#define isrCLEAR_EINT_1 2 + +/* + * Interrupt routine that simply wakes vButtonHandlerTask on each interrupt + * generated by a push of the built in button. + */ +void vButtonISR( void ) __attribute__ ((naked)); +extern xSemaphoreHandle xButtonSemaphore; + +void vButtonISR( void ) +{ + portENTER_SWITCHING_ISR(); + xSemaphoreGiveFromISR( xButtonSemaphore, pdFALSE ); + EXTINT = isrCLEAR_EINT_1; + VICVectAddr = 0; + portEXIT_SWITCHING_ISR( pdTRUE ); +} + + + diff --git a/Demo/ARM7_LPC2138_Rowley/threads.js b/Demo/ARM7_LPC2138_Rowley/threads.js new file mode 100644 index 000000000..819d7c6bc --- /dev/null +++ b/Demo/ARM7_LPC2138_Rowley/threads.js @@ -0,0 +1,118 @@ +function decode_stack(sp) +{ + var i; + var a = new Array(); + + var current_task; + + current_task = Debug.evaluate("pxCurrentTCB"); + + if( current_task == 0 ) + return; + + sp += 4; /* skip stored ulCriticalNesting */ + a[16] = Debug.evaluate("*(unsigned long*)" + sp); + + for (i = 0; i <= 15; i++) + { + sp += 4; + a[i] = Debug.evaluate("*(unsigned long*)" + sp); + } + + return a; +} + +function add_task(task, state) +{ + var tcb, task_name; + + var current_task; + + current_task = Debug.evaluate("pxCurrentTCB"); + + if( current_task == 0 ) + return; + + tcb = Debug.evaluate("*(tskTCB *)" + task); + task_name = Debug.evaluate("(char*)&(*(tskTCB *)" + task + ").pcTaskName[0]"); + Threads.add("#" + tcb.uxTCBNumber + " \"" + task_name + "\"", tcb.uxPriority, state, decode_stack(tcb.pxTopOfStack)); +} + +function add_list(list, state, current_task) +{ + var i, index, item, end; + var current_task; + + current_task = Debug.evaluate("pxCurrentTCB"); + + if( current_task == 0 ) + return; + + if (list.uxNumberOfItems) + { + index = list.pxIndex; + end = list.xListEnd; + for (i = 0; i < list.uxNumberOfItems + 1; i++) + { + item = Debug.evaluate("*(xListItem *)" + index); + if (index != end) + { + task = item.pvOwner; + if (task) add_task(task, (task == current_task) ? "executing" : state); + } + index = item.pxNext; + } + } +} + +function update() +{ + var i, current_task, list, lists, max_priority; + + Threads.clear(); + + current_task = Debug.evaluate("pxCurrentTCB"); + + if( current_task == 0 ) + return; + + Threads.newqueue("Ready"); + lists = Debug.evaluate("pxReadyTasksLists"); + if (lists) + { + max_priority = Debug.evaluate("uxTopUsedPriority"); + max_priority = Debug.evaluate("*(long *)" + max_priority); + + for (i = 0; i <= max_priority; i++) + { + list = Debug.evaluate("((xList*)" + lists + ")[" + (max_priority - i) + "]"); + add_list(list, "ready", current_task); + } + } + + Threads.newqueue("Blocked"); + + list = Debug.evaluate("pxDelayedTaskList"); + if (list) + { + list = Debug.evaluate("**(xList **)" + list); + add_list(list, "blocked"); + } + + list = Debug.evaluate("pxOverflowDelayedTaskList"); + if (list) + { + list = Debug.evaluate("**(xList **)" + list); + add_list(list, "blocked"); + } + + Threads.newqueue("Suspended"); + + list = Debug.evaluate("xSuspendedTaskList"); + if (list) + { + list = Debug.evaluate("*(xList *)" + list); + add_list(list, "suspended"); + } +} + -- 2.39.2