MBed RTOS 不响应串行
MBed RTOS doesnt respond to serial
我正在编写一个应用程序,我在其中等待来自串行的命令并根据数据转换 LED 颜色。我让每个元素独立工作:
- 通过串行连接接收和发送命令
- 改变 LED 颜色
- 收到命令时直接更改 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 再次 运行。
我正在编写一个应用程序,我在其中等待来自串行的命令并根据数据转换 LED 颜色。我让每个元素独立工作:
- 通过串行连接接收和发送命令
- 改变 LED 颜色
- 收到命令时直接更改 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 再次 运行。