Add additional NOPs as required by hardware manual.

Microblaze:
Previously a task inherited the exception enable state from the context from which xTaskCreate() was called.  Now tasks all have exceptions enabled if they are enabled in the hardware.

Windows/GCC:
Improve the implementation of portGET_HIGHEST_PRIORITY.

Common code:
Simplify the pointer use in xQueueGenericCreate()

Demo apps: 
Remove jpg images that were used to create web pages.
Fix capitalisation issues in some demos where some header files are incldued with the wrong case, preventing building on Linux.
Remove the Microblaze demos that are using obsolete tools.
Update main_blinky for the Windows port demo to include a software timer example.
This commit is contained in:
Richard Barry 2015-07-26 16:41:12 +00:00
parent 95b73d40d9
commit d3e053568d
157 changed files with 157 additions and 65765 deletions

View file

@ -68,15 +68,12 @@
*/
/******************************************************************************
* NOTE 1: The Win32 port is a simulation (or is that emulation?) only! Do not
* expect to get real time behaviour from the Win32 port or this demo
* application. It is provided as a convenient development and demonstration
* test bed only. This was tested using Windows XP on a dual core laptop.
*
* Windows will not be running the FreeRTOS simulator threads continuously, so
* the timing information in the FreeRTOS+Trace logs have no meaningful units.
* See the documentation page for the Windows simulator for an explanation of
* the slow timing:
* NOTE 1: Do not expect to get real time behaviour from the Win32 port or this
* demo application. It is provided as a convenient development and
* demonstration test bed only. Windows will not be running the FreeRTOS
* threads continuously, so the timing information in the FreeRTOS+Trace logs
* have no meaningful units. See the documentation page for the Windows
* simulator for further explanation:
* http://www.freertos.org/FreeRTOS-Windows-Simulator-Emulator-for-Visual-Studio-and-Eclipse-MingW.html
* - READ THE WEB DOCUMENTATION FOR THIS PORT FOR MORE INFORMATION ON USING IT -
*
@ -91,59 +88,65 @@
* in main.c.
******************************************************************************
*
* main_blinky() creates one queue, and two tasks. It then starts the
* scheduler.
* main_blinky() creates one queue, one software timer, and two tasks. It then
* starts the scheduler.
*
* The Queue Send Task:
* The queue send task is implemented by the prvQueueSendTask() function in
* this file. prvQueueSendTask() sits in a loop that causes it to repeatedly
* block for 200 (simulated as far as the scheduler is concerned, but in
* reality much longer - see notes above) milliseconds, before sending the
* value 100 to the queue that was created within main_blinky(). Once the
* value is sent, the task loops back around to block for another 200
* (simulated) milliseconds.
* this file. It uses vTaskDelayUntil() to create a period task that sends the
* value 100 to the queue every 200 milliseconds (please read the notes above
* regarding the accuracy of timing under Windows).
*
* The Queue Send Software Timer:
* The timer is a one-shot timer that is reset by a key press. The timer's
* period is set to two seconds - if the timer expires then its callback
* function writes the value 200 to the queue. The callback function is
* implemented by prvQueueSendTimerCallback() within this file.
*
* The Queue Receive Task:
* The queue receive task is implemented by the prvQueueReceiveTask() function
* in this file. prvQueueReceiveTask() sits in a loop where it repeatedly
* blocks on attempts to read data from the queue that was created within
* main_blinky(). When data is received, the task checks the value of the
* data, and if the value equals the expected 100, outputs a message. The
* 'block time' parameter passed to the queue receive function specifies that
* the task should be held in the Blocked state indefinitely to wait for data
* to be available on the queue. The queue receive task will only leave the
* Blocked state when the queue send task writes to the queue. As the queue
* send task writes to the queue every 200 (simulated - see notes above)
* milliseconds, the queue receive task leaves the Blocked state every 200
* milliseconds, and therefore outputs a message every 200 milliseconds.
* in this file. prvQueueReceiveTask() waits for data to arrive on the queue.
* When data is received, the task checks the value of the data, then outputs a
* message to indicate if the data came from the queue send task or the queue
* send software timer. As the queue send task writes to the queue every 200ms,
* the queue receive task will print a message indicating that it received data
* from the queue send task every 200ms. The queue receive task will print a
* message indicating that it received data from the queue send software timer
* 2 seconds after a key was last pressed.
*/
/* Standard includes. */
#include <stdio.h>
#include <conio.h>
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"
/* Priorities at which the tasks are created. */
#define mainQUEUE_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 2 )
#define mainQUEUE_SEND_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
/* The rate at which data is sent to the queue. The 200ms value is converted
to ticks using the portTICK_PERIOD_MS constant. */
#define mainQUEUE_SEND_FREQUENCY_MS ( 200 / portTICK_PERIOD_MS )
/* The rate at which data is sent to the queue. The times are converted from
milliseconds to ticks by the pdMS_TO_TICKS() macro where they are used. */
#define mainTASK_SEND_FREQUENCY_MS 200
#define mainTIMER_SEND_FREQUENCY_MS 2000
/* The number of items the queue can hold. This is 1 as the receive task
will remove items as they are added, meaning the send task should always find
the queue empty. */
#define mainQUEUE_LENGTH ( 1 )
/* The number of items the queue can hold. */
#define mainQUEUE_LENGTH ( 2 )
/* Values passed to the two tasks just to check the task parameter
functionality. */
#define mainQUEUE_SEND_PARAMETER ( 0x1111UL )
#define mainQUEUE_RECEIVE_PARAMETER ( 0x22UL )
/* The values sent to the queue receive task from the queue send task and the
queue send software timer respectively. */
#define mainVALUE_SENT_FROM_TASK ( 100UL )
#define mainVALUE_SENT_FROM_TIMER ( 200UL )
/*-----------------------------------------------------------*/
/*
@ -152,15 +155,25 @@ functionality. */
static void prvQueueReceiveTask( void *pvParameters );
static void prvQueueSendTask( void *pvParameters );
/*
* The callback function executed when the software timer expires.
*/
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle );
/*-----------------------------------------------------------*/
/* The queue used by both tasks. */
static QueueHandle_t xQueue = NULL;
/* A software timer that is started from the tick hook. */
static TimerHandle_t xTimer = NULL;
/*-----------------------------------------------------------*/
void main_blinky( void )
{
const TickType_t xTimerPeriod = pdMS_TO_TICKS( mainTIMER_SEND_FREQUENCY_MS );
/* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) );
@ -177,6 +190,13 @@ void main_blinky( void )
xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, ( void * ) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY, NULL );
/* Create the software timer, but don't start it yet. */
xTimer = xTimerCreate( "Timer", /* The text name assigned to the software timer - for debug only as it is not used by the kernel. */
xTimerPeriod, /* The period of the software timer in ticks. */
pdFALSE, /* xAutoReload is set to pdFALSE, so this is a one shot timer. */
NULL, /* The timer's ID is not used. */
prvQueueSendTimerCallback );/* The function executed when the timer expires. */
/* Start the tasks and timer running. */
vTaskStartScheduler();
}
@ -193,8 +213,8 @@ void main_blinky( void )
static void prvQueueSendTask( void *pvParameters )
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
const TickType_t xBlockTime = pdMS_TO_TICKS( mainQUEUE_SEND_FREQUENCY_MS );
const TickType_t xBlockTime = pdMS_TO_TICKS( mainTASK_SEND_FREQUENCY_MS );
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TASK;
/* Remove compiler warning in the case that configASSERT() is not
defined. */
@ -217,12 +237,26 @@ const TickType_t xBlockTime = pdMS_TO_TICKS( mainQUEUE_SEND_FREQUENCY_MS );
/* Send to the queue - causing the queue receive task to unblock and
toggle the 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
be empty at this point in the code. */
have at least one space at this point in the code. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
}
/*-----------------------------------------------------------*/
static void prvQueueSendTimerCallback( TimerHandle_t xTimerHandle )
{
const uint32_t ulValueToSend = mainVALUE_SENT_FROM_TIMER;
/* Avoid compiler warnings resulting from the unused parameter. */
( void ) xTimerHandle;
/* Send to the queue - causing the queue receive task to unblock and
write out a message. This function is called from the timer/daemon task, so
must not block. Hence the block time is set to 0. */
xQueueSend( xQueue, &ulValueToSend, 0U );
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask( void *pvParameters )
{
unsigned long ulReceivedValue;
@ -242,16 +276,34 @@ unsigned long ulReceivedValue;
xQueueReceive( xQueue, &ulReceivedValue, portMAX_DELAY );
/* To get here something must have been received from the queue, but
is it the expected value? If it is, toggle the LED. */
if( ulReceivedValue == 100UL )
is it the expected value? Normally calling printf() from a task is not
a good idea. Here there is lots of stack space and only one task is
using console IO so it is ok. */
if( ulReceivedValue == mainVALUE_SENT_FROM_TASK )
{
/* Normally calling printf() from a task is not a good idea. Here
there is lots of stack space and only one task is using console IO
so it is ok. */
printf( "Message received\r\n" );
ulReceivedValue = 0U;
printf( "Message received from task\r\n" );
}
else if( ulReceivedValue == mainVALUE_SENT_FROM_TIMER )
{
printf( "Message received from software timer\r\n" );
}
else
{
printf( "Unexpected message\r\n" );
}
/* Reset the timer if a key has been pressed. The timer will write
mainVALUE_SENT_FROM_TIMER to the queue when it expires. */
if( _kbhit() != 0 )
{
/* Remove the key from the input buffer. */
( void ) _getch();
/* Reset the software timer. */
xTimerReset( xTimer, portMAX_DELAY );
}
}
}
/*-----------------------------------------------------------*/