MBed RTOS不响应串行

时间:2017-04-13 19:21:50

标签: rtos mbed

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

  1. 通过串行连接接收和发送命令
  2. 更改LED颜色
  3. 收到命令后直接更改LED颜色(无RTOS)。
  4. 我需要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]" )
                {
    
                }
            }
        }
    }
    

1 个答案:

答案 0 :(得分:2)

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

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