2017-04-13 47 views
0

我正在編寫一個應用程序,我在等待命令從串口進入並根據數據轉換led顏色。我有每個元素在自己的權利的工作:MBed RTOS不響應串口

  1. Recieving和發送命令通過串行連接
  2. 改變LED的顏色
  3. 變化直接導致顏色時,收到命令(無RTOS)。

我需要LED迴路繼續工作,直到新數據已經到達但是,當我使用RTOS庫中的線程時,LED不會改變。這讓我認爲它是我的代碼和RTOS的問題,問題是我不知道是什麼導致它。

從調試(打印字符串到串口到pc)我看到線程正在運行並循環,它使用創建變量時設置的值。主線程似乎停止了,因爲沒有輸出到控制檯(或讀取串行輸入)。

如果我不開始線程串行通信再次工作確認問題出在我的代碼和RTOS庫。

從閱讀其他論壇和帖子我已經讀過,它可能是串行和RTOS的問題,並遵循建議刪除所有printf函數和更改爲RawSerial,但這沒有做任何事情。

我會很感激的任何幫助,讓代碼按預期

#include "mbed.h" 
#include "rtos.h" 
#include "xbee.h" 
#include "CMDLIB.h" 
#include "WS2812.h" 
#include "PixelArray.h" 

#define LED_COUNT1 134 
#define OUT_WHEEL 28 

char startChar = '$'; 
char endChar = ';'; 

Serial pc(USBTX, USBRX); // tx, rx 

CMDLIB cmd; 
xbee xbee(p28, p27, p29, 38400); 
PixelArray px1(LED_COUNT1); 
WS2812 set1(p5, 144, 3, 11, 10, 11); 
Thread ledthread; 

int ledFunction; 
int colour1[3], colour2[3], speed, intensity; 

//LED Functions 
void offLED() 
{ 
    for(int i = 1; i < LED_COUNT1; i++) 
    { 
     px1.Set(i, 0x000000); 
    } 
    set1.write(px1.getBuf()); 
} 

void solidPulse(int colour, int speed, int intensity) 
{ 
    px1.SetAll(colour); 
    //pc.printf("2\r\n"); 
    set1.write(px1.getBuf()); 
    //pc.printf("3\r\n"); 
    for(int a = 255; a > intensity; a--) 
    { 
     px1.SetAllI(a); 
     set1.write(px1.getBuf()); 
     wait_ms(speed); 
     //pc.printf("%d,",a); 
    } 
    //pc.printf("\r\n4\r\n"); 
    for(int a = intensity; a < 255; a++) 
    { 
     px1.SetAllI(a); 
     set1.write(px1.getBuf()); 
     wait_ms(speed); 
     //pc.printf("%d,",a); 
    } 
    //pc.printf("\r\n5\r\n"); 

} 

void ledThread() 
{ 
    while(1) 
    { 
     switch(ledFunction) 
     { 
      case 0: //Off 
       //offLED(); 
      break; 
      case 1: //Solid 
       //pc.printf("1\r\n"); 
      solidPulse(cmd.RGB2HEX(colour1[0], colour1[1], colour1[2]), speed, intensity); 
      break; 
      case 2: //Solid Pulse 
      solidPulse(cmd.RGB2HEX(colour1[0], colour1[1], colour1[2]), speed, intensity); 
      break; 
      default: 
      break; 
     } 
     //pc.printf("%d;\r\n", ledFunction); 
     wait_ms(200); 
    } 
} 

void setup() 
{ 
    set1.useII(WS2812::PER_PIXEL); // use per-pixel intensity scaling 
    xbee.setup(startChar, endChar); 
    pc.baud(38400); 
    muxcon = 0; 
    ledFunction = 0; 
    for(int j = 0; j < 3; j++) 
    { 
     colour1[j] = 1; 
     colour2[j] = 1; 
    } 
    speed = 100; 
    intensity = 0; 

    for(int i = 0; i < LED_COUNT1; i++) 
    { 
     px1.Set(i, 0xffffff); 
    } 
    set1.write(px1.getBuf()); 
} 

char * convertChar(string data) 
{ 
    char * chars = ""; 
    for(int k = 0; k < data.size(); k++) 
    { 
     chars += data[k]; 
    } 
    return chars; 
} 

int main() 
{ 
    setup(); 
    ledthread.start(ledThread); 
    string recData; 
    while(true) 
    { 
     if(xbee.readable()) 
     { 
      recData = xbee.readData(); 
      //pc.printf("Recieved Data: %s\r\n",recData); 
      string cmdString = cmd.getCommand(recData); 
      if(cmdString == "[TEL]") 
      { 
       gatherTelemetry(); 
       string telResult = cmd.formatTelemetry(sData1, sData2, sData3, sData4, sData5, sData6); 
       xbee.sendData(telResult); 
      } 
      if(cmdString == "[LED]") 
      { 
       //pc.printf("[RES],LED;\r\n"); 

       string res[10]; 
       int count = 0; 
       char c; 
       for(int j = 0; j < recData.size(); j++) 
       { 
        c = recData[j]; 
        if(c == ',' || c == ';') 
        { 
         count++; 
        } 
        else 
        { 
         res[count] += c; 
        } 
       } 
       ledFunction = atoi(res[1].c_str()); 
       colour1[0] = atoi(res[2].c_str()); 
       colour1[1] = atoi(res[3].c_str()); 
       colour1[2] = atoi(res[4].c_str()); 
       colour2[0] = atoi(res[5].c_str()); 
       colour2[1] = atoi(res[6].c_str()); 
       colour2[2] = atoi(res[7].c_str()); 
       speed = atoi(res[8].c_str()); 
       intensity = atoi(res[9].c_str()); 
       //pc.printf("Raw Values: %s-%s-%s-%s-%s-%s-%s-%s-%s-%s\r\n",res[0],res[1],res[2],res[3],res[4],res[5],res[6],res[7],res[8],res[9]); 
       //pc.printf("Converted: %d,%d,%d,%d,%d,%d,%d,%d,%d\r\n",ledFunction,colour1[0],colour1[1],colour1[2],colour2[0],colour2[1],colour2[2],speed,intensity); 


       xbee.sendData("[RES],OK"); 

       //solidPulse(cmd.RGB2HEX(colour1[0], colour1[1], colour1[2]), speed, intensity); 
      } 
      if(cmdString == "[CMD]") 
      { 

      } 
     } 
    } 
} 

回答

2

wait_ms功能不把正在運行的線程進入等待狀態,不允許另一個線程來運行工作。所以你的ledThread永遠不會放棄控制。 相反,ledThread應該調用Thread::wait,它將當前線程置於等待狀態並允許下一個就緒線程運行。

您可能還需要更改main while循環,以便放棄控制並允許ledThread再次運行。

+0

你會如何讓主線程放棄控制,線程等待? – NoLiver92

+1

@ NoLiver92:這是一種方式,但是在RTOS中,可以運行的最高優先級任務將運行。當任務不是_blocked_時,任務可以運行。 'Thread :: wait'是最簡單的阻塞方法,但不允許對傳入命令進行真正的實時響應;更好的方法是在xbee上阻塞等待;這要求'xbee'類是mBed RTOS感知。那就是你需要阻塞等待來替換'xbee :: readable()'。如果您定期輪詢'xbee :: readable',可能並不重要,但在其他情況下,即時實時響應需要輪詢可能不充分。 – Clifford