Closed denizzzka closed 4 years ago
Thanks for taking the time to post this issue, although I'm not sure I understand the bug you are reporting. In your code you create an event group and then set bit 1 before then calling xEventGroupWaitBits() to wait for bit 0 to be set. As bit 0 is already set I would expect xEventGroupWaitBits() to return immediately - which is what you said happens. That would then seem to be the expected behaviour. What am I missing?
Thanks for taking the time to post this issue, although I'm not sure I understand the bug you are reporting. In your code you create an event group and then set bit 1 before then calling xEventGroupWaitBits()
Yes, but before or after - it depends on luck because set
and wait
called inside of two different tasks.
to wait for bit 0 to be set.
Yes
As bit 0 is already set I would expect xEventGroupWaitBits() to return immediately - which is what you said happens.
Yes.
That would then seem to be the expected behaviour. What am I missing?
wait
returning value is 0. Zero indicates that time out expired, as I understand. (I am newbie FreeRTOS user)
Non-inifinity waitings returns bits setted inside of event group and then I sucessfully check them to detect what is happen. For example:
auto r = os.xEventGroupWaitBits(
group,
BITS_MASK,
clearOnExit,
os.pdFALSE, // xWaitForAllBits
tmout.toTicks // xTicksToWait
);
return r & BITS_MASK;
Expected behavior Infinity waiting
Oh, I meant "waiting for 1 bit is set and then want to be able to check it"
I have the following program:
EventBits_t group, returned_value;
void vTask1( void * p )
{
group = xEventGroupCreate();
xEventGroupSetBits(group, 0x01);
for( ;; )
{
returned_value = xEventGroupWaitBits(group, 0x01, pdFALSE, pdFALSE, portMAX_DELAY /* 0xFFFFFFFF */);
configASSERT( returned_value == 0x01 );
returned_value = xEventGroupWaitBits(group, 0x01, pdFALSE, pdFALSE, 10 );
configASSERT( returned_value == 0x01 );
returned_value = xEventGroupWaitBits(group, 0x01, pdTRUE, pdFALSE, 10 );
configASSERT( returned_value == 0x01 );
}
}
On the first iteration of the loop all three calls to xEventGroupWaitBits() return immediately and return the expected value. The third call to xEventGroupWaitBits() has the "clear on exit" value set to true, so on the second iteration of the loop the bit isn't set and xEventGroupWaitBits() blocks for ever.
Can you please post a similarly small sequence of code that demonstrates the bug. Thanks.
Your snippet also causes this error! (I slightly modified it - added includes, main and debug output)
#include <FreeRTOS.h>
#include <event_groups.h>
EventBits_t group, returned_value;
void vTask1( void * p )
{
group = xEventGroupCreate();
xEventGroupSetBits(group, 0x01);
for(int i = 0;; i++)
{
returned_value = xEventGroupWaitBits(group, 0x01, pdFALSE, pdFALSE, portMAX_DELAY /* 0xFFFFFFFF */);
printf("i=%d %d\n", i, returned_value);
configASSERT( returned_value == 0x01 ); // fails here on i == 1
returned_value = xEventGroupWaitBits(group, 0x01, pdFALSE, pdFALSE, 10 );
configASSERT( returned_value == 0x01 );
returned_value = xEventGroupWaitBits(group, 0x01, pdTRUE, pdFALSE, 10 );
configASSERT( returned_value == 0x01 );
}
}
int main()
{
vTask1(NULL);
}
$ qemu-system-arm -machine mps2-an511 -nographic -rtc clock=vm -icount shift=2 -semihosting -kernel firmware.elf
i=0 1
i=1 0
assertion "(null)" failed: file "../frtstest.c", line 15
debugger says same: on second loop iteration uxTaskResetEventItemValue
call inside of xEventGroupWaitBits
returns 0x80000001 and this leads to returning zero.
I have no ideas other than checking compiler options:
[1090/1110] clang -Ifirmware.elf.p -I. -I.. -Xclang -fcolor-diagnostics -pipe -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -g -target thumbv7m-unknown-none-eabi -fshort-enums -D_LIBUNWIND_IS_BAREMETAL -D_LIBUNWIND_HAS_NO_THREADS -DSTM32F1 -MD -MQ firmware.elf.p/subprojects_freertos_list.c.o -MF firmware.elf.p/subprojects_freertos_list.c.o.d -o firmware.elf.p/subprojects_freertos_list.c.o -c ../subprojects/freertos/list.c
Sources version: 375b08529593e97c7cf29d405fa3af9b98d0cd8a (tag: V10.4.1-kernel-only)
I am not able to replicate the behaviour you report. Using your code and QEMU command line the first time around the loop I get 0 and 1, as you do. The first call to xEventGroupWaitBits() the second time around the loop never exits because it has an infinite block time - so I don't get any more output. I am using the latest version of FreeRTOS but don't think anything has changed in the event group implementation for some time. Are you using an unmodified version of FreeRTOS? I recommend you get a clean version. Another possibility is that you are getting some data corruption somewhere so check your linker script and start up code too.
Are you using an unmodified version of FreeRTOS? I recommend you get a clean version.
Yes, unmodified. Ok, I wiped out freertos sources and fetched current ~master. Issue is still here.
Another possibility is that you are getting some data corruption somewhere so check your linker script and start up code too.
According debugger, group value 0x01 is placed into storage with 0x80000000 addition.
I think that is matter may be in the compiler, for example, maybe gcc can cut values while fetching from list into short
by some reason and 0x80 prefix is gone?
I use clang compiler:
Debian clang version 11.0.0-++20200928060632+eb83b551d3e-1~exp1~20200928161254.109
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /home/denizzz/bin
Also I grep sources and isn't find where is taskEVENT_LIST_ITEM_VALUE_IN_USE
should be removed.
reduced:
group = xEventGroupCreate();
xEventGroupSetBits(group, 0x01);
returned_value = xEventGroupWaitBits(group, 0x01, pdTRUE, pdFALSE, 10 );
configASSERT( returned_value == 0x01 );
returned_value = xEventGroupWaitBits(group, 0x01, pdFALSE, pdFALSE, portMAX_DELAY /* 0xFFFFFFFF */);
configASSERT( returned_value == 0x01 ); // fails here, not fails if first `xEventGroupWaitBits` is removed
taskEVENT_LIST_ITEM_VALUE_IN_USE really has nothing to do with it. Waiting ends before of deal with uxTaskResetEventItemValue
.
@RichardBarry can you tell me, what portmacro.h you used for qemu-system-arm -machine mps2-an511
hardware?
I use GCC/ARM_CM3, maybe this is not correct?
Problem found: portYIELD() is not yields. Probably not correct CPU type or something like that. In any case, this is not what is declared in the header of this bug report.
Thanks!
For googlers: this is exactly what I running into: https://www.freertos.org/FreeRTOS_Support_Forum_Archive/February_2018/freertos_xEventGroupWaitBits_unexpected_behavior_cd13225cj.html
I create event group with one bit:
Then I want to block another task until receive this message by calling:
xEventGroupWaitBits(group, 0x01, pdFALSE, pdFALSE, portMAX_DELAY /* 0xFFFFFFFF */);
Unexpectedly this call immediately returns 0 instead to wait for event.
I walked step by step over code and seen that call inside of
xEventGroupWaitBits
bodyLooks like it fetches result value from list with
taskEVENT_LIST_ITEM_VALUE_IN_USE
value and isn't wipes off it. And then it passes into wrong code branch.Target
Development board: qemu-system-arm -machine mps2-an511 -nographic -rtc clock=vm -icount shift=3 -semihosting
Instruction Set Architecture: ARM Cortex-M3
Toolchain and version: clang -target thumbv7m-unknown-none-eabi
Expected behavior Infinity waiting
Additional context For this calls I use DPP generated bindings of FreeRTOS headers for Dlang.