Building FreeRTOS + POSIX with GCC for RISC V architecture

Hi,
I see typedef conflict between #include<sys/types.h> and #include"FreeRTOS_POSIX/sys/types.h"

riscv64-unknown-elf-gcc --version
riscv64-unknown-elf-gcc (GCC) 9.2.0

FreeRTOS Source from

Building this code on Ubuntu 18.04

What i am trying todo :
Building FreeRTOS + POSIXs lib with GCC for RISC V arch.

The issue I see :
Conflicting type definitions between GCC sys/types.h and FreeRTOS_POSIX/sys/types.h,

the stdio.h from GCC includes sys/types.h, so that is leading to the conflict, the freeRTOS code DOES NOT include GCC’s sys/types.h (NO use of #include<sys/types.h>)

Error :
CC posix_demo.c
In file included from …/Source/lib/FreeRTOS-Plus-POSIX/include/FreeRTOS_POSIX.h:47,
from posix_demo.c:76:
…/Source/lib/include/FreeRTOS_POSIX/sys/types.h:48:38: error: conflicting types for ‘clock_t’
48 | typedef uint32_t clock_t;
| ^~~~~~~
In file included from /opt/riscv64/riscv64-unknown-elf/include/stdio.h:61,
from posix_demo.c:73:
/opt/riscv64/riscv64-unknown-elf/include/sys/types.h:107:19: note: previous declaration of ‘clock_t’ was here
107 | typedef CLOCK_T clock_t;
| ^~~~~~~
In file included from …/Source/lib/FreeRTOS-Plus-POSIX/include/FreeRTOS_POSIX.h:47,
from posix_demo.c:76:
…/Source/lib/include/FreeRTOS_POSIX/sys/types.h:57:38: error: conflicting types for ‘clockid_t’
57 | typedef int clockid_t;
| ^~~~~~~~~
In file included from /opt/riscv64/riscv64-unknown-elf/include/stdio.h:61,
from posix_demo.c:73:
/opt/riscv64/riscv64-unknown-elf/include/sys/types.h:199:21: note: previous declaration of ‘clockid_t’ was here
199 | typedef __clockid_t clockid_t;
| ^~~~~~~~~

I have tried changing the posixconfigENABLE_CLOCK_T / ENABLE_CLOCKID_T in FreeRTOS_POSIX_portable_default.h

82 /**
83 * @name Enable typedefs of POSIX types.
84 *
85 * Set these values to 1 or 0 to enable or disable the typedefs, respectively.
86 * These typedefs should only be disabled if they conflict with system typedefs.
87 */
88 / @{ */
89 #ifndef posixconfigENABLE_CLOCK_T
90 #define posixconfigENABLE_CLOCK_T 1 /
< clock_t in sys/types.h */
91 #endif
92 #ifndef posixconfigENABLE_CLOCKID_T
93 #define posixconfigENABLE_CLOCKID_T 1 /**< clockid_t in sys/types.h */
94 #endif

If i have to use the type defs from GCC i.e include<sys/types.h>, then i will have to edit the freeRTOS source files to change - “FreeRTOS_POSIX/sys/types.h” to <sys/types.h> I dont think this will be a good approach

Please suggest how to resolve this issue. Thanks
James

1 Like

Thanks for the info - I will have to check to see if we need to make any updates then report back.

One way to resolve conflicting type definition is to selectively enable type definition in FreeRTOS_POSIX_portable_default.h. As an example, please see portable/espressif/esp32_devkitc_esp_wrover_kit/FreeRTOS_POSIX_portable.h. This port is using sys/types.h provided by third party (line 35 disabled clock_t definition in FreeRTOS+POSIX, and line 58 included sys/type.h from system search directory).

This mix-and-match may seem messy. Though, POSIX systems are supposed to follow standard definitions. In this case for sys/types.h, https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.htmlclock_t shall be an integer or real-floating type. time_t shall be an integer type.” In FreeRTOS+POSIX clock_t is of type uint32_t, and could double check that your toolchain type definition can be cast to uint32_t.

One thing to call out – mix-and-match type definition may be fine (if both systems are following standard definition), additional effort is needed if to mix implementations. In the same example – line 50, we are using third party’s sched.h definition and also implementation; line 54 using FreeRTOS+POSIX time.h; …

1 Like

Hi Yuhui,
Thanks for the pointer, the build did go ahead. so now with below defines

70 #define _TIMER_T_DECLARED
71 #define __timer_t_defined
72
73 #define _CLOCKID_T_DECLARED
74 #define __clockid_t_defined
75
76 #define _CLOCK_T_DECLARED
77 #define __clock_t_defined
78
79 /* System headers. /
80 #include <stdbool.h>
81 #include <string.h>
82 #include <stdio.h>
83
84 /
FreeRTOS includes. */
85 #include “FreeRTOS_POSIX.h”
86
“posix_demo.c” << in the file , the errors related to clock_t , clockid_t, etc… are resolved.

When I made the change in Source/lib/FreeRTOS-Plus-POSIX/include/portable/FreeRTOS_POSIX_portable.h , the defines made no difference, so i moved them above very first use of include <stdio.h> in posix_demo.c then it seem to have the desired effect.

The next error build fails is due to struct itimerspec and struct timespec , conflict / redefinition.

Error Message :
…/Source/lib/include/FreeRTOS_POSIX/time.h:78:12: error: redefinition of ‘struct timespec’
78 | struct timespec
| ^~~~~~~~
In file included from /opt/riscv64/riscv64-unknown-elf/include/sys/timespec.h:38,
from /opt/riscv64/riscv64-unknown-elf/include/sys/select.h:16,
from /opt/riscv64/riscv64-unknown-elf/include/sys/types.h:50,
from /opt/riscv64/riscv64-unknown-elf/include/stdio.h:61,
from posix_demo.c:83:
/opt/riscv64/riscv64-unknown-elf/include/sys/_timespec.h:45:8: note: originally defined here
45 | struct timespec {
| ^~~~~~~~
In file included from …/Source/lib/include/FreeRTOS_POSIX/pthread.h:39,
from posix_demo.c:96:
…/Source/lib/include/FreeRTOS_POSIX/time.h:90:12: error: redefinition of ‘struct itimerspec’
90 | struct itimerspec
| ^~~~~~~~~~
In file included from /opt/riscv64/riscv64-unknown-elf/include/sys/select.h:16,
from /opt/riscv64/riscv64-unknown-elf/include/sys/types.h:50,
from /opt/riscv64/riscv64-unknown-elf/include/stdio.h:61,
from posix_demo.c:83:
/opt/riscv64/riscv64-unknown-elf/include/sys/timespec.h:58:8: note: originally defined here
58 | struct itimerspec {
| ^~~~~~~~~~

in the case of sys/types.h, i see the below defines to just enabled them, but see no such defines in timespec and itimespec case.

#if !defined(__clockid_t_defined) && !defined(_CLOCKID_T_DECLARED)

typedef __clockid_t clockid_t;

#define __clockid_t_defined

#define _CLOCKID_T_DECLARED

#endif

I am not able to upload the file FreeRTOS_POSIX_portable.h [New users are not allowed to upload ].
I used the file you pointed in “espressif” port and removed the defines for
// #define posixconfigENABLE_CLOCK_T 0
// #define posixconfigENABLE_CLOCKID_T 0
// #define posixconfigENABLE_TIMESPEC 0
// #define posixconfigENABLE_ITIMERSPEC 0

to use the FreeRTOS definition.

Question :

  1. Do you suggest adding #ifndef itimerspec_defined in sys/timespec.h and timespec.h also ? May be will hit similar issues with posixconfigENABLE_PTHREAD* configs also ?

  2. If i Do define below in FreeRTOS_POSIX_portable.h
    #define posixconfigENABLE_TIMESPEC 0
    #define posixconfigENABLE_ITIMERSPEC 0

I get the below warning and error, as struct timespec is not declared , so resolve this i have to include time.h from the RISC V tool chain path NOT FreeRTOS_POSIX/time.h

…/Source/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c: At top level:
…/Source/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c:164:42: warning: ‘struct timespec’ declared inside parameter list will not be visible outside of this definition or declaration
164 | struct timespec * const pxDestination )
| ^~~~~~~~
…/Source/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c:163:6: error: conflicting types for ‘UTILS_NanosecondsToTimespec’
163 | void UTILS_NanosecondsToTimespec( int64_t llSource,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from …/Source/lib/FreeRTOS-Plus-POSIX/source/FreeRTOS_POSIX_utils.c:38:
…/Source/lib/include/FreeRTOS_POSIX/utils.h:90:6: note: previous declaration of ‘UTILS_NanosecondsToTimespec’ was here
90 | void UTILS_NanosecondsToTimespec( int64_t llSource,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~

Not sure if these issues is specific to RISC V tool chain.

Please let me know, what you think.
Thanks
J

To your questions:

  1. If timespec.h is not part of the POSIX standards, so that we don’t have this header in FreeRTOS+POSIX. (Please use this link – https://pubs.opengroup.org/onlinepubs/9699919799/, this is of version “Issue 7, 2018”) Instead, timespec and itimerspec are defined in time.h, per specification https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html. In our implementation, timespec only includes two members tv_sec and tv_nsec. (Similarly logic for itimerspec.) So if the interfaces your application and/or toolchain is calling requires more than these two members, you may be looking for toolchain’s implementation of time.h instead of FreeRTOS+POSIX. (As mentioned in the post, may need some effort in first defining which POSIX implementation to use. We all claim “POSIX compliant”, though in reality there may be subtle deviation for how closely standard is followed.)

  2. For FreeRTOS_POSIX_portable.h and also your earlier comment on " the defines made no difference", there may be some issue in how project/include directory is setup. Please double check this header can be found and referenced correctly by compiler.

1 Like

I am able to build code now, when stdio.h is NOT included in posix_demo.c Using FreeRTOS data types for all. so there are NO FreeRTOS_POSIX_portable.h overrides.

But i see issues when i try to execute the code.

I am Using Spike simulator, the execution stops with :
*** FAILED *** (tohost = 4)
looks like pthread_join() did not return, issue might be in xQueueSemaphoreTake()

Can you tell me if i can enable some debug / trace in FreeRTOS to get to the reason for crash ?

reason for the crash could be the definition of pthread_t, which is void * now, but in the demo when used on Windows its a Long Long Int.

Appreciate if you can give some pointers on how to get to the root cause of this issue. Thanks

I would be grateful if you could attach the POSIX relevant headers files that get included in your build so we can try and set up a similar scenario here. We won’t be able to run in Spike, but I think the mismatched data types are more relevant than the architecture.

Hi Richard,

I got the riscv toolchain from - git clone --recursive https://github.com/riscv/riscv-gnu-toolchain

The conflict and redefinition errors seen when stdio.h was included in posix_demo.c :

for 1 and 2 by defining the below, we can skip the toolchain definition, but for the other cases 3,4 and 5 i did not see that option.
#define _CLOCKID_T_DECLARED
#define __clockid_t_defined
#define _CLOCK_T_DECLARED
#define __clock_t_defined

1
…/Source/lib/include/FreeRTOS_POSIX/sys/types.h:48:38: error: conflicting types for ‘clock_t’
48 | typedef uint32_t clock_t;

/opt/riscv64/riscv64-unknown-elf/include/sys/types.h:107:19: note: previous declaration of ‘clock_t’ was here
107 | typedef CLOCK_T clock_t;

2
…/Source/lib/include/FreeRTOS_POSIX/sys/types.h:57:38: error: conflicting types for ‘clockid_t’
57 | typedef int clockid_t;
/opt/riscv64/riscv64-unknown-elf/include/sys/types.h:199:21: note: previous declaration of ‘clockid_t’ was here
199 | typedef __clockid_t clockid_t;

3
…/Source/lib/include/FreeRTOS_POSIX/sys/types.h:152:38: error: conflicting types for ‘ssize_t’
152 | typedef int ssize_t;
| ^~~~~~~
/opt/riscv64/riscv64-unknown-elf/include/sys/types.h:184:18: note: previous declaration of ‘ssize_t’ was here
184 | typedef _ssize_t ssize_t;
| ^~~~~~~

4
…/Source/lib/include/FreeRTOS_POSIX/time.h:78:12: error: redefinition of ‘struct timespec’
78 | struct timespec
| ^~~~~~~~
In file included from /opt/riscv64/riscv64-unknown-elf/include/sys/timespec.h:38,
from /opt/riscv64/riscv64-unknown-elf/include/sys/select.h:16,
from /opt/riscv64/riscv64-unknown-elf/include/sys/types.h:50,
from /opt/riscv64/riscv64-unknown-elf/include/stdio.h:61,
from posix_demo.c:83:
/opt/riscv64/riscv64-unknown-elf/include/sys/_timespec.h:45:8: note: originally defined here
45 | struct timespec {
| ^~~~~~~~

5
…/Source/lib/include/FreeRTOS_POSIX/pthread.h:98:8: error: redefinition of ‘struct sched_param’
98 | struct sched_param
| ^~~~~~~~~~~
In file included from /opt/riscv64/riscv64-unknown-elf/include/sys/_pthreadtypes.h:23,
from /opt/riscv64/riscv64-unknown-elf/include/sys/types.h:223,
from /opt/riscv64/riscv64-unknown-elf/include/stdio.h:61,
from posix_demo.c:74:
/opt/riscv64/riscv64-unknown-elf/include/sys/sched.h:48:8: note: originally defined here
48 | struct sched_param {
| ^~~~~~~~~~~

Please see let me know, how to resolve these errors

in comment 6 you mentioned “We won’t be able to run in Spike” so you are suggesting to look at other alternatives, like Qemu ? has someone looked as using FreeRTOS + Posix on Qemu for any architecture ?

Let me know, Thanks
J

I was only meaning we don’t have Spike set up here so we won’t run it in Spike - not that FreeRTOS won’t run in Spike. I have no idea if FreeRTOS will run in Spike or not but I would assume it does.

We do run in QEMU, but note odd behaviour of the machine timer that does not make the code crash, but does make tests fail (because tests expect ticks to be regularly spaced whereas in QEMU they are erratic).

When i run my FreeRTOS + POSIX port on spike, i get (tohost = 4)

How can i get to the rootcause of the crash - *** FAILED *** (tohost = 4)

I have tried using GDB + DDD , when i put a forced hang (while(1)) and change the $PC to single step form last known point, i see debugger ends up in trap_entry().

When i tried to add printfs , i see part of the trace is getting truncated.

Pls suggest how i can proceed. Thanks
J

Sorry - never used Spike.