Skip to content

Commit 770608a

Browse files
authored
Add nanosleep function (#383)
Signed-off-by: David Laseca Perez <davidlaseca@eprosima.com>
1 parent 108d5c3 commit 770608a

2 files changed

Lines changed: 36 additions & 1 deletion

File tree

‎CMakeLists.txt‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
option(BUILD_ETHERNET_INTERFACE "Build ethernet interface support" OFF)
22
option(BUILD_WLAN_INTERFACE "Build wlan interface support" ON)
33

4-
set(COMPONENT_SRC "")
4+
set(COMPONENT_SRC "posix_functions/nanosleep.c")
55

66
if(BUILD_ETHERNET_INTERFACE)
77
list(APPEND COMPONENT_SRC "network_interfaces/uros_ethernet_netif.c")
@@ -102,6 +102,10 @@ target_compile_definitions(${COMPONENT_LIB} PUBLIC RCL_MICROROS)
102102
add_dependencies(${COMPONENT_LIB} libmicroros-prebuilt)
103103
target_link_libraries(${COMPONENT_LIB} INTERFACE libmicroros-prebuilt)
104104

105+
# libmicroros.a is linked after this component, so force the linker to pull
106+
# in the nanosleep() shim before rclc references it
107+
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u nanosleep")
108+
105109
set_directory_properties( PROPERTIES ADDITIONAL_CLEAN_FILES
106110
"${COMPONENT_DIR}/include;${COMPONENT_DIR}/micro_ros_dev;${COMPONENT_DIR}/micro_ros_src;${COMPONENT_DIR}/esp32_toolchain.cmake" )
107111

‎posix_functions/nanosleep.c‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <errno.h>
2+
#include <time.h>
3+
#include <unistd.h>
4+
5+
// ESP-IDF defines _POSIX_TIMERS but does not implement nanosleep()
6+
// Declared weak so that a native ESP-IDF implementation takes precedence
7+
__attribute__((weak)) int nanosleep(const struct timespec * req, struct timespec * rem)
8+
{
9+
(void) rem; // Never interrupted: FreeRTOS has no signals
10+
11+
if (req == NULL ||
12+
req->tv_sec < 0 ||
13+
req->tv_nsec < 0 ||
14+
req->tv_nsec >= 1000000000L) {
15+
errno = EINVAL;
16+
return -1;
17+
}
18+
19+
// Sleep the whole seconds without overflowing useconds_t
20+
for (time_t s = 0; s < req->tv_sec; s++) {
21+
usleep(1000000);
22+
}
23+
24+
// Round the remaining nanoseconds up to microseconds
25+
useconds_t us = (req->tv_nsec + 999) / 1000;
26+
if (us > 0) {
27+
usleep(us);
28+
}
29+
30+
return 0;
31+
}

0 commit comments

Comments
 (0)