I was astonished to find differences between macro definition of termios.h
On RHEL or Centos 7 I have the (also confusing octal) values
#define PARENB 0000400
#define PARODD 0001000
On other sources we see
#define PARENB 0x00001000 /* parity enable */
#define PARODD 0x00002000 /* odd parity, else even */
For PARENB 0x1000 = 4096 = 10000octal which is not 0000400
I thought it would be the same on all platforms/distributions (apart maybe for 32 bits/64bits distinction).
Why such difference ? Can we by mistake use one instead of the other ? is there an historical reason ?
Related
The problem:
I'm writing a general C library for an LCD in a microcontroller project.
up to 8 LCDs with various sizes(e.g. 128*96 or 64*48) in various addresses may be added (e.g. LCD3 and LCD7). but only one of them is actively coded at a time. so I thought for a mechanism to do so.
in the code, there is a definition for CLCD_ROWS and CLCD_COLS which correspond to the Active display size.
#define CLCD_ROWS // Active LCD rows
#define CLCD_COLS // Active LCD columns
and there's definitions for the various LCDs. for example, if we have LCD3 and LCD7 connected, we define their sizes with :
#define CLCD_ROWS3 96
#define CLCD_COLS3 64
#define CLCD_ROWS7 128
#define CLCD_COLS7 32
The question:
I've written a [wrong] macro to redefine the values of CLCD_ROWS and CLCD_COLS :
#define cLcd_setActiveI2CcLcd(X) \
CLCD_ROWS = CLCD_ROWS##X \
CLCD_COLS = CLCD_COLS##X
and in my main code I call the macro:
cLcd_setActiveI2CcLcd(7);
which gives me an error of "missing ;".
it is easy to implement it with variables. but since these values are hardcoded , I thought they are "preprocessable" since need every bit of RAM in a low end MCU.
Is my approach about preprocessing this values, correct ?
What is the right way to write a macro for that purpose ?
I'm using a C99 compiler.
First things first, your method of using function-type macro is wrong. Even if you fix the error you have, the macro will not do CLCD_ROWS equal to CLCD_ROWS7, but to CLCD_ROWSX (that is how macros work, it concatenates the thing you give, not its value). Instead if you want to use macros for reducing RAM usage you can change your code to:
1st Solution
#define ROW_COLS 7 // change this if you use different display
#if ROW_COLS == 7
#define CLCD_ROWS 128
#define CLCD_COLS 32
#elif ROW_COLS == 3
#define CLCD_ROWS 96
#define CLCD_COLS 64
#endif
2nd Solution
If you want dynamically change the size of your display in the runtime, you can do it like this:
static int display_cnt;
#define CLCD_ROWS ((display_cnt == 3) ? 96 : 128)
#define CLCD_COLS ((display_cnt == 3) ? 64 : 32)
So when you change the value of display_cnt variable, the macro will automatically change its value.
I'm on GCC112, which is a little-endian Power8 machine running Linux. Power8 has in-core crypto providing AES, SHA and a few other useful features. I'm trying to determine the availability of the features at runtime using getauxval. The use case is distros building for a "minimum" capable machine, and we need to swap-in a faster function at runtime.
The dump of hwcaps.h is shown below, but it lacks specific bits for Power8, AES, SHA and others. However, I believe Power8 is ISA 2.07, and ISA 2.07 has the bit PPC_FEATURE2_ARCH_2_07.
The thing I am not clear on is, is Power8 in-core crypto optional like ARM's crypto under ARMv8. I can't find a document that clearly states the requirement, and I don't have a membership to OpenPower to access ISA documents. (Another possibility is, it is stated but I missed it in the docs).
Is it possible to use getauxval to query the runtime environment for the features? If not, then how do we determine feature availability at runtime? Is CPU probing the only alternative available?
Maybe more generally, how do we determine Power6, Power7 and Power8 runtime environments?
auxv.h is mostly empty. The header file includes hwcaps.h.
$ cat /usr/include/bits/hwcap.h
...
/* The bit numbers must match those in the kernel's asm/cputable.h. */
/* Feature definitions in AT_HWCAP. */
#define PPC_FEATURE_32 0x80000000 /* 32-bit mode. */
#define PPC_FEATURE_64 0x40000000 /* 64-bit mode. */
#define PPC_FEATURE_601_INSTR 0x20000000 /* 601 chip, Old POWER ISA. */
#define PPC_FEATURE_HAS_ALTIVEC 0x10000000 /* SIMD/Vector Unit. */
#define PPC_FEATURE_HAS_FPU 0x08000000 /* Floating Point Unit. */
#define PPC_FEATURE_HAS_MMU 0x04000000 /* Memory Management Unit. */
#define PPC_FEATURE_HAS_4xxMAC 0x02000000 /* 4xx Multiply Accumulator. */
#define PPC_FEATURE_UNIFIED_CACHE 0x01000000 /* Unified I/D cache. */
#define PPC_FEATURE_HAS_SPE 0x00800000 /* Signal Processing ext. */
#define PPC_FEATURE_HAS_EFP_SINGLE 0x00400000 /* SPE Float. */
#define PPC_FEATURE_HAS_EFP_DOUBLE 0x00200000 /* SPE Double. */
#define PPC_FEATURE_NO_TB 0x00100000 /* 601/403gx have no timebase */
#define PPC_FEATURE_POWER4 0x00080000 /* POWER4 ISA 2.00 */
#define PPC_FEATURE_POWER5 0x00040000 /* POWER5 ISA 2.02 */
#define PPC_FEATURE_POWER5_PLUS 0x00020000 /* POWER5+ ISA 2.03 */
#define PPC_FEATURE_CELL_BE 0x00010000 /* CELL Broadband Engine */
#define PPC_FEATURE_BOOKE 0x00008000 /* ISA Category Embedded */
#define PPC_FEATURE_SMT 0x00004000 /* Simultaneous
Multi-Threading */
#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
#define PPC_FEATURE_ARCH_2_05 0x00001000 /* ISA 2.05 */
#define PPC_FEATURE_PA6T 0x00000800 /* PA Semi 6T Core */
#define PPC_FEATURE_HAS_DFP 0x00000400 /* Decimal FP Unit */
#define PPC_FEATURE_POWER6_EXT 0x00000200 /* P6 + mffgpr/mftgpr */
#define PPC_FEATURE_ARCH_2_06 0x00000100 /* ISA 2.06 */
#define PPC_FEATURE_HAS_VSX 0x00000080 /* P7 Vector Extension. */
#define PPC_FEATURE_PSERIES_PERFMON_COMPAT 0x00000040
#define PPC_FEATURE_TRUE_LE 0x00000002
#define PPC_FEATURE_PPC_LE 0x00000001
/* Feature definitions in AT_HWCAP2. */
#define PPC_FEATURE2_ARCH_2_07 0x80000000 /* ISA 2.07 */
#define PPC_FEATURE2_HAS_HTM 0x40000000 /* Hardware Transactional
Memory */
#define PPC_FEATURE2_HAS_DSCR 0x20000000 /* Data Stream Control
Register */
#define PPC_FEATURE2_HAS_EBB 0x10000000 /* Event Base Branching */
#define PPC_FEATURE2_HAS_ISEL 0x08000000 /* Integer Select */
#define PPC_FEATURE2_HAS_TAR 0x04000000 /* Target Address Register */
I'd say that getauxval() would be the best way to do this; the HWCAP & HWCAP2 values are exactly for determining hardware features. Missing from your list is the PPC_FEATURE2_VEC_CRYPTO, which indicates the presence of the vector crypto instructions, which sounds like the one you need.
As a side note: you probably don't want to detect processor implementations, but processor features. Specifically, check for the individual feature, rather than trying to check for a process that provides that feature. (eg., detect VEC_CRYPTO directly, rather than trying to check for POWER8, and assume that that implies crypto functionality).
As a bit of detail, Linux's cputable entries specify the HWCAP/HWCAP2 values. Using POWER8 as an example:
#define COMMON_USER2_POWER8 (PPC_FEATURE2_ARCH_2_07 | \
PPC_FEATURE2_HTM_COMP | \
PPC_FEATURE2_HTM_NOSC_COMP | \
PPC_FEATURE2_DSCR | \
PPC_FEATURE2_ISEL | PPC_FEATURE2_TAR | \
PPC_FEATURE2_VEC_CRYPTO)
That's from arch/powerpc/include/asm/cputable.h in the kernel (which also provides the actual hwcap bits that can be set in the aux vector).
Finally, I'm fairly sure you don't need to be an OpenPOWER foundation member to download the ISA (latest is 3.0B) - you just need an account on the website.
I'm trying to write a portable program that deals with ustar archives. For device files, these archives store the major and minor device numbers. However, the struct stat as laid out in POSIX only contains a single st_rdev member of type dev_t described with “Device ID (if file is character or block special).”
How can I convert between a pair of major and minor device numbers and a single st_rdev member as returned by stat() in a portable manner?
While all POSIX programming interfaces use the device number (of type dev_t) as is, FUZxxl pointed out in a comment to this answer that the common UStar file format -- most common tar archive format -- does split the device number into major and minor. (They are typically encoded as seven octal digits each, so for compatibility reasons one should limit to 21-bit unsigned major and 21-bit unsigned minor. This also means that mapping the device number to just the major or just the minor is not a reliable approach.)
The following include file expanding on Jonathon Reinhart's answer, after digging on the web for the various systems man pages and documentation (for makedev(), major(), and minor()), plus comments to this question.
#if defined(custom_makedev) && defined(custom_major) && defined(custom_minor)
/* Already defined */
#else
#undef custom_makedev
#undef custom_major
#undef custom_minor
#if defined(__linux__) || defined(__GLIBC__)
/* Linux, Android, and other systems using GNU C library */
#ifndef _BSD_SOURCE
#define _BSD_SOURCE 1
#endif
#include <sys/types.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(_WIN32)
/* 32- and 64-bit Windows. VERIFY: These are just a guess! */
#define custom_makedev(dmajor, dminor) ((((unsigned int)dmajor << 8) & 0xFF00U) | ((unsigned int)dminor & 0xFFFF00FFU))
#define custom_major(devnum) (((unsigned int)devnum & 0xFF00U) >> 8)
#define custom_minor(devnum) ((unsigned int)devnum & 0xFFFF00FFU)
#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
/* FreeBSD, OpenBSD, NetBSD, and DragonFlyBSD */
#include <sys/types.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(__APPLE__) && defined(__MACH__)
/* Mac OS X */
#include <sys/types.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(_AIX) || defined (__osf__)
/* AIX, OSF/1, Tru64 Unix */
#include <sys/types.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(hpux)
/* HP-UX */
#include <sys/sysmacros.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#elif defined(sun)
/* Solaris */
#include <sys/types.h>
#include <sys/mkdev.h>
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#else
/* Unknown OS. Try a the BSD approach. */
#ifndef _BSD_SOURCE
#define _BSD_SOURCE 1
#endif
#include <sys/types.h>
#if defined(makedev) && defined(major) && defined(minor)
#define custom_makedev(dmajor, dminor) makedev(dmajor, dminor)
#define custom_major(devnum) major(devnum)
#define custom_minor(devnum) minor(devnum)
#endif
#endif
#if !defined(custom_makedev) || !defined(custom_major) || !defined(custom_minor)
#error Unknown OS: please add definitions for custom_makedev(), custom_major(), and custom_minor(), for device number major/minor handling.
#endif
#endif
One could glean additional definitions from existing UStar-format -capable archivers. Compatibility with existing implementations on each OS/architecture is, in my opinion, the most important thing here.
The above should cover all systems using GNU C library, Linux (including Android), FreeBSD, OpenBSD, NetBSD, DragonFlyBSD, Mac OS X, AIX, Tru64, HP-UX, and Solaris, plus any that define the macros when <sys/types.h> is included. Of the Windows part, I'm not sure.
As I understand it, Windows uses device 0 for all normal files, and a HANDLE (a void pointer type) for devices. I am not at all sure whether the above logic is sane on Windows, but many older systems put the 8 least significant bits of the device number into minor, and the next 8 bits into major, and the convention seems to be that any leftover bits would be put (without shifting) into minor, too. Examining existing UStar-format tar archives with references to devices would be useful, but I personally do not use Windows at all.
If a system is not detected, and the system does not use the BSD-style inclusion for defining the macros, the above will error out stopping the compilation. (I would personally add compile-time machinery that could help finding the correct header definitions, using e.g. find, xargs, and grep, in case that happens, with a suggestion to send the addition upstream, too. touch empty.h ; cpp -dM empty.h ; rm -f empty.h should show all predefined macros, to help with identifying the OS and/or C library.)
Originally, POSIX stated that dev_t must be an arithmetic type (thus, theoretically, it might have been some variant of float or double on some systems), but IEEE Std 1003.1, 2013 Edition says it must be an integer type. I would wager that means no known POSIX-y system ever used a floating-point dev_t type. It would seem that Windows uses a void pointer, or HANDLE type, but Windows is not POSIX-compliant anyway.
Use the major() and minor() macros after defining BSD_SOURCE.
The makedev(), major(), and minor() functions are not specified in
POSIX.1, but are present on many other systems.
http://man7.org/linux/man-pages/man3/major.3.html
I have a program based on an antique version of ls for Minix, but much mangled modified by me since then. It has the following code to detect the major and minor macros — and some comments about (now) antique systems where it has worked in the past. It assumes a sufficiently recent version of GCC is available to support #pragma GCC diagnostic ignored etc. You have to be trying pretty hard (e.g. clang -Weverything) to get the -Wunused-macros option in effect unless you include it explicitly.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
/* Defines to ensure major and minor macros are available */
#define _DARWIN_C_SOURCE /* In <sys/types.h> on MacOS X */
#define _BSD_SOURCE /* In <sys/sysmacros.h> via <sys/types.h> on Linux (Ubuntu 12.0.4) */
#define __EXTENSIONS__ /* Maybe beneficial on Solaris */
#pragma GCC diagnostic pop
/* From Solaris 2.6 sys/sysmacros.h
**
** WARNING: The device number macros defined here should not be used by
** device drivers or user software. [...] Application software should make
** use of the library routines available in makedev(3). [...] Macro
** routines bmajor(), major(), minor(), emajor(), eminor(), and makedev()
** will be removed or their definitions changed at the next major release
** following SVR4.
**
** #define O_BITSMAJOR 7 -- # of SVR3 major device bits
** #define O_BITSMINOR 8 -- # of SVR3 minor device bits
** #define O_MAXMAJ 0x7f -- SVR3 max major value
** #define O_MAXMIN 0xff -- SVR3 max major value
**
** #define L_BITSMAJOR 14 -- # of SVR4 major device bits
** #define L_BITSMINOR 18 -- # of SVR4 minor device bits
** #define L_MAXMAJ 0x3fff -- SVR4 max major value
** #define L_MAXMIN 0x3ffff -- MAX minor for 3b2 software drivers.
** -- For 3b2 hardware devices the minor is restricted to 256 (0-255)
*/
/* AC_HEADER_MAJOR:
** - defines MAJOR_IN_MKDEV if found in sys/mkdev.h
** - defines MAJOR_IN_SYSMACROS if found in sys/macros.h
** - otherwise, hope they are in sys/types.h
*/
#if defined MAJOR_IN_MKDEV
#include <sys/mkdev.h>
#elif defined MAJOR_IN_SYSMACROS
#include <sys/sysmacros.h>
#elif defined(MAJOR_MINOR_MACROS_IN_SYS_TYPES_H)
/* MacOS X 10.2 - for example */
/* MacOS X 10.5 requires -D_DARWIN_C_SOURCE or -U_POSIX_C_SOURCE - see above */
#elif defined(USE_CLASSIC_MAJOR_MINOR_MACROS)
#define major(x) ((x>>8) & 0x7F)
#define minor(x) (x & 0xFF)
#else
/* Hope the macros are in <sys/types.h> or otherwise magically visible */
#endif
#define MAJOR(x) ((long)major(x))
#define MINOR(x) ((long)minor(x))
You will justifiably not be all that keen on the 'hope the macros are … magically visible' part of the code.
The reference to AC_HEADER_MAJOR is to the macro in the autoconf that deduces this information. It would be relevant if you have a config.h file generated by autoconf.
POSIX
Note that the POSIX pax command defines the ustar format and specifies that it includes devmajor and devminor in the information, but adds:
… Represent character special files and block special files respectively. In this case the devmajor and devminor fields shall contain information defining the device, the format of which is unspecified by this volume of POSIX.1-2008. Implementations may map the device specifications to their own local specification or may ignore the entry.
This means that there isn't a fully portable way to represent the numbers. This is not wholly unreasonable (but it is a nuisance); the meanings of the major and minor device numbers varies across platforms and is unspecified too. Any attempt to create block or character devices via ustar format will only work reasonably reliably if the source and target machines are running the same (version of the same) operating system — though usually they're portable across versions of the same operating system.
I ran into some issues configuring my stm32f429-DISCO board for a UART transmission on UART5.
I used the example project provided by st. To be exact, the UART/UART_TwoBoards_ComDMA in version 1.7.0.
In this example the USART1 is used to circle one data package around.
When the DISCO-board is programmed with the original code, I can see the USART1 output message on my oscilloscope.
On the other hand, when I try the same thing with the UART5, because the pins for USART1 will be blocked in my final configuration it won't work.
I narrowed the problem down to the initialization process.
HAL_UART_MspInit(huart);
This function is not setting the TC and RXNE bit in UART1->SR, and therefore the UART5 is not configured.
I know for UART1 you need to enable the clock, because it can be a synchronous transmission.
__HAL_RCC_USART1_CLK_ENABLE();
I can't seem to find a similar function for UART5. Has somebody an idea or a hint for me?
In case a bigger problem is underlying this issue, here are the changed settings for the UART5 configuration of the example.
/* Definition for USARTx clock resources */
#define USARTx UART5
//#define USARTx_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE();
#define DMAx_CLK_ENABLE() __HAL_RCC_DMA1_CLK_ENABLE()
#define USARTx_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define USARTx_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
//#define USARTx_FORCE_RESET() __HAL_RCC_USART1_FORCE_RESET()
//#define USARTx_RELEASE_RESET() __HAL_RCC_USART1_RELEASE_RESET()
/* Definition for USARTx Pins */
#define USARTx_TX_PIN GPIO_PIN_12
#define USARTx_TX_GPIO_PORT GPIOC
#define USARTx_TX_AF GPIO_AF8_UART5
#define USARTx_RX_PIN GPIO_PIN_2
#define USARTx_RX_GPIO_PORT GPIOD
#define USARTx_RX_AF GPIO_AF8_UART5
/* Definition for USARTx's DMA */
#define USARTx_TX_DMA_CHANNEL DMA_CHANNEL_4
#define USARTx_TX_DMA_STREAM DMA1_Stream7
#define USARTx_RX_DMA_CHANNEL DMA_CHANNEL_4
#define USARTx_RX_DMA_STREAM DMA1_Stream0
/* Definition for USARTx's NVIC */
#define USARTx_DMA_TX_IRQn DMA1_Stream7_IRQn
#define USARTx_DMA_RX_IRQn DMA1_Stream0_IRQn
#define USARTx_DMA_TX_IRQHandler DMA1_Stream7_IRQHandler
#define USARTx_DMA_RX_IRQHandler DMA1_Stream0_IRQHandler
#define USARTx_IRQn UART5_IRQn
#define USARTx_IRQHandler UART5_IRQHandler
I'm happy for any suggestion and help that guides me in the right direction.
Thank you for your time,
eimer
UART5 has no S, so the function to enable the clock is called
__HAL_RCC_UART5_CLK_ENABLE();, like e.g. there: Receiving data from 2 UARTs, STM32F4-Discovery, HAL drivers
I have this definition
#define LED_CLOCK_PIN (DDRD, PORTD, PD6)
I want to write two more definitions, in order to get PORTD and PD6 values, something like this
#define GET_PORT(_PORT_) /*some magic goes here*/
#define GET_PIN(_PIN_) /*some magic goes here*/
uint8_t port = GET_PORT(LED_CLOCK_PIN);
uint8_t pin = GET_PIN(LED_CLOCK_PIN);
Is it possible?
Do you mean something like:
#define LED_CLOCK_PIN (DDRD, PORTD, PD6)
#define SND(A, B, C) B
#define GET_PORT(X) SND X
uint8_t port = GET_PORT(LED_CLOCK_PIN);
gcc -E processes it to uint8_t port = PORTD;. I'm not sure if this is fully portable and guaranteed by standard.
If you were permitted to change you first define to:
#define LED_CLOCK_PIN DDRD, PORTD, PD6
then with C99 you can do (not tested):
#define GET_PORT(x) (((int[]){x})[1])
Is there a reason you would want to parameterize the port instead of accessing it directly by name? That is, instead of
#define GET_PORT
Would it make more sense to have something like
#define GET_PORT_D (port.D)
#define LED_CLOCK_PIN 0x10 //Bit 5 of the port.D register, for example
#define GET_LED_CLOCK_PIN ( (port.D & LED_CLOCK_PIN) >> 4)
This way, there is no ambiguity to what you're doing with the port, so it improves readability. Second, the likelihood that you are changing what LED_CLOCK_PIN actually means (since it accesses hardware) is probably pretty low, so again why not make the code unambiguous.