[英]Arduino uno freertos tasks stopped running
I'm working on a project with arduino UNO, i'm using freertos for multitasking, i have two tasks : 1-TaskLedBlink. 我正在与arduino UNO进行一个项目,我正在使用freertos进行多任务处理,我有两个任务: 1-TaskLedBlink。 and 2-TaskSerialP6008. 和2-TaskSerialP6008。 the first task is used to flash a led twice every given period of time and the second one is used to receive a frame from serial port and then send it back. 第一个任务用于在给定的时间段内两次刷新LED,第二个任务用于从串行端口接收帧,然后将其发送回去。 the frame should start with 0x02 and ends with 0x0D . 框架应以0x02开头,以0x0D结束。 when the 0x02 is received, i start adding incoming bytes to an array called asciiFrame until 0x0D was received, after that i send the hole frame back. 当接收到0x02时,我开始将传入的字节添加到称为asciiFrame的数组中,直到接收到0x0D ,之后我将空帧发送回去。 Until that moment the program was working just fine . 在那一刻之前,程序运行良好 。 then i decided to add a block of code wich is responsible for decoding the asciiFrame, the result is saved in an array called binaryFrame . 然后我决定添加一个代码块,该代码块负责解码asciiFrame,结果保存在一个名为binaryFrame的数组中。 Here the program's started to act strange . 在这里,程序开始表现得很奇怪。 the led stops flashing, sometimes is on sometimes is off, serial data are lost (not received). LED停止闪烁,有时亮,有时灭,串行数据丢失(未接收)。 in the worst cases the program is no more responding until i reboot the arduino. 在最坏的情况下,直到我重新启动arduino为止,程序才不再响应。 When i started looking around to solve the problem i found that when i remove this line binaryFrame[m]=(asciiFrame[k]&15)+((asciiFrame[k+1]&15)<<4); 当我开始四处张望以解决问题时,我发现当我删除这一行时, binaryFrame [m] =(asciiFrame [k]&15)+(((asciiFrame [k + 1]&15)<< 4); the program works fine. 该程序工作正常。 Help please solve this problem...here is the code 帮助请解决这个问题...这里是代码
#include <Arduino_FreeRTOS.h>
#include <semphr.h> // add the FreeRTOS functions for Semaphores (or Flags).
byte inByte = 0; // incoming serial byte
bool startByte = false;
byte asciiFrame[18]; //array to save ascci frame p6008 02 xx xx....0d max 18 bytes including 0x02 and 0x0D
byte binaryFrame[8]; //array to save binary frame p6008 (max 7 bytes + CHECKSUM)
byte i=0; //index used to select case in array
byte j=0; //index used to select byte in array to send it over serial
byte k=0; //index used to convert from ascii to binary
byte m=0; //to save data in binary frame
bool asciiFrameComplete = false; //to indicate that a complete frame(ascii mode) hs been recieved
bool binaryFrameComplete = false;
bool asciiP6008Enabled = true; //true(ascii mode) false(binary mode)
// Declare a mutex Semaphore Handle which we will use to manage the Serial Port.
// It will be used to ensure only only one Task is accessing this resource at any time.
SemaphoreHandle_t xSerialSemaphore;
// define two Tasks for DigitalRead & AnalogRead
void TaskLedBlink( void *pvParameters );
void TaskSerialP6008( void *pvParameters );
// the setup function runs once when you press reset or power the board
void setup() {
// initialize serial communication at 9600 bits per second:
pinMode(13, OUTPUT);
Serial.begin(9600);
// Semaphores are useful to stop a Task proceeding, where it should be paused to wait,
// because it is sharing a resource, such as the Serial port.
// Semaphores should only be used whilst the scheduler is running, but we can set it up here.
if ( xSerialSemaphore == NULL ) // Check to confirm that the Serial Semaphore has not already been created.
{
xSerialSemaphore = xSemaphoreCreateMutex(); // Create a mutex semaphore we will use to manage the Serial Port
if ( ( xSerialSemaphore ) != NULL )
xSemaphoreGive( ( xSerialSemaphore ) ); // Make the Serial Port available for use, by "Giving" the Semaphore.
}
// Now set up two Tasks to run independently.
xTaskCreate(
TaskLedBlink
, (const portCHAR *)"LedBlink" // A name just for humans
, 128 // This stack size can be checked & adjusted by reading the Stack Highwater
, NULL
, 2 // Priority, with 1 being the highest, and 4 being the lowest.
, NULL );
xTaskCreate(
TaskSerialP6008
, (const portCHAR *) "AnalogRead"
, 256 // Stack size
, NULL
, 1 // Priority
, NULL );
// Now the Task scheduler, which takes over control of scheduling individual Tasks, is automatically started.
//vTaskStartScheduler();
}
void loop(){
// Empty. Things are done in Tasks.
}
/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/
void TaskLedBlink( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
for (;;) // A Task shall never return or exit.
{
digitalWrite(13, HIGH);
vTaskDelay(1);
digitalWrite(13, LOW);
vTaskDelay(6);
digitalWrite(13, HIGH);
vTaskDelay(1);
digitalWrite(13, LOW);
vTaskDelay(17);
}
}
void TaskSerialP6008( void *pvParameters __attribute__((unused)) ) // This is a Task.
{
for (;;)
{
// read the input on analog pin 0:
//int sensorValue = analogRead(A0);
if (Serial.available()>0)
{
inByte = Serial.read();
if ((inByte == 2 || startByte)&&asciiP6008Enabled) //if 2 was received or already has been(startByte), and ascii mode is enabled
{
startByte = true; //start byte came
asciiFrame[i] = inByte; //save bytes in frame array
i++; //increment to the next case in frame array
if (inByte == 13) //end byte came
{
asciiFrameComplete = true;
startByte = false;
i=0;
if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
{
for (j=0;j<18&&asciiFrame[j]!=0;j++) //send frame back
Serial.write(asciiFrame[j]);
memset(asciiFrame, 0, sizeof(asciiFrame)); //then clear it
}
xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
for(k=1 ; k<sizeof(asciiFrame) ; k++)
{
if(asciiFrame[k]==13)
{
binaryFrameComplete=true;
m=0;
break;
}
if(k%2!=0)
{
binaryFrame[m]=(asciiFrame[k]&15)+((asciiFrame[k+1]&15)<<4);
m++;
}
}
// if ( xSemaphoreTake( xSerialSemaphore, ( TickType_t ) 5 ) == pdTRUE )
// {
// for (j=0;j<8;j++) //send frame back
// Serial.write(binaryFrame[j]);
// memset(asciiFrame, 0, sizeof(asciiFrame)); //then clear it
// memset(binaryFrame, 0, sizeof(asciiFrame)); //then clear it
// }
// xSemaphoreGive( xSerialSemaphore ); // Now free or "Give" the Serial Port for others.
}
if (i==sizeof(asciiFrame)) //if array is full ecrase received data, frame length should not exceed 18 bytes
{
memset(asciiFrame, 0, sizeof(asciiFrame)); //clear array
i=0; //init i
startByte = false;
}
}
else if(!asciiP6008Enabled) //binary enabled
{
Serial.println("binary enabled");
}
}
//vTaskDelay(1); // one tick delay (15ms) in between reads for stability
}
}
我认为问题在于将变量声明为全局变量,我已经在任务中声明了它们,并且效果很好。
seems you're near the RAM limits... 看来您已接近RAM限制...
or your m exceeds the binaryFrame limits... 或者您的m超出了binaryFrame限制...
By quickly looking, I estimate m being about half of k, and you defined 通过快速查看,我估计m约为k的一半,您定义了
byte asciiFrame[18];
byte binaryFrame[8];
and if there's no 0x0D, you won't reset m ... 如果没有0x0D,则不会重置m ...
With local variables you get a different behavior when spoofing memory. 使用局部变量,在欺骗内存时会得到不同的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.