Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Added 'extern "C"' modifiers for mixed C/C++ #5

Closed
wants to merge 1 commit into from

2 participants

@bacek

Hello.

While my first attempt to use AtomThreads with standard Arduino UNO I found that function declarations aren't exported as "C" functions. So, there is simple changes in kernel and avr port to add them.

Sorry, I didn't change other ports just because I don't have other hardware to test it.

Regards,
Vasily

@kelvinlawson

Thanks for the patch Vasily.

So that I can decide on the best place to put the extern C declarations, can you let me know your build environment please? Are you building the Atomthreads C modules as a separate project with a C compiler, and then linking the objects in with your application code built with a C++ compiler?

If the Atomthreads C modules are built separately with a C compiler, can you get the same effect by surrounding the #include's of Atomthreads header files in your application code with extern C declarations?

@bacek

Hello Kevin.

This is pretty much standard mixed C/C++ project. C code compiled with C compiler, C++ with C++. Linking done with C++ compiler.

Yes, I can surround atomThreas includes with 'extern "C"' declarations but it's really-really bad way. '#ifdef __cplusplus' appoach is commonly used for such projects. For example glibc (or any other linux's libraries includes uses it). Or Parrot VM which is dual-compilable.

Vasily

@kelvinlawson

Thanks. I'm familiar with the mechanism, although typically I'm working in C and linking with C++ libraries rather than the other way round. Just trying to establish what subset of header files I should roll it out into, including the other architecture ports which are not changed in the pull request.

The main "public" header files are:

  • atom.h
  • atommutex.h
  • atomqueue.h
  • atomsem.h
  • atomtimer.h

The rest of the headers are typically not included by external applications, or are included but only via inclusion from one of the public headers (atom.h etc). I note that your change puts the extern C declarations underneath the inclusion of other headers (e.g. in atom.h it's placed after the other header inclusions). Was there any reason for this or can it be placed above the headers?

My thinking is that I'll place these extern C declarations in the public headers, and the rest of them will work without modification if they are included inside the same declarations. This way we can merge in exact copies of CPU vendor headers unmodified, and don't have to make changes to all of the existing header ports. I'd just like to check with you whether this would work for you. Since you are the best person to test this right now, it would be great if you could try this instead please: just put the extern C declarations in the above 5 files and make sure it surrounds the internal header includes. If that works for you then I'll merge that straight in.

Thanks for your submission & help.

@kelvinlawson

Modifiers now added to the main public header files as described in my last comment. Please let me know if you need find further header files need to be modified. Thanks for your submission.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
View
8 kernel/atom.h
@@ -33,6 +33,10 @@
#include "atomtimer.h"
#include "atomport.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Data types */
/* Forward declaration */
@@ -122,5 +126,9 @@ extern void archFirstThreadRestore(ATOM_TCB *new_tcb_ptr);
extern void atomTimerTick (void);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ATOM_H */
View
8 kernel/atommutex.h
@@ -29,6 +29,10 @@
#ifndef __ATOM_MUTEX_H
#define __ATOM_MUTEX_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct atom_mutex
{
ATOM_TCB * suspQ; /* Queue of threads suspended on this mutex */
@@ -41,4 +45,8 @@ extern uint8_t atomMutexDelete (ATOM_MUTEX *mutex);
extern uint8_t atomMutexGet (ATOM_MUTEX *mutex, int32_t timeout);
extern uint8_t atomMutexPut (ATOM_MUTEX *mutex);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ATOM_MUTEX_H */
View
8 kernel/atomport-template.h
@@ -31,6 +31,10 @@
#define __ATOM_PORT_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Required number of system ticks per second (normally 100 for 10ms tick) */
#define SYSTEM_TICKS_PER_SEC 100
@@ -74,5 +78,9 @@
/* Uncomment to enable stack-checking */
/* #define ATOM_STACK_CHECKING */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ATOM_PORT_H */
View
8 kernel/atomqueue.h
@@ -29,6 +29,10 @@
#ifndef __ATOM_QUEUE_H
#define __ATOM_QUEUE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct atom_queue
{
ATOM_TCB * putSuspQ; /* Queue of threads waiting to send */
@@ -46,4 +50,8 @@ extern uint8_t atomQueueDelete (ATOM_QUEUE *qptr);
extern uint8_t atomQueueGet (ATOM_QUEUE *qptr, int32_t timeout, uint8_t *msgptr);
extern uint8_t atomQueuePut (ATOM_QUEUE *qptr, int32_t timeout, uint8_t *msgptr);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ATOM_QUEUE_H */
View
8 kernel/atomsem.h
@@ -30,6 +30,10 @@
#ifndef __ATOM_SEM_H
#define __ATOM_SEM_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct atom_sem
{
ATOM_TCB * suspQ; /* Queue of threads suspended on this semaphore */
@@ -42,4 +46,8 @@ extern uint8_t atomSemGet (ATOM_SEM *sem, int32_t timeout);
extern uint8_t atomSemPut (ATOM_SEM *sem);
extern uint8_t atomSemResetCount (ATOM_SEM *sem, uint8_t count);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ATOM_SEM_H */
View
8 kernel/atomtimer.h
@@ -32,6 +32,10 @@
#include "atomport.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Callback function prototype */
typedef void ( * TIMER_CB_FUNC ) ( POINTER cb_data ) ;
@@ -58,4 +62,8 @@ extern uint8_t atomTimerDelay (uint32_t ticks);
extern uint32_t atomTimeGet (void);
extern void atomTimeSet (uint32_t new_time);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ATOM_TIMER_H */
View
8 ports/avr/atomport-private.h
@@ -30,10 +30,18 @@
#ifndef __ATOM_PORT_PRIVATE_H
#define __ATOM_PORT_PRIVATE_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* CPU Frequency */
#define AVR_CPU_HZ 1000000
/* Function prototypes */
void avrInitSystemTickTimer ( void );
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ATOM_PORT_PRIVATE_H */
View
8 ports/avr/atomport.h
@@ -40,6 +40,10 @@
/* Definition of NULL is available from stddef.h on this platform */
#include <stddef.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* Required number of system ticks per second (normally 100 for 10ms tick) */
#define SYSTEM_TICKS_PER_SEC 100
@@ -68,5 +72,9 @@
/* Uncomment to enable stack-checking */
/* #define ATOM_STACK_CHECKING */
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __ATOM_PORT_H */
View
8 ports/avr/uart.h
@@ -13,6 +13,9 @@
#include "atom.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
/*
* Perform UART startup initialization.
@@ -23,3 +26,8 @@ int uart_init(uint32_t baudrate);
* Send one character to the UART.
*/
int uart_putchar(char c, FILE *stream);
+
+#ifdef __cplusplus
+}
+#endif
+
Something went wrong with that request. Please try again.