只有一个任务正在运行,那就是优先级最高的接收器任务,其他任务都不会运行,除非我使用
xtaskdelay
这是我的任务中不能使用的要求
该代码创建了4个定时器,用于控制4个信号量,当任务获取信号量时,任务将使用这些信号量进行工作。有3个发送方任务和1个接收方,发送方在使用随机函数随机传递给定时器的随机时间段内发送到创建的队列(前两个发送方具有相同的优先级,而第三个发送方具有更高的优先级)。当代码达到1000条消息后,它会重置,计时器发送的界限会更高,它会经过6个周期,然后关闭并停止调度程序,并在要发送的消息上打印游戏是“时间是XYZ”,其中XYZ是以刻度为单位的系统时间
/*
* This file is part of the µOS++ distribution.
* (https://github.com/micro-os-plus)
* Copyright (c) 2014 Liviu Ionescu.
*
* 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.
*/
// ----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include "diag/trace.h"
#define configUSE_PREEMPTION 1
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "timers.h"
#include "semphr.h"
#include "projdefs.h"
#include "event_groups.h"
#include "portable.h"
#include "list.h"
#include "croutine.h"
#include "deprecated_definitions.h"
#include "mpu_prototypes.h"
#include "mpu_wrappers.h"
#include "StackMacros.h"
#include <time.h>
#define CCM_RAM __attribute__((section(".ccmram")))
int NumberOfSent1=0;
int NumberOfSent2=0;
int NumberOfSent3=0;
int NumberOfBlocked1=0;
int NumberOfBlocked2=0;
int NumberOfBlocked3=0;
int NumberOfReceived=0;
int Average_sent1=0;
int Average_sent2=0;
int Average_sent3=0;
int Average_blocked1=0;
int Average_blocked2=0;
int Average_blocked3=0;
int TotalTime1=0;
int TotalTime2=0;
int TotalTime3=0;
int Timer1Rand;
int Timer2Rand;
int Timer3Rand;
int UpperBound=150;
int LowerBound=50;
int TimeTask1=0;
int TimeTask2=0;
int TimeTask3=0;
short AverageTime1=0;
short AverageTime2=0;
short AverageTime3=0;
int counterForCycle=0;
char tickcount_converted[10];
char Message[30]="Time is ";
char Buffer[32];
SemaphoreHandle_t xSemaphore1;
SemaphoreHandle_t xSemaphore2;
SemaphoreHandle_t xSemaphore3;
SemaphoreHandle_t xSemaphore4;
QueueHandle_t GlobalQueue;
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
/*-----------------------------------------------------------*/
/*
* The LED timer callback function. This does nothing but switch the red LED
* off.
*/
static void Timer1Callback( TimerHandle_t xTimer );
static void Timer2Callback( TimerHandle_t xTimer );
static void Timer3Callback(TimerHandle_t xTimer);
void Timer4Callback(TimerHandle_t xTimer);
static void Sender1(void);
static void Sender2(void);
static void Sender3(void);
void Receiver(void);
/*-----------------------------------------------------------*/
/* The LED software timer. This uses vLEDTimerCallback() as its callback
* function.
*/
static TimerHandle_t xTimer1;
static TimerHandle_t xTimer2;
static TimerHandle_t xTimer3;
static TimerHandle_t xTimer4;
TaskHandle_t Task1H;
TaskHandle_t Task2H;
TaskHandle_t Task3H;
TaskHandle_t Task4H;
BaseType_t Task1;
BaseType_t Task2;
BaseType_t Task3;
BaseType_t Task4;
BaseType_t xTimer1Started, xTimer2Started,xTimer3Started,xTimer4Started;
// ----- main() ---------------------------------------------------------------
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wmissing-declarations"
#pragma GCC diagnostic ignored "-Wreturn-type"
int
main()
{
// Add your code here.
srand(time(NULL));
xSemaphore1=xSemaphoreCreateBinary();
xSemaphore2=xSemaphoreCreateBinary();
xSemaphore3=xSemaphoreCreateBinary();
xSemaphore4=xSemaphoreCreateBinary();
xSemaphoreGive(xSemaphore4);
GlobalQueue=xQueueCreate(10,32);
Timer1Rand=(rand() % (150 - 50 + 1)) + 50;
Timer2Rand=(rand() % (150 - 50 + 1)) + 50;
Timer3Rand=(rand() % (150 - 50 + 1)) + 50;
xTimer1 = xTimerCreate( "Timer1", ( pdMS_TO_TICKS(Timer1Rand) ), pdTRUE, ( void * ) 0, Timer1Callback);
xTimer2 = xTimerCreate( "Timer2", ( pdMS_TO_TICKS(Timer2Rand) ), pdTRUE, ( void * ) 1, Timer2Callback);
xTimer3 = xTimerCreate( "Timer3", ( pdMS_TO_TICKS(Timer3Rand) ), pdTRUE, ( void * ) 2, Timer3Callback);
xTimer4 = xTimerCreate( "Timer4", ( pdMS_TO_TICKS(100) ), pdTRUE, ( void * ) 3, Timer4Callback);
Task1 = xTaskCreate(Sender1,"Sender1",1024,(void *)1,0,&Task1H);
Task2 = xTaskCreate(Sender2,"Sender2",1024,(void *)2,0,&Task2H);
Task3 = xTaskCreate(Sender3,"Sender3",1024,(void *)3,1,&Task3H);
Task4 = xTaskCreate(Receiver,"Receiver",1024,(void *)4,2,&Task4H);
if( ( xTimer1 != NULL ) && ( xTimer2 != NULL )&& ( xTimer3 != NULL )&& ( xTimer4 != NULL ) )
{
xTimer1Started = xTimerStart( xTimer1, 0 );
xTimer2Started = xTimerStart( xTimer2, 0 );
xTimer3Started = xTimerStart( xTimer3, 0 );
xTimer4Started = xTimerStart( xTimer4, 0 );
}
// if( xTimer1 != NULL ) xTimer1Started = xTimerStart( xTimer1, 0 );
if( xTimer1Started == pdPASS && xTimer2Started == pdPASS&& xTimer3Started == pdPASS&& xTimer4Started == pdPASS)
{
vTaskStartScheduler();
}
// if( xTimer1Started == pdPASS)vTaskStartScheduler();
return 0;
}
#pragma GCC diagnostic pop
// ----------------------------------------------------------------------------
static void Timer1Callback(TimerHandle_t xTimer){
xSemaphoreGive( xSemaphore1 );
//srand(time());
Timer1Rand=(rand() % (UpperBound - LowerBound + 1)) + LowerBound;
// vTaskResume(Task1H);
//printf("A%d\n",Timer2Rand);
}
static void Timer2Callback(TimerHandle_t xTimer){
xSemaphoreGive( xSemaphore2 );
//srand(time());
Timer2Rand=(rand() % (UpperBound - LowerBound + 1)) + LowerBound;
//printf("B%d\n",Timer2Rand);
// vTaskResume(Task2H);
}
static void Timer3Callback(TimerHandle_t xTimer){
xSemaphoreGive( xSemaphore3 );
//srand(time());
Timer3Rand=(rand() % (UpperBound - LowerBound + 1)) + LowerBound;
//printf("C%d\n",Timer3Rand);
//vTaskResume(Task3H);
}
void Timer4Callback(TimerHandle_t xTimer){
xSemaphoreGive( xSemaphore4 );
}
static void Sender1(void){
while(1){
if( xSemaphoreTake( xSemaphore1, 0 ) == pdTRUE){
TotalTime1+=Timer1Rand;
TimeTask1=xTaskGetTickCount();
//printf("A%d\n",TimeTask1);
itoa(TimeTask1,tickcount_converted,10);
for(int i=0;i<8;i++){
Message[8+i]=tickcount_converted[i];
}
//printf("A%s\n",Message);
if(xQueueSend(GlobalQueue,&Message,0)==pdTRUE){
NumberOfSent1++;}
else NumberOfBlocked1++;
//printf("A%d\n",NumberOfSent1);
//printf("AQ%d\n",NumberOfBlocked1);
//vTaskDelay( pdMS_TO_TICKS(10) );
// vTaskSuspend(Task1H);
xTimerChangePeriod(xTimer1,pdMS_TO_TICKS(Timer1Rand),0);
}}
}
static void Sender2(void){
while(1){
if( xSemaphoreTake( xSemaphore2, 0 ) == pdTRUE){
TotalTime2+=Timer2Rand;
TimeTask2=xTaskGetTickCount();
itoa(TimeTask2,tickcount_converted,10);
for(int i=0;i<8;i++){
Message[8+i]=tickcount_converted[i];
}
if(xQueueSend(GlobalQueue,&Message,0)==pdTRUE){
NumberOfSent2++;}
else NumberOfBlocked2++;
//vTaskDelay( pdMS_TO_TICKS(10) );
//printf("B%d\n",NumberOfSent2);
// vTaskSuspend(Task2H);
xTimerChangePeriod(xTimer2,pdMS_TO_TICKS(Timer2Rand),0);
}}
}
static void Sender3(void){
while(1){
if( xSemaphoreTake( xSemaphore3, 0 ) == pdTRUE){
TotalTime3+=Timer3Rand;
TimeTask3=xTaskGetTickCount();
itoa(TimeTask3,tickcount_converted,10);
for(int i=0;i<8;i++){
Message[8+i]=tickcount_converted[i];
}
if(xQueueSend(GlobalQueue,&Message,0)==pdTRUE){
NumberOfSent3++;}
else NumberOfBlocked3++;
printf("C%d\n",NumberOfSent3);
// vTaskSuspend(Task3H);
xTimerChangePeriod(xTimer3,pdMS_TO_TICKS(Timer3Rand),0);
// vTaskDelay( pdMS_TO_TICKS(10) );
}
}
}
void Receiver(void){
while(1){
if( xSemaphoreTake( xSemaphore4, 0 ) == pdTRUE){
if(NumberOfReceived==1000){
AverageTime1=TotalTime1/(NumberOfSent1+NumberOfBlocked1);
AverageTime2=TotalTime2/(NumberOfSent2+NumberOfBlocked2);
AverageTime3=TotalTime3/(NumberOfSent3+NumberOfBlocked3);
printf("NumberOfSent1 in cycle %d =%d\n",counterForCycle,NumberOfSent1);
printf("NumberOfBlocked1 in cycle %d= %d\n",counterForCycle,NumberOfBlocked1);
printf("Average 1 in cycle %d :%d\n",counterForCycle,AverageTime1);
printf("NumberOfSent2 in cycle %d =%d\n",counterForCycle,NumberOfSent2);
printf("NumberOfBlocked2 in cycle %d =%d\n",counterForCycle,NumberOfBlocked2);
printf("AverageTime2 in cycle %d =%d\n",counterForCycle,AverageTime2);
printf("NumberOfSent3 in cycle %d =%d\n",counterForCycle,NumberOfSent3);
printf("NumberOfBlocked3 in cycle %d =%d\n",counterForCycle,NumberOfBlocked3);
printf("AverageTime3 in cycle %d =%d\n",counterForCycle,AverageTime3);
printf("NumberOfReceived in cycle %d =%d\n",counterForCycle,NumberOfReceived);
xQueueReset(GlobalQueue);
counterForCycle++;
TotalTime1=0;
TotalTime2=0;
TotalTime3=0;
NumberOfSent1=0;
NumberOfSent2=0;
NumberOfSent3=0;
NumberOfBlocked1=0;
NumberOfBlocked2=0;
NumberOfBlocked3=0;
NumberOfReceived=0;
UpperBound+=50;
LowerBound+=30;
}
if(UpperBound>400){
xTimerDelete(xTimer1,0);
xTimerDelete(xTimer2,0);
xTimerDelete(xTimer3,0);
xTimerDelete(xTimer4,0);
trace_puts("Game Over");
vTaskEndScheduler();
}
if(xQueueReceive(GlobalQueue,Buffer,0)==pdTRUE){
NumberOfReceived++;
}
//printf("D%d\n",NumberOfReceived);
// vTaskSuspend(Task4H);
//
//printf("t%d\n",NumberOfReceived);
xTimerChangePeriod(xTimer4,pdMS_TO_TICKS(100),0);
// vTaskDelay( pdMS_TO_TICKS(10) );
}
}}
void vApplicationMallocFailedHook( void )
{
/* Called if a call to pvPortMalloc() fails because there is insufficient
free memory available in the FreeRTOS heap. pvPortMalloc() is called
internally by FreeRTOS API functions that create tasks, queues, software
timers, and semaphores. The size of the FreeRTOS heap is set by the
configTOTAL_HEAP_SIZE configuration constant in FreeRTOSConfig.h. */
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationStackOverflowHook( TaskHandle_t pxTask, char *pcTaskName )
{
( void ) pcTaskName;
( void ) pxTask;
/* Run time stack overflow checking is performed if
configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook
function is called if a stack overflow is detected. */
for( ;; );
}
/*-----------------------------------------------------------*/
void vApplicationIdleHook( void )
{
volatile size_t xFreeStackSpace;
/* This function is called on each cycle of the idle task. In this case it
does nothing useful, other than report the amout of FreeRTOS heap that
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. */
}
}
void vApplicationTickHook(void) {
}
StaticTask_t xIdleTaskTCB CCM_RAM;
StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE] CCM_RAM;
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize) {
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
state will be stored. */
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
/* Pass out the array that will be used as the Idle task's stack. */
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
Note that, as the array is necessarily of type StackType_t,
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}
static StaticTask_t xTimerTaskTCB CCM_RAM;
static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH] CCM_RAM;
/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize) {
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}
我希望所有任务都能工作,但只有一个任务能工作。问题是,只有一项任务在工作,其他任务不在工作,这是优先级最高的接收器任务(2),没有其他任务工作,甚至定时器也没有被调用。如果你们中有人能解决这个问题,我将不胜感激。