MBed RTOS 不响应串行

MBed RTOS doesnt respond to serial

我正在编写一个应用程序,我在其中等待来自串行的命令并根据数据转换 LED 颜色。我让每个元素独立工作:

  1. 通过串行连接接收和发送命令
  2. 改变 LED 颜色
  3. 收到命令时直接更改 LED 颜色(无 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]" )
            {

            }
        }
    }
}

wait_ms函数不会让运行ning线程进入等待状态,也不允许另一个线程运行。所以你的 ledThread 永远不会放弃控制权。 相反,ledThread 应该调用 Thread::wait,它会将当前线程置于等待状态,并允许下一个就绪线程进入 运行.

您可能还需要更改 main while 循环,以便它放弃控制并允许 ledThread 再次 运行。