osEvent eve;
eve=osSignalWait(0,osWaitForever);
本来是可以根据信号不同在一个任务中执行不同的功能,前提是要把信号清零。我一直奇怪信号设置一后就不变了,比如我设置了osSignalSet(xxsHandle,0x01);osSignalSet(xxsHandle,0x02);osSignalSet(xxsHandle,0x04);之后,下次再设置信号0x01的话,其实另外两个模块下的程序也会执行,也就是多oswaitsignal没有清零任何信号,查看变量证实了我的判断,于是想用ossignalclear语句,很遗憾居然就是一个定义没有内容。查看oswaitsignal定义,关键语句如下:if(xTaskNotifyWait( 0,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE),查看xTaskNotifyWait定义,发现那个0就是执行前要清零的信号位,0位当然什么都不清除,他妈妈的这个封装真的有问题,一直以为是自己错了,请看freertos的解释:
ulBitsToClearOnEntry Any bits set in ulBitsToClearOnEntry will be cleared in the calling RTOS task's notification value on entry to the xTaskNotifyWait() function (before the task waits for a new notification) provided a notification is not already pending when xTaskNotifyWait() is called.
For example, if ulBitsToClearOnEntry is 0x01, then bit 0 of the task's notification value will be cleared on entry to the function.
Setting ulBitsToClearOnEntry to 0xffffffff (ULONG_MAX) will clear all the bits in the task's notification value, effectively clearing the value to 0.
很清楚地解释了这一点,难道cmisis封装时不能添加一个变量吗?
由于我的程序不需要保留signal位,所以最简单的办法就是直接修改cmsis_os这个程序,把0直接换成0xffffffff,如下if(xTaskNotifyWait( 0xffffffff,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE)。问题解决。
if(eve.value.signals==0x01){}
if(eve.value.signals==0x02){}
运行结果是如果信号1先触发的话,那么信号2就完蛋了,如果信号2先触发信号1就完蛋,百思不得其解,
看定义如下typedef struct {
osStatus status; ///< status code: event or error information
union {
uint32_t v; ///< message as 32-bit value
void *p; ///< message or mail as void pointer
int32_t signals; ///< signal flags
} value; ///< event value
union {
osMailQId mail_id; ///< mail id obtained by \ref osMailCreate
osMessageQId message_id; ///< message id obtained by \ref osMessageCreate
} def; ///< event definition
} osEvent;
eve=osSignalWait(0,osWaitForever);
本来是可以根据信号不同在一个任务中执行不同的功能,前提是要把信号清零。我一直奇怪信号设置一后就不变了,比如我设置了osSignalSet(xxsHandle,0x01);osSignalSet(xxsHandle,0x02);osSignalSet(xxsHandle,0x04);之后,下次再设置信号0x01的话,其实另外两个模块下的程序也会执行,也就是多oswaitsignal没有清零任何信号,查看变量证实了我的判断,于是想用ossignalclear语句,很遗憾居然就是一个定义没有内容。查看oswaitsignal定义,关键语句如下:if(xTaskNotifyWait( 0,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE),查看xTaskNotifyWait定义,发现那个0就是执行前要清零的信号位,0位当然什么都不清除,他妈妈的这个封装真的有问题,一直以为是自己错了,请看freertos的解释:
ulBitsToClearOnEntry Any bits set in ulBitsToClearOnEntry will be cleared in the calling RTOS task's notification value on entry to the xTaskNotifyWait() function (before the task waits for a new notification) provided a notification is not already pending when xTaskNotifyWait() is called.
For example, if ulBitsToClearOnEntry is 0x01, then bit 0 of the task's notification value will be cleared on entry to the function.
Setting ulBitsToClearOnEntry to 0xffffffff (ULONG_MAX) will clear all the bits in the task's notification value, effectively clearing the value to 0.
很清楚地解释了这一点,难道cmisis封装时不能添加一个变量吗?
由于我的程序不需要保留signal位,所以最简单的办法就是直接修改cmsis_os这个程序,把0直接换成0xffffffff,如下if(xTaskNotifyWait( 0xffffffff,(uint32_t) signals, (uint32_t *)&ret.value.signals, ticks) != pdTRUE)。问题解决。
今天遇到一个奇怪的问题,程序重写了多次,没办法用串口跟踪查看,发现判断条件已经具备,但是没有执行条件语句下的内容,而且发现触发条件值很快改变,根本没有经过我的延迟时间。如果是自动循环,则条件语句第一次不执行,第二次开始完全执行了条件语句中的内容。
代码如下:
eve=osMessageGet(SampleControlQueueHandle,500);
if(eve.status==osEventMessage)
{
rSampleControldef=eve.value.p;
lSampleStartFlag=rSampleControldef->startSampleFlag;
lAutoOrManual=rSampleControldef->autoOrManual;
lForwardTime=rSampleControldef->forwardTime*100;
lBackFlowTimeTime=rSampleControldef->autoLoopTime*100-lForwardTime;
rSampleFlag=1;
osPoolFree(samplePoolHandle,rSampleControldef);
}
if(rSampleFlag)
{
HAL_UART_Transmit(&huart1,"SampleOK\r\n",10,100);
}
else
{
HAL_UART_Transmit(&huart1,"SampleNOOK\r\n",12,100);
}
if(lSampleStartFlag)
{
HAL_UART_Transmit(&huart1,"StartOK\r\n",9,100);
}
else
{
HAL_UART_Transmit(&huart1,"StartNOOK\r\n",11,100);
}
if(lSampleStartFlag && rSampleFlag)
{
CHROM_SAMPLE_ON;
LED7_ON;
HAL_UART_Transmit(&huart1,"Forwarding\r\n",12,100);
osDelayUntil(&lastWakeTime,lForwardTime);
CHROM_SAMPLE_OFF;
LED7_OFF;
HAL_UART_Transmit(&huart1,"BackFlowing\r\n",13,100);
osDelayUntil(&lastWakeTime,lBackFlowTimeTime);
HAL_UART_Transmit(&huart1,"Chrom Standby\r\n",15,100);
if(!lAutoOrManual)rSampleFlag=0;
}
osDelay(500);
初步怀疑是os智能地执行了调度,由于任务开始时是无意义的空循环,所以os没有调用那部分空闲代码,
osEvent eve;
eve=osSignalWait(0,osWaitForever);
if(eve.value.signals==0x01){}
if(eve.value.signals==0x02){}
运行结果是如果信号1先触发的话,那么信号2就完蛋了,如果信号2先触发信号1就完蛋,百思不得其解,
看定义如下typedef struct {
osStatus status; ///< status code: event or error information
union {
uint32_t v; ///< message as 32-bit value
void *p; ///< message or mail as void pointer
int32_t signals; ///< signal flags
} value; ///< event value
union {
osMailQId mail_id; ///< mail id obtained by \ref osMailCreate
osMessageQId message_id; ///< message id obtained by \ref osMessageCreate
} def; ///< event definition
} osEvent;
忽然有点明白了,改变判断语句如下:
if(eve.value.signals & 0x01)
if(eve.value.signals & 0x02)
程序正常,位判断
这个就是我想要找的哈哈
http://www.keil.com/pack/doc/cmsis/RTOS/html/index.html
file:///C:/Keil_v5/ARM/Pack/ARM/CMSIS/4.3.0/CMSIS/Documentation/RTOS/html/modules.html
楼主把它翻译一下,给我们这些不会英文的也看看
我也是刚玩,cmsis_os 显然是封装了freertos,如果完全使用freertos命令在程序中也是没问题的,但是cmsis_os更方便;没玩过RTX,个人估计如果在cubemx中也选择rtx的话,cmsis也把rtx封装了,即os的api和rtx的api有同样的功能。
国内资料太少,google又上不去,学的很艰难啊,比如我勾选了usb,cubemx把usb初始化放在defaulttask中了,难道usb要不停地初始化吗?百度不到的,希望共同提高
谷歌上不去好多资料都查不到,国内的搜索就是一大堆广告