|
|
@ -71,11 +71,11 @@
|
|
|
|
* incorporates a Cortex-M3 microcontroller.
|
|
|
|
* incorporates a Cortex-M3 microcontroller.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* The main() Function:
|
|
|
|
* The main() Function:
|
|
|
|
* main() creates three demo specific software timers, one demo specific queue,
|
|
|
|
* main() creates two demo specific software timers, one demo specific queue,
|
|
|
|
* and two demo specific tasks. It then creates a whole host of 'standard demo'
|
|
|
|
* and three demo specific tasks. It then creates a whole host of 'standard
|
|
|
|
* tasks/queues/semaphores, before starting the scheduler. The demo specific
|
|
|
|
* demo' tasks/queues/semaphores, before starting the scheduler. The demo
|
|
|
|
* tasks and timers are described in the comments here. The standard demo
|
|
|
|
* specific tasks and timers are described in the comments here. The standard
|
|
|
|
* tasks are described on the FreeRTOS.org web site.
|
|
|
|
* demo tasks are described on the FreeRTOS.org web site.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* The standard demo tasks provide no specific functionality. They are
|
|
|
|
* The standard demo tasks provide no specific functionality. They are
|
|
|
|
* included to both test the FreeRTOS port, and provide examples of how the
|
|
|
|
* included to both test the FreeRTOS port, and provide examples of how the
|
|
|
@ -102,6 +102,11 @@
|
|
|
|
* the Blocked state every 200 milliseconds, and therefore toggles the LED
|
|
|
|
* the Blocked state every 200 milliseconds, and therefore toggles the LED
|
|
|
|
* every 200 milliseconds.
|
|
|
|
* every 200 milliseconds.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
|
|
|
|
* The Demo Specific OLED Task:
|
|
|
|
|
|
|
|
* The OLED task is a very simple task that just scrolls a message across the
|
|
|
|
|
|
|
|
* OLED. Ideally this would be done in a timer, but the OLED driver accesses
|
|
|
|
|
|
|
|
* the I2C which is time consuming.
|
|
|
|
|
|
|
|
*
|
|
|
|
* The Demo Specific LED Software Timer and the Button Interrupt:
|
|
|
|
* The Demo Specific LED Software Timer and the Button Interrupt:
|
|
|
|
* The user button SW1 is configured to generate an interrupt each time it is
|
|
|
|
* The user button SW1 is configured to generate an interrupt each time it is
|
|
|
|
* pressed. The interrupt service routine switches an LED on, and resets the
|
|
|
|
* pressed. The interrupt service routine switches an LED on, and resets the
|
|
|
@ -110,10 +115,6 @@
|
|
|
|
* Therefore, pressing the user button will turn the LED on, and the LED will
|
|
|
|
* Therefore, pressing the user button will turn the LED on, and the LED will
|
|
|
|
* remain on until a full five seconds pass without the button being pressed.
|
|
|
|
* remain on until a full five seconds pass without the button being pressed.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* The Demo Specific OLED Software Timer:
|
|
|
|
|
|
|
|
* The OLED software timer is responsible for drawing a scrolling text message
|
|
|
|
|
|
|
|
* on the OLED.
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* The Demo Specific "Check" Callback Function:
|
|
|
|
* The Demo Specific "Check" Callback Function:
|
|
|
|
* This is called each time the 'check' timer expires. The check timer
|
|
|
|
* This is called each time the 'check' timer expires. The check timer
|
|
|
|
* callback function inspects all the standard demo tasks to see if they are
|
|
|
|
* callback function inspects all the standard demo tasks to see if they are
|
|
|
@ -122,7 +123,7 @@
|
|
|
|
* is ever discovered. The check timer callback toggles the LED defined by
|
|
|
|
* is ever discovered. The check timer callback toggles the LED defined by
|
|
|
|
* the mainCHECK_LED definition each time it executes. Therefore, if LED
|
|
|
|
* the mainCHECK_LED definition each time it executes. Therefore, if LED
|
|
|
|
* mainCHECK_LED is toggling every three seconds, then no error have been found.
|
|
|
|
* mainCHECK_LED is toggling every three seconds, then no error have been found.
|
|
|
|
* If LED mainCHECK_LED is toggling every 500ms, then at least one error has
|
|
|
|
* If LED mainCHECK_LED is toggling every 500ms, then at least one errors has
|
|
|
|
* been found. The task in which the error was discovered is displayed at the
|
|
|
|
* been found. The task in which the error was discovered is displayed at the
|
|
|
|
* bottom of the "task stats" page that is served by the embedded web server.
|
|
|
|
* bottom of the "task stats" page that is served by the embedded web server.
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -146,6 +147,7 @@
|
|
|
|
/* Microsemi drivers/libraries includes. */
|
|
|
|
/* Microsemi drivers/libraries includes. */
|
|
|
|
#include "mss_gpio.h"
|
|
|
|
#include "mss_gpio.h"
|
|
|
|
#include "mss_watchdog.h"
|
|
|
|
#include "mss_watchdog.h"
|
|
|
|
|
|
|
|
#include "mss_timer.h"
|
|
|
|
#include "oled.h"
|
|
|
|
#include "oled.h"
|
|
|
|
|
|
|
|
|
|
|
|
/* Common demo includes. */
|
|
|
|
/* Common demo includes. */
|
|
|
@ -193,6 +195,7 @@ the queue empty. */
|
|
|
|
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
|
|
|
#define mainCREATOR_TASK_PRIORITY ( tskIDLE_PRIORITY + 3 )
|
|
|
|
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
|
|
|
#define mainFLASH_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
|
|
|
#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
|
|
|
#define mainuIP_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
|
|
|
|
|
|
|
|
#define mainOLED_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
|
|
|
|
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
|
|
|
#define mainINTEGER_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
|
|
|
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
|
|
|
#define mainGEN_QUEUE_TASK_PRIORITY ( tskIDLE_PRIORITY )
|
|
|
|
|
|
|
|
|
|
|
@ -202,15 +205,19 @@ stack than most of the other tasks. */
|
|
|
|
|
|
|
|
|
|
|
|
/* The period at which the check timer will expire, in ms, provided no errors
|
|
|
|
/* The period at which the check timer will expire, in ms, provided no errors
|
|
|
|
have been reported by any of the standard demo tasks. */
|
|
|
|
have been reported by any of the standard demo tasks. */
|
|
|
|
#define mainCHECK_TIMER_PERIOD_ms ( 3000UL )
|
|
|
|
#define mainCHECK_TIMER_PERIOD_MS ( 3000UL / portTICK_RATE_MS )
|
|
|
|
|
|
|
|
|
|
|
|
/* The period at which the OLED timer will expire. Each time it expires, it's
|
|
|
|
/* The period at which the OLED timer will expire. Each time it expires, it's
|
|
|
|
callback function updates the OLED text. */
|
|
|
|
callback function updates the OLED text. */
|
|
|
|
#define mainOLED_PERIOD_ms ( 75UL )
|
|
|
|
#define mainOLED_PERIOD_MS ( 75UL / portTICK_RATE_MS )
|
|
|
|
|
|
|
|
|
|
|
|
/* The period at which the check timer will expire, in ms, if an error has been
|
|
|
|
/* The period at which the check timer will expire, in ms, if an error has been
|
|
|
|
reported in one of the standard demo tasks. */
|
|
|
|
reported in one of the standard demo tasks. */
|
|
|
|
#define mainERROR_CHECK_TIMER_PERIOD_ms ( 500UL )
|
|
|
|
#define mainERROR_CHECK_TIMER_PERIOD_MS ( 500UL / portTICK_RATE_MS )
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The LED will remain on until the button has not been pushed for a full
|
|
|
|
|
|
|
|
5000ms. */
|
|
|
|
|
|
|
|
#define mainLED_TIMER_PERIOD_MS ( 5000UL / portTICK_RATE_MS )
|
|
|
|
|
|
|
|
|
|
|
|
/* A zero block time. */
|
|
|
|
/* A zero block time. */
|
|
|
|
#define mainDONT_BLOCK ( 0UL )
|
|
|
|
#define mainDONT_BLOCK ( 0UL )
|
|
|
@ -231,17 +238,12 @@ static void prvQueueSendTask( void *pvParameters );
|
|
|
|
* The LED timer callback function. This does nothing but switch the red LED
|
|
|
|
* The LED timer callback function. This does nothing but switch the red LED
|
|
|
|
* off.
|
|
|
|
* off.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static void vLEDTimerCallback( xTimerHandle xTimer );
|
|
|
|
static void prvLEDTimerCallback( xTimerHandle xTimer );
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* The check timer callback function, as described at the top of this file.
|
|
|
|
* The check timer callback function, as described at the top of this file.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static void vCheckTimerCallback( xTimerHandle xTimer );
|
|
|
|
static void prvCheckTimerCallback( xTimerHandle xTimer );
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* The OLED timer callback function, as described at the top of this file.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void vOLEDTimerCallback( xTimerHandle xHandle );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* This is not a 'standard' partest function, so the prototype is not in
|
|
|
|
* This is not a 'standard' partest function, so the prototype is not in
|
|
|
@ -254,22 +256,26 @@ void vParTestSetLEDFromISR( unsigned portBASE_TYPE uxLED, signed portBASE_TYPE x
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
extern void vuIP_Task( void *pvParameters );
|
|
|
|
extern void vuIP_Task( void *pvParameters );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
* A very simply task that does nothing but scroll the OLED display. Ideally
|
|
|
|
|
|
|
|
* this would be done within a timer, but it accesses the I2C port which is
|
|
|
|
|
|
|
|
* time consuming.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void prvOLEDTask( void * pvParameters);
|
|
|
|
|
|
|
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
/* The queue used by both application specific demo tasks defined in this file. */
|
|
|
|
/* The queue used by both application specific demo tasks defined in this file. */
|
|
|
|
static xQueueHandle xQueue = NULL;
|
|
|
|
static xQueueHandle xQueue = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
/* The LED software timer. This uses vLEDTimerCallback() as it's callback
|
|
|
|
/* The LED software timer. This uses prvLEDTimerCallback() as it's callback
|
|
|
|
function. */
|
|
|
|
function. */
|
|
|
|
static xTimerHandle xLEDTimer = NULL;
|
|
|
|
static xTimerHandle xLEDTimer = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
/* The check timer. This uses vCheckTimerCallback() as it's callback
|
|
|
|
/* The check timer. This uses prvCheckTimerCallback() as it's callback
|
|
|
|
function. */
|
|
|
|
function. */
|
|
|
|
static xTimerHandle xCheckTimer = NULL;
|
|
|
|
static xTimerHandle xCheckTimer = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
/* The OLED software timer. Writes a moving text string to the OLED. */
|
|
|
|
|
|
|
|
static xTimerHandle xOLEDTimer = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The status message that is displayed at the bottom of the "task stats" web
|
|
|
|
/* The status message that is displayed at the bottom of the "task stats" web
|
|
|
|
page, which is served by the uIP task. This will report any errors picked up
|
|
|
|
page, which is served by the uIP task. This will report any errors picked up
|
|
|
|
by the check timer callback. */
|
|
|
|
by the check timer callback. */
|
|
|
@ -287,33 +293,31 @@ int main(void)
|
|
|
|
|
|
|
|
|
|
|
|
if( xQueue != NULL )
|
|
|
|
if( xQueue != NULL )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* Start the two application specific demo tasks, as described in the
|
|
|
|
/* Start the three application specific demo tasks, as described in the
|
|
|
|
comments at the top of this file. */
|
|
|
|
comments at the top of this file. */
|
|
|
|
xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
|
|
|
|
xTaskCreate( prvQueueReceiveTask, ( signed char * ) "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL );
|
|
|
|
xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
|
|
|
|
xTaskCreate( prvQueueSendTask, ( signed char * ) "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
|
|
|
|
|
|
|
|
xTaskCreate( prvOLEDTask, ( signed char * ) "OLED", configMINIMAL_STACK_SIZE, NULL, mainOLED_TASK_PRIORITY, NULL );
|
|
|
|
|
|
|
|
|
|
|
|
/* Create the software timer that is responsible for turning off the LED
|
|
|
|
/* Create the software timer that is responsible for turning off the LED
|
|
|
|
if the button is not pushed within 5000ms, as described at the top of
|
|
|
|
if the button is not pushed within 5000ms, as described at the top of
|
|
|
|
this file. */
|
|
|
|
this file. */
|
|
|
|
xLEDTimer = xTimerCreate( ( const signed char * ) "LEDTimer", /* A text name, purely to help debugging. */
|
|
|
|
xLEDTimer = xTimerCreate( ( const signed char * ) "LEDTimer", /* A text name, purely to help debugging. */
|
|
|
|
( 5000 / portTICK_RATE_MS ), /* The timer period, in this case 5000ms (5s). */
|
|
|
|
( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */
|
|
|
|
pdFALSE, /* This is a one shot timer, so xAutoReload is set to pdFALSE. */
|
|
|
|
pdFALSE, /* This is a one shot timer, so xAutoReload is set to pdFALSE. */
|
|
|
|
( void * ) 0, /* The ID is not used, so can be set to anything. */
|
|
|
|
( void * ) 0, /* The ID is not used, so can be set to anything. */
|
|
|
|
vLEDTimerCallback /* The callback function that switches the LED off. */
|
|
|
|
prvLEDTimerCallback /* The callback function that switches the LED off. */
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
/* Create the software timer that performs the 'check' functionality,
|
|
|
|
/* Create the software timer that performs the 'check' functionality,
|
|
|
|
as described at the top of this file. */
|
|
|
|
as described at the top of this file. */
|
|
|
|
xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */
|
|
|
|
xCheckTimer = xTimerCreate( ( const signed char * ) "CheckTimer",/* A text name, purely to help debugging. */
|
|
|
|
( mainCHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ),/* The timer period, in this case 3000ms (3s). */
|
|
|
|
( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */
|
|
|
|
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
|
|
|
|
pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */
|
|
|
|
( void * ) 0, /* The ID is not used, so can be set to anything. */
|
|
|
|
( void * ) 0, /* The ID is not used, so can be set to anything. */
|
|
|
|
vCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
|
|
|
|
prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */
|
|
|
|
);
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
|
|
/* Create the OLED timer as described at the top of this file. */
|
|
|
|
|
|
|
|
xOLEDTimer = xTimerCreate( ( const signed char * ) "OLEDTimer", ( mainOLED_PERIOD_ms / portTICK_RATE_MS ), pdTRUE, ( void * ) 0, vOLEDTimerCallback );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Create a lot of 'standard demo' tasks. */
|
|
|
|
/* Create a lot of 'standard demo' tasks. */
|
|
|
|
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
|
|
|
vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY );
|
|
|
|
vCreateBlockTimeTasks();
|
|
|
|
vCreateBlockTimeTasks();
|
|
|
@ -325,7 +329,13 @@ int main(void)
|
|
|
|
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
|
|
|
|
vStartTimerDemoTask( mainTIMER_TEST_PERIOD );
|
|
|
|
|
|
|
|
|
|
|
|
/* Create the web server task. */
|
|
|
|
/* Create the web server task. */
|
|
|
|
// xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainuIP_STACK_SIZE, NULL, mainuIP_TASK_PRIORITY, NULL );
|
|
|
|
xTaskCreate( vuIP_Task, ( signed char * ) "uIP", mainuIP_STACK_SIZE, NULL, mainuIP_TASK_PRIORITY, NULL );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The suicide tasks must be created last, as they need to know how many
|
|
|
|
|
|
|
|
tasks were running prior to their creation in order to ascertain whether
|
|
|
|
|
|
|
|
or not the correct/expected number of tasks are running at any given
|
|
|
|
|
|
|
|
time. */
|
|
|
|
|
|
|
|
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
|
|
|
|
|
|
|
|
|
|
|
|
/* Start the tasks and timer running. */
|
|
|
|
/* Start the tasks and timer running. */
|
|
|
|
vTaskStartScheduler();
|
|
|
|
vTaskStartScheduler();
|
|
|
@ -340,7 +350,7 @@ int main(void)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
static void vCheckTimerCallback( xTimerHandle xTimer )
|
|
|
|
static void prvCheckTimerCallback( xTimerHandle xTimer )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* Check the standard demo tasks are running without error. Latch the
|
|
|
|
/* Check the standard demo tasks are running without error. Latch the
|
|
|
|
latest reported error in the pcStatusMessage character pointer. */
|
|
|
|
latest reported error in the pcStatusMessage character pointer. */
|
|
|
@ -379,18 +389,18 @@ static void vCheckTimerCallback( xTimerHandle xTimer )
|
|
|
|
pcStatusMessage = "Error: RecMutex\r\n";
|
|
|
|
pcStatusMessage = "Error: RecMutex\r\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ) ) != pdTRUE )
|
|
|
|
if( xAreTimerDemoTasksStillRunning( ( mainCHECK_TIMER_PERIOD_MS ) ) != pdTRUE )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pcStatusMessage = "Error: TimerDemo";
|
|
|
|
pcStatusMessage = "Error: TimerDemo";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Toggle the check LED to give an indication of the system status. If
|
|
|
|
/* Toggle the check LED to give an indication of the system status. If
|
|
|
|
the LED toggles every mainCHECK_TIMER_PERIOD_ms milliseconds then
|
|
|
|
the LED toggles every mainCHECK_TIMER_PERIOD_MS milliseconds then
|
|
|
|
everything is ok. A faster toggle indicates an error. */
|
|
|
|
everything is ok. A faster toggle indicates an error. */
|
|
|
|
vParTestToggleLED( mainCHECK_LED );
|
|
|
|
vParTestToggleLED( mainCHECK_LED );
|
|
|
|
|
|
|
|
|
|
|
|
/* Have any errors been latch in pcStatusMessage? If so, shorten the
|
|
|
|
/* Have any errors been latch in pcStatusMessage? If so, shorten the
|
|
|
|
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_ms milliseconds.
|
|
|
|
period of the check timer to mainERROR_CHECK_TIMER_PERIOD_MS milliseconds.
|
|
|
|
This will result in an increase in the rate at which mainCHECK_LED
|
|
|
|
This will result in an increase in the rate at which mainCHECK_LED
|
|
|
|
toggles. */
|
|
|
|
toggles. */
|
|
|
|
if( pcStatusMessage != NULL )
|
|
|
|
if( pcStatusMessage != NULL )
|
|
|
@ -398,12 +408,12 @@ static void vCheckTimerCallback( xTimerHandle xTimer )
|
|
|
|
/* This call to xTimerChangePeriod() uses a zero block time. Functions
|
|
|
|
/* This call to xTimerChangePeriod() uses a zero block time. Functions
|
|
|
|
called from inside of a timer callback function must *never* attempt
|
|
|
|
called from inside of a timer callback function must *never* attempt
|
|
|
|
to block. */
|
|
|
|
to block. */
|
|
|
|
xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_ms / portTICK_RATE_MS ), mainDONT_BLOCK );
|
|
|
|
xTimerChangePeriod( xCheckTimer, ( mainERROR_CHECK_TIMER_PERIOD_MS ), mainDONT_BLOCK );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
static void vLEDTimerCallback( xTimerHandle xTimer )
|
|
|
|
static void prvLEDTimerCallback( xTimerHandle xTimer )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* The timer has expired - so no button pushes have occurred in the last
|
|
|
|
/* The timer has expired - so no button pushes have occurred in the last
|
|
|
|
five seconds - turn the LED off. */
|
|
|
|
five seconds - turn the LED off. */
|
|
|
@ -443,13 +453,6 @@ static void prvQueueSendTask( void *pvParameters )
|
|
|
|
portTickType xNextWakeTime;
|
|
|
|
portTickType xNextWakeTime;
|
|
|
|
const unsigned long ulValueToSend = 100UL;
|
|
|
|
const unsigned long ulValueToSend = 100UL;
|
|
|
|
|
|
|
|
|
|
|
|
/* The suicide tasks must be created last, as they need to know how many
|
|
|
|
|
|
|
|
tasks were running prior to their creation in order to ascertain whether
|
|
|
|
|
|
|
|
or not the correct/expected number of tasks are running at any given time.
|
|
|
|
|
|
|
|
Therefore the standard demo 'death' tasks are not created in main(), but
|
|
|
|
|
|
|
|
instead created here. */
|
|
|
|
|
|
|
|
vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The timer command queue will have been filled when the timer test tasks
|
|
|
|
/* The timer command queue will have been filled when the timer test tasks
|
|
|
|
were created in main() (this is part of the test they perform). Therefore,
|
|
|
|
were created in main() (this is part of the test they perform). Therefore,
|
|
|
|
while the check and OLED timers can be created in main(), they cannot be
|
|
|
|
while the check and OLED timers can be created in main(), they cannot be
|
|
|
@ -457,7 +460,6 @@ const unsigned long ulValueToSend = 100UL;
|
|
|
|
task will drain the command queue, and now the check and OLED timers can be
|
|
|
|
task will drain the command queue, and now the check and OLED timers can be
|
|
|
|
started successfully. */
|
|
|
|
started successfully. */
|
|
|
|
xTimerStart( xCheckTimer, portMAX_DELAY );
|
|
|
|
xTimerStart( xCheckTimer, portMAX_DELAY );
|
|
|
|
xTimerStart( xOLEDTimer, portMAX_DELAY );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialise xNextWakeTime - this only needs to be done once. */
|
|
|
|
/* Initialise xNextWakeTime - this only needs to be done once. */
|
|
|
|
xNextWakeTime = xTaskGetTickCount();
|
|
|
|
xNextWakeTime = xTaskGetTickCount();
|
|
|
@ -474,7 +476,7 @@ const unsigned long ulValueToSend = 100UL;
|
|
|
|
toggle an LED. 0 is used as the block time so the sending operation
|
|
|
|
toggle an LED. 0 is used as the block time so the sending operation
|
|
|
|
will not block - it shouldn't need to block as the queue should always
|
|
|
|
will not block - it shouldn't need to block as the queue should always
|
|
|
|
be empty at this point in the code. */
|
|
|
|
be empty at this point in the code. */
|
|
|
|
xQueueSend( xQueue, &ulValueToSend, 0 );
|
|
|
|
xQueueSend( xQueue, &ulValueToSend, mainDONT_BLOCK );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
@ -500,33 +502,20 @@ unsigned long ulReceivedValue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
static void vOLEDTimerCallback( xTimerHandle xHandle )
|
|
|
|
static void prvOLEDTask( void * pvParameters)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
volatile size_t xFreeStackSpace;
|
|
|
|
|
|
|
|
static struct oled_data xOLEDData;
|
|
|
|
static struct oled_data xOLEDData;
|
|
|
|
static unsigned char ucOffset1 = 0, ucOffset2 = 5;
|
|
|
|
static unsigned char ucOffset1 = 0, ucOffset2 = 5;
|
|
|
|
|
|
|
|
static portTickType xLastScrollTime = 0UL;
|
|
|
|
|
|
|
|
|
|
|
|
/* This function is called on each cycle of the idle task. In this case it
|
|
|
|
/* Initialise the display. */
|
|
|
|
does nothing useful, other than report the amount of FreeRTOS heap that
|
|
|
|
OLED_init();
|
|
|
|
remains unallocated. */
|
|
|
|
|
|
|
|
xFreeStackSpace = xPortGetFreeHeapSize();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( xFreeStackSpace > 100 )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* By now, the kernel has allocated everything it is going to, so
|
|
|
|
|
|
|
|
if there is a lot of heap remaining unallocated then
|
|
|
|
|
|
|
|
the value of configTOTAL_HEAP_SIZE in FreeRTOSConfig.h can be
|
|
|
|
|
|
|
|
reduced accordingly. */
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialise the parts of the oled_data structure that do not change. */
|
|
|
|
xOLEDData.line1 = FIRST_LINE;
|
|
|
|
xOLEDData.line1 = FIRST_LINE;
|
|
|
|
xOLEDData.char_offset1 = ucOffset1++;
|
|
|
|
|
|
|
|
xOLEDData.string1 = " www.FreeRTOS.org";
|
|
|
|
xOLEDData.string1 = " www.FreeRTOS.org";
|
|
|
|
|
|
|
|
|
|
|
|
xOLEDData.line2 = SECOND_LINE;
|
|
|
|
xOLEDData.line2 = SECOND_LINE;
|
|
|
|
xOLEDData.char_offset2 = ucOffset2++;
|
|
|
|
|
|
|
|
xOLEDData.string2 = " www.FreeRTOS.org";
|
|
|
|
xOLEDData.string2 = " www.FreeRTOS.org";
|
|
|
|
|
|
|
|
|
|
|
|
xOLEDData.contrast_val = OLED_CONTRAST_VAL;
|
|
|
|
xOLEDData.contrast_val = OLED_CONTRAST_VAL;
|
|
|
|
xOLEDData.on_off = OLED_HORIZ_SCROLL_OFF;
|
|
|
|
xOLEDData.on_off = OLED_HORIZ_SCROLL_OFF;
|
|
|
|
xOLEDData.column_scrool_per_step = OLED_HORIZ_SCROLL_STEP;
|
|
|
|
xOLEDData.column_scrool_per_step = OLED_HORIZ_SCROLL_STEP;
|
|
|
@ -534,21 +523,35 @@ static unsigned char ucOffset1 = 0, ucOffset2 = 5;
|
|
|
|
xOLEDData.time_intrval_btw_scroll_step = OLED_HORIZ_SCROLL_TINVL;
|
|
|
|
xOLEDData.time_intrval_btw_scroll_step = OLED_HORIZ_SCROLL_TINVL;
|
|
|
|
xOLEDData.end_page = OLED_END_PAGE;
|
|
|
|
xOLEDData.end_page = OLED_END_PAGE;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialise the last scroll time. This only needs to be done once,
|
|
|
|
|
|
|
|
because from this point on it will get automatically updated in the
|
|
|
|
|
|
|
|
xTaskDelayUntil() API function. */
|
|
|
|
|
|
|
|
xLastScrollTime = xTaskGetTickCount();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for( ;; )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Wait until it is time to update the OLED again. */
|
|
|
|
|
|
|
|
vTaskDelayUntil( &xLastScrollTime, mainOLED_PERIOD_MS );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
xOLEDData.char_offset1 = ucOffset1++;
|
|
|
|
|
|
|
|
xOLEDData.char_offset2 = ucOffset2++;
|
|
|
|
|
|
|
|
|
|
|
|
OLED_write_data( &xOLEDData, BOTH_LINES );
|
|
|
|
OLED_write_data( &xOLEDData, BOTH_LINES );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
static void prvSetupHardware( void )
|
|
|
|
static void prvSetupHardware( void )
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
SystemCoreClockUpdate();
|
|
|
|
|
|
|
|
|
|
|
|
/* Disable the Watch Dog Timer */
|
|
|
|
/* Disable the Watch Dog Timer */
|
|
|
|
MSS_WD_disable( );
|
|
|
|
MSS_WD_disable( );
|
|
|
|
|
|
|
|
|
|
|
|
/* Configure the GPIO for the LEDs. */
|
|
|
|
/* Configure the GPIO for the LEDs. */
|
|
|
|
vParTestInitialise();
|
|
|
|
vParTestInitialise();
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialise the display. */
|
|
|
|
|
|
|
|
OLED_init();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Setup the GPIO and the NVIC for the switch used in this simple demo. */
|
|
|
|
/* Setup the GPIO and the NVIC for the switch used in this simple demo. */
|
|
|
|
NVIC_SetPriority( GPIO8_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
|
|
|
NVIC_SetPriority( GPIO8_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
|
|
|
|
NVIC_EnableIRQ( GPIO8_IRQn );
|
|
|
|
NVIC_EnableIRQ( GPIO8_IRQn );
|
|
|
@ -616,3 +619,33 @@ char *pcGetTaskStatusMessage( void )
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void vMainConfigureTimerForRunTimeStats( void )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const unsigned long ulMax32BitValue = 0xffffffffUL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MSS_TIM64_init( MSS_TIMER_PERIODIC_MODE );
|
|
|
|
|
|
|
|
MSS_TIM64_load_immediate( ulMax32BitValue, ulMax32BitValue );
|
|
|
|
|
|
|
|
MSS_TIM64_start();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
unsigned long ulGetRunTimeCounterValue( void )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
unsigned long long ullCurrentValue;
|
|
|
|
|
|
|
|
const unsigned long long ulMax64BitValue = 0xffffffffffffffffULL;
|
|
|
|
|
|
|
|
unsigned long *pulHighWord, *pulLowWord;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pulHighWord = ( unsigned long * ) &ullCurrentValue;
|
|
|
|
|
|
|
|
pulLowWord = pulHighWord++;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MSS_TIM64_get_current_value( ( uint32_t * ) pulHighWord, ( uint32_t * ) pulLowWord );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Convert the down count into an upcount. */
|
|
|
|
|
|
|
|
ullCurrentValue = ulMax64BitValue - ullCurrentValue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Scale to a 32bit number of suitable frequency. */
|
|
|
|
|
|
|
|
ullCurrentValue >>= 13;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Just return 32 bits. */
|
|
|
|
|
|
|
|
return ( unsigned long ) ullCurrentValue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|