Skip to content

Commit f2f6bbc

Browse files
committed
Fixes for proper core compatibility
1 parent e0d9661 commit f2f6bbc

File tree

6 files changed

+307
-0
lines changed

6 files changed

+307
-0
lines changed

cores/arduino/Arduino.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <zephyr/drivers/pwm.h>
1414
#include <zephyr/drivers/adc.h>
1515
#include <zephyr/drivers/i2c.h>
16+
#include <math.h>
1617

1718
#if DT_PROP_LEN(DT_PATH(zephyr_user), digital_pin_gpios) > 0
1819
#define DIGITAL_PIN_EXISTS(n, p, i, dev, num) \
@@ -110,4 +111,8 @@ int digitalPinToInterrupt(pin_size_t pin);
110111
#ifdef __cplusplus
111112
#include <SerialUSB.h>
112113
#include <zephyrSerial.h>
114+
115+
// Allow namespace-less operations if Arduino.h is included
116+
using namespace arduino;
117+
113118
#endif // __cplusplus

cores/arduino/abi.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright (c) 2024 Arduino SA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <stdlib.h>
8+
9+
extern "C" void __cxa_pure_virtual(void) __attribute__ ((__noreturn__));
10+
extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
11+
12+
namespace std {
13+
[[gnu::weak, noreturn]] void terminate() {
14+
abort();
15+
}
16+
}
17+
18+
void __cxa_pure_virtual(void) {
19+
std::terminate();
20+
}
21+
22+
void __cxa_deleted_virtual(void) {
23+
std::terminate();
24+
}

cores/arduino/itoa.cpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
* Copyright (c) 2024 Arduino SA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <api/itoa.h>
8+
#include <string.h>
9+
10+
#ifdef __cplusplus
11+
extern "C" {
12+
#endif
13+
14+
#include <api/deprecated-avr-comp/avr/dtostrf.c.impl>
15+
16+
extern char* itoa( int value, char *string, int radix )
17+
{
18+
return ltoa( value, string, radix ) ;
19+
}
20+
21+
extern char* ltoa( long value, char *string, int radix )
22+
{
23+
char tmp[33];
24+
char *tp = tmp;
25+
long i;
26+
unsigned long v;
27+
int sign;
28+
char *sp;
29+
30+
if ( string == NULL )
31+
{
32+
return 0 ;
33+
}
34+
35+
if (radix > 36 || radix <= 1)
36+
{
37+
return 0 ;
38+
}
39+
40+
sign = (radix == 10 && value < 0);
41+
if (sign)
42+
{
43+
v = -value;
44+
}
45+
else
46+
{
47+
v = (unsigned long)value;
48+
}
49+
50+
while (v || tp == tmp)
51+
{
52+
i = v % radix;
53+
v = v / radix;
54+
if (i < 10)
55+
*tp++ = i+'0';
56+
else
57+
*tp++ = i + 'a' - 10;
58+
}
59+
60+
sp = string;
61+
62+
if (sign)
63+
*sp++ = '-';
64+
while (tp > tmp)
65+
*sp++ = *--tp;
66+
*sp = 0;
67+
68+
return string;
69+
}
70+
71+
extern char* utoa( unsigned int value, char *string, int radix )
72+
{
73+
return ultoa( value, string, radix ) ;
74+
}
75+
76+
extern char* ultoa( unsigned long value, char *string, int radix )
77+
{
78+
char tmp[33];
79+
char *tp = tmp;
80+
long i;
81+
unsigned long v = value;
82+
char *sp;
83+
84+
if ( string == NULL )
85+
{
86+
return 0;
87+
}
88+
89+
if (radix > 36 || radix <= 1)
90+
{
91+
return 0;
92+
}
93+
94+
while (v || tp == tmp)
95+
{
96+
i = v % radix;
97+
v = v / radix;
98+
if (i < 10)
99+
*tp++ = i+'0';
100+
else
101+
*tp++ = i + 'a' - 10;
102+
}
103+
104+
sp = string;
105+
106+
107+
while (tp > tmp)
108+
*sp++ = *--tp;
109+
*sp = 0;
110+
111+
return string;
112+
}
113+
114+
#ifdef __cplusplus
115+
} // extern "C"
116+
#endif

