-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cpu/esp32/freertos: fix semaphore take #11239
cpu/esp32/freertos: fix semaphore take #11239
Conversation
@JulianHolzwarth Thanks for figuring out that bug. Makes sense. Obviously, these functions were never used by SDK library functions even though they require that the symbols are defined for linking. |
I wonder if it wouldn't be better to bundle the test application |
2fc56dd
to
ce3de87
Compare
I will work on it Wednesday . |
44e53fc
to
04cbb4f
Compare
Added test for freertos. Only for BOARD:esp32-wroom-32 at the moment. At the moment it only tests xSemaphoreTake(), xSemaphoreTakeRecursive() and the creation of the semaphore. It creates the semaphore and calls take for it multiple times and checks whether the return value is correct. Take should return (quote freertos documention): "pdPASS Returned only if the call to xSemaphoreTakeRecursive() was successful in obtaining the semaphore." "pdFAIL Returned if the call to xSemaphoreTakeRecursive() did not successfully obtain the semaphore." The same for xSemaphoreTake(). The future goal for this test is to test the complete freertos compatibility layer and to have the test for a general freertos compatibility layer that does not only work for esp32.
xSemaphoreTake() returned before the fix: pdFALSE(equal to pdFAIL) when the call was successful in obtaining the semaphore and pdTRUE(equal to pdPASS) when the call did not successfully obtain the semaphore. According to freertos documentation: "pdPASS Returned only if the call to xSemaphoreTake() was successful in obtaining the semaphore" "pdFAIL Returned if the call to xSemaphoreTake() did not successfully obtain the semaphore." Fixed it to return the correct value.
xSemaphoreTakeRecursive() returned before the fix: pdFALSE(equal to pdFAIL) when the call was successful in obtaining the semaphore and pdTRUE(equal to pdPASS) when the call did not successfully obtain the semaphore. According to freertos documentation: "pdPASS Returned only if the call to xSemaphoreTakeRecursive() was successful in obtaining the semaphore" "pdFAIL Returned if the call to xSemaphoreTakeRecursive() did not successfully obtain the semaphore." Fixed it to return the correct value.
04cbb4f
to
e1d4551
Compare
This reverts commit 0a7a86d.
I reverted the test commit. Are you ok with this one? |
xSemaphoreTake() and xSemaphoreTakeRecursive() assert when timeout is not 0 or portMAX_DELAY because it is not implemented. Return value fix: cpu/esp32/freertos: fix semaphore take RIOT-OS#11239
Ping @gschorcht? |
@@ -94,7 +94,7 @@ BaseType_t xSemaphoreTake (SemaphoreHandle_t xSemaphore, | |||
case queueQUEUE_TYPE_MUTEX: | |||
{ | |||
if (xTicksToWait == 0) { | |||
return (mutex_trylock(mutex) == 0) ? pdTRUE : pdFALSE; | |||
return (mutex_trylock(mutex) == 1) ? pdPASS : pdFAIL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JulianHolzwarth Don't change the return values. There is no reason for it. According to API reference, the return value of xSemaphoreTake is pdTRUE
or pdFALSE
. Even though the values are the same, we should use them as specified to avoid misleadings in future implementations of the FreeRTOS adaptation layer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was looking at the Reference Manual. It gave me more information about the function.
https://www.freertos.org/wp-content/uploads/2018/07/FreeRTOS_Reference_Manual_V10.0.0.pdf
(Page 244 ff.)
Linked from here:
https://www.freertos.org/Documentation/RTOS_book.html
If you like PdTrue
more I will change it.
How shall we proceed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latest official release http://www.freertos.org/a00104.html has return pdPASS;
and
https://github.com/aws/amazon-freertos/blob/edc41fb223b8f9529162651a7c0459b10b450164/freertos_kernel/queue.c#L1414
has the same.
(The other return is return errQUEUE_EMPTY
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's strange. Obviously, the official offline documentation does not fit the official online documentation. And even more strange, the documentation in semphr.h does not fit the implementatoin in queue.c.
The question is how errQUEUE_EMPTY
is defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might become a pitfall. By default, these values are defined:
#define errQUEUE_EMPTY ( ( BaseType_t ) 0 )
#define pdFALSE ( ( BaseType_t ) 0 )
#define pdFAIL ( pdFALSE )
Defining something like an error code which is nothing else or the same as pdFALSE
is quite strange, especially since other error codes are real values:
#define errQUEUE_BLOCKED ( -4 )
#define errQUEUE_YIELD ( -5 )
If someone concludes from the online documentation that xSemaphoreTake
returns something like a boolean, he could try the following:
if (!xSemaphoreTake(...)) {
...
}
Although it would work for errQUEUE_EMPTY
, it would not work for the other error codes.
@@ -147,7 +147,7 @@ BaseType_t xSemaphoreTakeRecursive (SemaphoreHandle_t xSemaphore, | |||
rmutex_t* rmutex = &((_rmutex_t*)xSemaphore)->rmutex; | |||
|
|||
if (xTicksToWait == 0) { | |||
ret = (rmutex_trylock(rmutex) == 0) ? pdTRUE : pdFALSE; | |||
ret = (rmutex_trylock(rmutex) == 1) ? pdPASS : pdFAIL; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return values should not be changed, see above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Finally, we can change the return values because they are mapped to pdTRUE and pdFALSE anyway. So there will be no difference.
Contribution description
Involved parts:
cpu/esp32/freertos/semphr.c
andtests/freertos
Added test to test freertos. At the moment only tests for
esp32-wroom-32
board the mutex semaphore creation andxSemaphoreTake()
and the reucursive mutex semaphore creation andxSemaphoreTakeRecursive()
.The future goal for this test is to test the complete freertos compatibility layer and to have the test for a general freertos compatibility layer that does not only work for esp32. I am currently working on a general freertos compatibility layer and trying to implement a test for it first, while doing it i noticed a bug.
Bug fix for
cpu/esp32/freertos/semphr.c::xSemaphoreTakeRecursive()
and cpu/esp32/freertos/semphr.c::xSemaphoreTake()
return value whenxTicksToWait
is 0. The bug is that the functions returnpdTRUE
when it failed andpdFALSE
when it was succesful.But they should return (freertos documentation):
Testing procedure
only whitelisted for
esp32-wroom-32
To test run
BOARD=esp32-wroom-32 make -C tests/freertos/ flash test
To see the the bug run the command before the return value fix commit (there is one for each function)