mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-03 14:38:30 -04:00
AP_Progmem created: progmem macros per specific platform
* derived from AP_Common
This commit is contained in:
parent
a2f97ac7c7
commit
5c738810e2
@ -12,47 +12,11 @@
|
||||
/// libraries.
|
||||
///
|
||||
|
||||
#ifndef _AP_COMMON_H
|
||||
#define _AP_COMMON_H
|
||||
|
||||
#include <string.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#ifndef EXCLUDECORE
|
||||
// Get the common arduino functions
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "wiring.h"
|
||||
#endif
|
||||
// ... and remove some of their stupid macros
|
||||
#undef round
|
||||
#undef abs
|
||||
#endif
|
||||
|
||||
// prog_char_t is used as a wrapper type for prog_char, which is
|
||||
// a character stored in flash. By using this wrapper type we can
|
||||
// auto-detect at compile time if a call to a string function is using
|
||||
// a flash-stored string or not
|
||||
typedef struct {
|
||||
char c;
|
||||
} prog_char_t;
|
||||
#ifndef __AP_COMMON_H__
|
||||
#define __AP_COMMON_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "c++.h" // c++ additions
|
||||
//#include "AP_Vector.h"
|
||||
//#include "AP_Loop.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @name Warning control
|
||||
//@{
|
||||
//
|
||||
// Turn on/off warnings of interest.
|
||||
//
|
||||
// These warnings are normally suppressed by the Arduino IDE,
|
||||
// but with some minor hacks it's possible to have warnings
|
||||
// emitted. This helps greatly when diagnosing subtle issues.
|
||||
//
|
||||
#pragma GCC diagnostic warning "-Wall"
|
||||
#pragma GCC diagnostic warning "-Wextra"
|
||||
#pragma GCC diagnostic warning "-Wlogical-op"
|
||||
@ -74,117 +38,10 @@ typedef struct {
|
||||
# undef PSTR
|
||||
# define PSTR(_x) _x // help the compiler with printf_P
|
||||
# define float double // silence spurious format warnings for %f
|
||||
#else
|
||||
// This is a workaround for GCC bug c++/34734.
|
||||
//
|
||||
// The C++ compiler normally emits many spurious warnings for the use
|
||||
// of PSTR (even though it generates correct code). This workaround
|
||||
// has an equivalent effect but avoids the warnings, which otherwise
|
||||
// make finding real issues difficult.
|
||||
//
|
||||
#ifdef DESKTOP_BUILD
|
||||
# undef PROGMEM
|
||||
# define PROGMEM __attribute__(())
|
||||
#else
|
||||
# undef PROGMEM
|
||||
# define PROGMEM __attribute__(( section(".progmem.data") ))
|
||||
#endif
|
||||
|
||||
# undef PSTR
|
||||
/* Need const type for progmem - new for avr-gcc 4.6 */
|
||||
# if __AVR__ && __GNUC__ == 4 && __GNUC_MINOR__ > 5
|
||||
# define PSTR(s) (__extension__({static const prog_char __c[] PROGMEM = (s); \
|
||||
(const prog_char_t *)&__c[0]; }))
|
||||
#else
|
||||
# define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); \
|
||||
(prog_char_t *)&__c[0]; }))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// a varient of PSTR() for progmem strings passed to %S in printf()
|
||||
// this gets the gcc __format__ checking right
|
||||
#define FPSTR(s) (wchar_t *)(s)
|
||||
|
||||
|
||||
static inline int strcasecmp_P(const char *str1, const prog_char_t *pstr)
|
||||
{
|
||||
return strcasecmp_P(str1, (const prog_char *)pstr);
|
||||
}
|
||||
|
||||
static inline int strcmp_P(const char *str1, const prog_char_t *pstr)
|
||||
{
|
||||
return strcmp_P(str1, (const prog_char *)pstr);
|
||||
}
|
||||
|
||||
static inline size_t strlen_P(const prog_char_t *pstr)
|
||||
{
|
||||
return strlen_P((const prog_char *)pstr);
|
||||
}
|
||||
|
||||
static inline void * memcpy_P(void *dest, const prog_char_t *src, size_t n)
|
||||
{
|
||||
return memcpy_P(dest, (const prog_char *)src, n);
|
||||
}
|
||||
|
||||
// strlcat_P() in AVR libc seems to be broken
|
||||
static inline size_t strlcat_P(char *d, const prog_char_t *s, size_t bufsize)
|
||||
{
|
||||
size_t len1 = strlen(d);
|
||||
size_t len2 = strlen_P(s);
|
||||
size_t ret = len1 + len2;
|
||||
|
||||
if (len1+len2 >= bufsize) {
|
||||
if (bufsize < (len1+1)) {
|
||||
return ret;
|
||||
}
|
||||
len2 = bufsize - (len1+1);
|
||||
}
|
||||
if (len2 > 0) {
|
||||
memcpy_P(d+len1, s, len2);
|
||||
d[len1+len2] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline char * strncpy_P(char *buffer, const prog_char_t *pstr, size_t buffer_size)
|
||||
{
|
||||
return strncpy_P(buffer, (const prog_char *)pstr, buffer_size);
|
||||
}
|
||||
|
||||
|
||||
// read something the size of a pointer. This makes the menu code more
|
||||
// portable
|
||||
static inline uintptr_t pgm_read_pointer(const void *s)
|
||||
{
|
||||
if (sizeof(uintptr_t) == sizeof(uint16_t)) {
|
||||
return (uintptr_t)pgm_read_word(s);
|
||||
} else {
|
||||
union {
|
||||
uintptr_t p;
|
||||
uint8_t a[sizeof(uintptr_t)];
|
||||
} u;
|
||||
uint8_t i;
|
||||
for (i=0; i< sizeof(uintptr_t); i++) {
|
||||
u.a[i] = pgm_read_byte(i + (const prog_char *)s);
|
||||
}
|
||||
return u.p;
|
||||
}
|
||||
}
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
///
|
||||
/// @name Macros
|
||||
/// @{
|
||||
|
||||
/// Define a constant string in program memory. This is a little more obvious
|
||||
/// and less error-prone than typing the declaration out by hand. It's required
|
||||
/// when passing PROGMEM strings to static object constructors because the PSTR
|
||||
/// hack can't be used at global scope.
|
||||
///
|
||||
#define PROGMEM_STRING(_v, _s) static const char _v[] PROGMEM = _s
|
||||
|
||||
#define ToRad(x) (x*0.01745329252) // *pi/180
|
||||
#define ToDeg(x) (x*57.2957795131) // *180/pi
|
||||
// @}
|
||||
@ -223,19 +80,6 @@ struct Location {
|
||||
///
|
||||
//@{
|
||||
|
||||
/// XXX this should probably be replaced with radians()/degrees(), but their
|
||||
/// inclusion in wiring.h makes doing that here difficult.
|
||||
#define ToDeg(x) (x*57.2957795131) // *180/pi
|
||||
#define ToRad(x) (x*0.01745329252) // *pi/180
|
||||
|
||||
//@}
|
||||
|
||||
#ifdef DESKTOP_BUILD
|
||||
// used to report serious errors in autotest
|
||||
# define SITL_debug(fmt, args ...) fprintf(stdout, "%s:%u " fmt, __FUNCTION__, __LINE__, ## args)
|
||||
#else
|
||||
# define SITL_debug(fmt, args ...)
|
||||
#endif
|
||||
|
||||
/* Product IDs for all supported products follow */
|
||||
|
||||
|
14
libraries/AP_Progmem/AP_Progmem.h
Normal file
14
libraries/AP_Progmem/AP_Progmem.h
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
#ifndef __AP_PROGMEM_H__
|
||||
#define __AP_PROGMEM_H__
|
||||
|
||||
#if defined(__AVR__)
|
||||
#include "AP_Progmem_AVR.h"
|
||||
#elif defined(DESKTOP_BUILD)
|
||||
#include "AP_Progmem_DesktopBuild.h"
|
||||
#endif
|
||||
|
||||
#define PROGMEM_STRING(_v, _s) static const char _v[] PROGMEM = _s
|
||||
|
||||
#endif // __AP_PROGMEM_H__
|
||||
|
29
libraries/AP_Progmem/AP_Progmem_AVR.cpp
Normal file
29
libraries/AP_Progmem/AP_Progmem_AVR.cpp
Normal file
@ -0,0 +1,29 @@
|
||||
|
||||
/* Only build this file for AVR - it exists to provide overrides for
|
||||
* broken avr libc */
|
||||
#ifdef __AVR__
|
||||
|
||||
#include <string.h>
|
||||
#include "AP_Progmem.h"
|
||||
|
||||
// strlcat_P() in AVR libc seems to be broken
|
||||
size_t strlcat_P(char *d, const prog_char_t *s, size_t bufsize)
|
||||
{
|
||||
size_t len1 = strlen(d);
|
||||
size_t len2 = strlen_P(s);
|
||||
size_t ret = len1 + len2;
|
||||
|
||||
if (len1+len2 >= bufsize) {
|
||||
if (bufsize < (len1+1)) {
|
||||
return ret;
|
||||
}
|
||||
len2 = bufsize - (len1+1);
|
||||
}
|
||||
if (len2 > 0) {
|
||||
memcpy_P(d+len1, s, len2);
|
||||
d[len1+len2] = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif // __AVR__
|
74
libraries/AP_Progmem/AP_Progmem_AVR.h
Normal file
74
libraries/AP_Progmem/AP_Progmem_AVR.h
Normal file
@ -0,0 +1,74 @@
|
||||
|
||||
#ifndef __AP_PROGMEM_AVR_H__
|
||||
#define __AP_PROGMEM_AVR_H__
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#define SITL_debug(fmt, args ...)
|
||||
|
||||
// prog_char_t is used as a wrapper type for prog_char, which is
|
||||
// a character stored in flash. By using this wrapper type we can
|
||||
// auto-detect at compile time if a call to a string function is using
|
||||
// a flash-stored string or not
|
||||
typedef struct {
|
||||
char c;
|
||||
} prog_char_t;
|
||||
|
||||
#undef PSTR
|
||||
/* Need const type for progmem - new for avr-gcc 4.6 */
|
||||
#if __AVR__ && __GNUC__ == 4 && __GNUC_MINOR__ > 5
|
||||
#define PSTR(s) (__extension__({static const prog_char __c[] PROGMEM = (s); \
|
||||
(const prog_char_t *)&__c[0]; }))
|
||||
#else
|
||||
#define PSTR(s) (__extension__({static prog_char __c[] PROGMEM = (s); \
|
||||
(prog_char_t *)&__c[0]; }))
|
||||
#endif
|
||||
|
||||
|
||||
static inline int strcasecmp_P(const char *str1, const prog_char_t *pstr)
|
||||
{
|
||||
return strcasecmp_P(str1, (const prog_char *)pstr);
|
||||
}
|
||||
|
||||
static inline int strcmp_P(const char *str1, const prog_char_t *pstr)
|
||||
{
|
||||
return strcmp_P(str1, (const prog_char *)pstr);
|
||||
}
|
||||
|
||||
static inline size_t strlen_P(const prog_char_t *pstr)
|
||||
{
|
||||
return strlen_P((const prog_char *)pstr);
|
||||
}
|
||||
|
||||
static inline void *memcpy_P(void *dest, const prog_char_t *src, size_t n)
|
||||
{
|
||||
return memcpy_P(dest, (const prog_char *)src, n);
|
||||
}
|
||||
|
||||
|
||||
static inline char *strncpy_P(char *buffer, const prog_char_t *pstr, size_t buffer_size)
|
||||
{
|
||||
return strncpy_P(buffer, (const prog_char *)pstr, buffer_size);
|
||||
}
|
||||
|
||||
|
||||
// read something the size of a pointer. This makes the menu code more
|
||||
// portable
|
||||
static inline uintptr_t pgm_read_pointer(const void *s)
|
||||
{
|
||||
if (sizeof(uintptr_t) == sizeof(uint16_t)) {
|
||||
return (uintptr_t)pgm_read_word(s);
|
||||
} else {
|
||||
union {
|
||||
uintptr_t p;
|
||||
uint8_t a[sizeof(uintptr_t)];
|
||||
} u;
|
||||
uint8_t i;
|
||||
for (i=0; i< sizeof(uintptr_t); i++) {
|
||||
u.a[i] = pgm_read_byte(i + (const prog_char *)s);
|
||||
}
|
||||
return u.p;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // __AP_PROGMEM_AVR_H__
|
20
libraries/AP_Progmem/AP_Progmem_DesktopBuild.h
Normal file
20
libraries/AP_Progmem/AP_Progmem_DesktopBuild.h
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
#ifndef __AP_PROGMEM_DESKTOP_BUILD_H__
|
||||
#define __AP_PROGMEM_DESKTOP_BUILD_H__
|
||||
|
||||
#ifndef __AP_PROGMEM_H__
|
||||
#error "Do not import AP_Progmem_DesktopBuild.h directly - use AP_Progmem.h"
|
||||
#endif // __AP_PROGMEM_H__
|
||||
|
||||
/* Inherit AVR definitions for everything else */
|
||||
#include "AP_Progmem_AVR.h"
|
||||
|
||||
#undef PROGMEM
|
||||
#define PROGMEM __attribute__(())
|
||||
|
||||
#undef SITL_debug
|
||||
#define SITL_debug(fmt, args ...) fprintf(stdout, "%s:%u " fmt, __FUNCTION__, __LINE__, ## args)
|
||||
|
||||
|
||||
#endif // __AP_PROGMEM_DESKTOP_BUILD_H__
|
||||
|
Loading…
Reference in New Issue
Block a user