eive-obsw/gomspace/libutil/include/gs/util/pgm.h

163 lines
4.9 KiB
C

#ifndef GS_UTIL_PROGMEM_H
#define GS_UTIL_PROGMEM_H
/* Copyright (c) 2013-2017 GomSpace A/S. All rights reserved. */
/**
@file
Macros for handling special memory access.
On most targets/processors, constant data/strings are located in the program space and can be read in the same way as data in the data space.
However, on a few targets (e.g. avr/avr8), data/strings must be marked in a special way in order to go into the program space, see #GS_PGM_STR()
Using following macros, will make it easier to make cross-platform code and avoid \#if/\#endif.
These macros should only be used where the code also needs to run on avr/avr8.
@note Including this header on avr/avr8 will REDEFINE printf!.
http://www.atmel.com/webdoc/avrlibcreferencemanual/group__avr__pgmspace.html.
http://www.nongnu.org/avr-libc/user-manual/pgmspace.html.
*/
#include <gs/util/stdio.h>
#if defined(__AVR__)
#include <avr/pgmspace.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__AVR__) || (__DOXYGEN__)
/**
Special program/data memory handling.
*/
#define GS_PGM 1
/**
Place object in program space (must be const).
Example: static const uint8_t data8[] GS_PGM_OBJECT = {1, 255};
*/
#define GS_PGM_OBJECT PROGMEM
/**
Place const string in program space.
By default the string goes into data, uses thereby uses up space.
Once the string is placed in program space, xx_P functions must be used to access them - see #GS_PGM_PRINTF.
@note printf is re-defined by including this header
*/
#define GS_PGM_STR(str) PSTR(str)
/**
Read uint8 from program space (near).
*/
#define GS_PGM_UINT8(value) pgm_read_byte(&(value))
/**
Read uint8 from program space using a pointer (near).
*/
#define GS_PGM_UINT8_BY_PTR(value) pgm_read_byte(value)
/**
Read word from program space (near).
*/
#define GS_PGM_UINT16(value) pgm_read_word(&(value))
/**
Read word from program space using a pointer (near).
*/
#define GS_PGM_UINT16_BY_PTR(value) pgm_read_word(value)
/**
Read dword from program space (near).
*/
#define GS_PGM_UINT32(value) pgm_read_dword(&(value))
/**
Read word from program space using a pointer (near).
*/
#define GS_PGM_UINT32_BY_PTR(value) pgm_read_dword(value)
/**
Memcpy from program space (near).
@param[in] dst destination.
@param[in] src source - program space.
@param[in] n number of bytes to copy
*/
#define GS_PGM_MEMCPY(dst, src, n) memcpy_P(dst, src, n)
/**
String compare (program space)
@param[in] s1 string 1
@param[in] s2 string 2 - program space.
@param[in] n max number of bytes to compare
*/
#define GS_PGM_STRNCMP(s1,s2,n) strncmp_P(s1, s2, n)
/**
String compare (program space)
@param[in] s1 string 1
@param[in] s2 string 2 - program space.
@param[in] n max number of bytes to compare
*/
#define GS_PGM_STRNCASECMP(s1,s2,n) strncasecmp_P(s1, s2, n)
/**
String formatting character for referencing a string placed in programs space.
*/
#define GS_PGM_FMT_STR "S"
/**
printf (format string in program space).
Example: print \a param->name (from prgram space) and \a value from data space, using a format string in program space.
GS_PGM_PRINTF(GS_PGM_STR("%"GS_PGM_FMT_STR", %d"), param->name, value)
*/
#define GS_PGM_PRINTF(format, ...) printf_P(format, ##__VA_ARGS__)
/**
vprintf (format string in program space).
*/
#define GS_PGM_VPRINTF(format, va) vfprintf_P(stdout, format, va)
/**
snprintf (format string in program space).
*/
#define GS_PGM_SNPRINTF(buf, bufsize, format, ...) snprintf_P(buf, bufsize, format, ##__VA_ARGS__)
/**
vsnprintf (format string in program space).
*/
#define GS_PGM_VSNPRINTF(buf, bufsize, format, va) vsnprintf_P(buf, bufsize, format, va)
/**
redefines printf (puts format string in program space)
*/
#undef printf
#define printf(format, ...) GS_PGM_PRINTF(GS_PGM_STR(format), ## __VA_ARGS__)
#else
#undef GS_PGM
#define GS_PGM_OBJECT
#define GS_PGM_STR(str) (str)
#define GS_PGM_UINT8(value) (value)
#define GS_PGM_UINT8_BY_PTR(value) (*(value))
#define GS_PGM_UINT16(value) (value)
#define GS_PGM_UINT16_BY_PTR(value) (*(value))
#define GS_PGM_UINT32(value) (value)
#define GS_PGM_UINT32_BY_PTR(value) (*(value))
#define GS_PGM_MEMCPY(dst, src, size) memcpy(dst, src, size)
#define GS_PGM_STRNCMP(s1,pgmstr,size) strncmp(s1, pgmstr, size)
#define GS_PGM_STRNCASECMP(s1,pgmstr,size) strncasecmp(s1, pgmstr, size)
#define GS_PGM_FMT_STR "s"
#define GS_PGM_PRINTF(format, ...) printf(format, ## __VA_ARGS__)
#define GS_PGM_VPRINTF(format, va) vprintf(format, va)
#define GS_PGM_SNPRINTF(buf, bufsize, format, ...) snprintf(buf, bufsize, format, ##__VA_ARGS__)
#define GS_PGM_VSNPRINTF(buf, bufsize, format, va) vsnprintf(buf, bufsize, format, va)
#endif
#ifdef __cplusplus
}
#endif
#endif