cores/arduino/new

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
* Copyright (c) 2024 Arduino SA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef NEW_H
8+
#define NEW_H
9+
10+
#include <stdlib.h>
11+
12+
namespace std {
13+
struct nothrow_t {};
14+
extern const nothrow_t nothrow;
15+
16+
// These are not actually implemented, to prevent overhead and
17+
// complexity. They are still declared to allow implementing
18+
// them in user code if needed.
19+
typedef void (*new_handler)();
20+
new_handler set_new_handler(new_handler new_p) noexcept;
21+
new_handler get_new_handler() noexcept;
22+
23+
// This is normally declared in various headers that we do not have
24+
// available, so just define it here. We could also use ::size_t
25+
// below, but then anyone including <new> can no longer assume
26+
// std::size_t is available.
27+
using size_t = ::size_t;
28+
} // namespace std
29+
30+
[[gnu::weak]] void * operator new(std::size_t size);
31+
[[gnu::weak]] void * operator new[](std::size_t size);
32+
33+
[[gnu::weak]] void * operator new(std::size_t size, const std::nothrow_t tag) noexcept;
34+
[[gnu::weak]] void * operator new[](std::size_t size, const std::nothrow_t& tag) noexcept;
35+
36+
void * operator new(std::size_t size, void *place) noexcept;
37+
void * operator new[](std::size_t size, void *place) noexcept;
38+
39+
[[gnu::weak]] void operator delete(void * ptr) noexcept;
40+
[[gnu::weak]] void operator delete[](void * ptr) noexcept;
41+
42+
#if __cplusplus >= 201402L
43+
[[gnu::weak]] void operator delete(void* ptr, std::size_t size) noexcept;
44+
[[gnu::weak]] void operator delete[](void * ptr, std::size_t size) noexcept;
45+
#endif // __cplusplus >= 201402L
46+
47+
[[gnu::weak]] void operator delete(void* ptr, const std::nothrow_t& tag) noexcept;
48+
[[gnu::weak]] void operator delete[](void* ptr, const std::nothrow_t& tag) noexcept;
49+
50+
void operator delete(void* ptr, void* place) noexcept;
51+
void operator delete[](void* ptr, void* place) noexcept;
52+
53+
#endif
54+

cores/arduino/new.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* Copyright (c) 2024 Arduino SA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "new.h"
8+
9+
// The C++ spec dictates that allocation failure should cause the
10+
// (non-nothrow version of the) operator new to throw an exception.
11+
// Since we expect to have exceptions disabled, it would be more
12+
// appropriate (and probably standards-compliant) to terminate instead.
13+
// Historically failure causes null to be returned, but this define
14+
// allows switching to more robust terminating behaviour (that might
15+
// become the default at some point in the future). Note that any code
16+
// that wants null to be returned can (and should) use the nothrow
17+
// versions of the new statement anyway and is unaffected by this.
18+
// #define NEW_TERMINATES_ON_FAILURE
19+
20+
namespace std {
21+
// Defined in abi.cpp
22+
void terminate();
23+
24+
const nothrow_t nothrow;
25+
}
26+
27+
static void * new_helper(std::size_t size) {
28+
// Even zero-sized allocations should return a unique pointer, but
29+
// malloc does not guarantee this
30+
if (size == 0)
31+
size = 1;
32+
return malloc(size);
33+
}
34+
35+
void * operator new(std::size_t size) {
36+
void *res = new_helper(size);
37+
#if defined(NEW_TERMINATES_ON_FAILURE)
38+
if (!res)
39+
std::terminate();
40+
#endif
41+
return res;
42+
}
43+
void * operator new[](std::size_t size) {
44+
return operator new(size);
45+
}
46+
47+
void * operator new(std::size_t size, const std::nothrow_t tag) noexcept {
48+
#if defined(NEW_TERMINATES_ON_FAILURE)
49+
// Cannot call throwing operator new as standard suggests, so call
50+
// new_helper directly then
51+
return new_helper(size);
52+
#else
53+
return operator new(size);
54+
#endif
55+
}
56+
void * operator new[](std::size_t size, const std::nothrow_t& tag) noexcept {
57+
#if defined(NEW_TERMINATES_ON_FAILURE)
58+
// Cannot call throwing operator new[] as standard suggests, so call
59+
// malloc directly then
60+
return new_helper(size);
61+
#else
62+
return operator new[](size);
63+
#endif
64+
}
65+
66+
void * operator new(std::size_t size, void *place) noexcept {
67+
// Nothing to do
68+
(void)size; // unused
69+
return place;
70+
}
71+
void * operator new[](std::size_t size, void *place) noexcept {
72+
return operator new(size, place);
73+
}
74+
75+
void operator delete(void * ptr) noexcept {
76+
free(ptr);
77+
}
78+
void operator delete[](void * ptr) noexcept {
79+
operator delete(ptr);
80+
}
81+
82+
#if __cplusplus >= 201402L
83+
void operator delete(void* ptr, std::size_t size) noexcept {
84+
operator delete(ptr);
85+
}
86+
void operator delete[](void * ptr, std::size_t size) noexcept {
87+
operator delete[](ptr);
88+
}
89+
#endif // __cplusplus >= 201402L
90+
91+
void operator delete(void* ptr, const std::nothrow_t& tag) noexcept {
92+
operator delete(ptr);
93+
}
94+
void operator delete[](void* ptr, const std::nothrow_t& tag) noexcept {
95+
operator delete[](ptr);
96+
}
97+
98+
void operator delete(void* ptr, void* place) noexcept {
99+
(void)ptr; (void)place; // unused
100+
// Nothing to do
101+
}
102+
void operator delete[](void* ptr, void* place) noexcept {
103+
(void)ptr; (void)place; // unused
104+
// Nothing to do
105+
}

cores/arduino/new.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file originally used a non-standard name for this Arduino core
2+
// only, so still expose the old new.h name for compatibility.
3+
#include "new"

0 commit comments

Comments
 (0)