I am trying to port some patches to linux-4.4 kernel and I am facing following error ./arch/arm64/include/asm/processor.h:159:40: error: implicit declaration of function ‘task_stack_page’ [-Werror=implicit-function-declaration]. Could you give me any pointer on this as to where the issue comes from?
In file included from ./arch/arm64/include/asm/debug-monitors.h:25:0,
from ./arch/arm64/include/asm/bug.h:21,
from include/linux/bug.h:4,
from include/linux/thread_info.h:11,
from include/asm-generic/preempt.h:4,
from arch/arm64/include/generated/asm/preempt.h:1,
from include/linux/preempt.h:60,
from include/linux/spinlock.h:50,
from include/linux/seqlock.h:35,
from include/linux/time.h:5,
from include/uapi/linux/timex.h:56,
from include/linux/timex.h:56,
from include/linux/sched.h:19,
from arch/arm64/kernel/asm-offsets.c:21:
./arch/arm64/include/asm/compat.h: In function ‘arch_compat_alloc_user_space’:
./arch/arm64/include/asm/processor.h:159:40: error: implicit declaration of function ‘task_stack_page’ [-Werror=implicit-function-declaration]
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
^
./arch/arm64/include/asm/ptrace.h:137:5: note: in definition of macro ‘compat_user_mode’
(((regs)->pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) == \
^
./arch/arm64/include/asm/compat.h:236:38: note: in expansion of macro ‘user_stack_pointer’
#define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
^
./arch/arm64/include/asm/compat.h:236:57: note: in expansion of macro ‘task_pt_regs’
#define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
^
./arch/arm64/include/asm/compat.h:240:24: note: in expansion of macro ‘compat_user_stack_pointer’
return (void __user *)compat_user_stack_pointer() - len;
^
./arch/arm64/include/asm/processor.h:159:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
^
./arch/arm64/include/asm/ptrace.h:137:5: note: in definition of macro ‘compat_user_mode’
(((regs)->pstate & (PSR_MODE32_BIT | PSR_MODE_MASK)) == \
^
./arch/arm64/include/asm/compat.h:236:38: note: in expansion of macro ‘user_stack_pointer’
#define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
^
./arch/arm64/include/asm/compat.h:236:57: note: in expansion of macro ‘task_pt_regs’
#define compat_user_stack_pointer() (user_stack_pointer(task_pt_regs(current)))
^
./arch/arm64/include/asm/compat.h:240:24: note: in expansion of macro ‘compat_user_stack_pointer’
return (void __user *)compat_user_stack_pointer() - len;
^
./arch/arm64/include/asm/processor.h:159:3: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)
^
I have checked the code and made sure that proper header files are included. Is there any gcc debug options to find where the error is coming from? I wonder why there is no tool (I might be wrong) to debug such compilation errors so that we can easily find the cause of errors
Related
I like to know what is HISTOGRAMS in EBPF.
So for example below ebpf program creates histogram
Compiling it cause warning then bunch of errors udp.c:7:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int] BPF_HISTOGRAM(counter, u64);
SO in this tutorial about XDP it tells to create histogram I need to do BPF_HISTOGRAM(counter, u64); so where BPF_HISTOGRAM is #defined. Also what needed to be a type specifier in above waring so if I am doing BPF_HISTOGRAM(counter, u64); so I am assuming it wil be expended to something like u64 counter so if thats the case there here u go I have type specifier than what else is it complaining about in clang command root#fawad:/home/fawad/bpf# clang -I /usr/include/x86_64-linux-gnu/ -O2 -Wall -target bpf -c udp.c -o udp.o
How how to get rid of these errors and a warning if I try to compile with above command
Errors like : IPPROTO_UDP not found
use of undeclared u64
use of undeclared counter,(if I am assuming right in above question text why this warning and error about counter and histogram)
So I have this simple code
#define KBUILD_MODNAME "udp_counter"
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/udp.h>
BPF_HISTOGRAM(counter, u64);
int udp_counter(struct xdp_md *ctx)
{
void *data = (void *)(long)ctx->data;
void *data_end = (void *)(long)ctx->data_end;
struct ethhdr *eth = data;
if ((void *)eth + sizeof(*eth) <= data_end)
{
struct iphdr *ip = data + sizeof(*eth);
if ((void *)ip + sizeof(*ip) <= data_end)
{
if (ip->protocol == IPPROTO_UDP)
{
struct udphdr *udp = (void *)ip + sizeof(*ip);
if ((void *)udp + sizeof(*udp) <= data_end)
{
u64 value = htons(udp->dest);
counter.increment(value);
}
}
}
}
return XDP_PASS;
}
Throws error
udp.c:7:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
BPF_HISTOGRAM(counter, u64);
^
udp.c:7:15: error: a parameter list without types is only allowed in a function definition
BPF_HISTOGRAM(counter, u64);
^
udp.c:22:33: error: use of undeclared identifier 'IPPROTO_UDP'
if (ip->protocol == IPPROTO_UDP)
^
udp.c:28:21: error: use of undeclared identifier 'u64'
u64 value = htons(udp->dest);
^
udp.c:29:21: error: use of undeclared identifier 'counter'
counter.increment(value);
^
udp.c:29:39: error: use of undeclared identifier 'value'
counter.increment(value);
^
1 warning and 5 errors generated.
root#fawad:/home/fawad/bpf# gedit udp.c
(gedit:7386): Gtk-WARNING **: 13:24:34.572
https://dev.to/satrobit/absolute-beginner-s-guide-to-bcc-xdp-and-ebpf-47oi
I am trying to use some old devices called sensinodes . There are a couple of pieces of software needed for this, contiki, sdcc and the some nano_usb_programmer
I'm working from these instruction and I can't seem to make the nano_usb_programmer on ubuntu 16.04 LTS as this pretty old now and things have moved on.
https://github.com/avian2/contiki
When making the nano element I get the error *Edited
In file included from main.c:17:0:
opts.h:25:2: error: redefinition of typedef ‘mode_t’ with different type
}mode_t;
^
In file included from /usr/include/stdlib.h:314:0,
from main.c:10:
/usr/include/x86_64-linux-gnu/sys/types.h:70:18: note: previous declaration of ‘mode_t’ was here
typedef __mode_t mode_t;
^
main.c: In function ‘main’:
main.c:57:6: warning: implicit declaration of function ‘opts_parse’ [-Wimplicit-function-declaration]
if (opts_parse(argc, argv) < 0)
^
main.c:77:4: warning: implicit declaration of function ‘prog_scan’ [-Wimplicit-function-declaration]
prog_scan();
^
main.c:178:7: warning: implicit declaration of function ‘hexfile_out’ [-Wimplicit-function-declaration]
hexfile_out(line_data, 0x04, 0, ptr, 2);
^
main.c:220:15: warning: implicit declaration of function ‘hexfile_build_tables’ [-Wimplicit-function-declaration]
if((rval = hexfile_build_tables(opts.filename, page_buffer, page_table)) == -1)
^
main.c:231:4: warning: implicit declaration of function ‘hexfile_program’ [-Wimplicit-function-declaration]
hexfile_program(page_buffer, page_table);
^
Makefile:25: recipe for target 'main.o' failed
make: *** [main.o] Error 1
It is pointing to line 25 the following file, my c knowledge just isn't any where near good enough to fix this. Any help would be great.
/*
* opts.h
*
* Created on: Dec 21, 2009
* Author: martti
*/
#ifndef OPTS_H_
#define OPTS_H_
#include "cdi.h"
typedef enum
{
USAGE,
VERSION,
SCAN,
WRITE,
WRITE_FAST,
READ,
WRITE_MAC,
READ_MAC,
LOCK,
ERASE
}mode_t;
typedef struct opts_t
{
int port;
chip_t chip;
mode_t mode;
uint8_t write_mac[8];
ramcode_t code_in_ram;
char *filename;
}opts_t;
extern opts_t opts;
#endif /* OPTS_H_ */
I am having issues while trying to pass a macro constant as an argument to a macro function.
Consider the following code -
#define ERROR 10
#define MAIN "Main:"
#define LOG(lvl,mod,fmt,...) \
char msg[256] = {0}; \
snprintf(msg, 256, "%s: %d: "fmt,mod,lvl,##__VA_ARGS__)
int main()
{ ....
LOG(ERROR, MAIN, "This is a log statement.\n"); // Doesn't compile
LOG(10, "Main:", "This is a log statement.\n"); // Compiles
....
}
The second log statement compiles but the first log statement generate the following compilation error -
error: expected `)' before ‘;’ token
error: expected primary-expression before ‘,’ token
error: expected `;' before ‘)’ token
Why is this happening? I want to be able to define a set of Logging levels and Modules constants, and use them while invoking the LOG() macro.
One problem with your macro is that it declares a variable at a random spot in a block of code, which C89 does not allow: you were allowed to declare variables only at the top of a block. Even with C99 compiler, the problem does not go away, because now you can introduce multiple declarations of the same name in the same scope, which is prohibited.
You can use the do/while(0) trick to solve this problem:
#define LOG(lvl,mod,fmt,...) do {\
char msg[256] = {0}; \
snprintf(msg, 256, "%s: %d: "fmt,mod,lvl,##__VA_ARGS__) \
} while(0)
There are three two issues I can see:
You will have multiple msg variables within the same scope.
You are missing a comma (as pointed-out by #Ninetainedo).
You do nothing with the formatted string.
I would prefer to declare a global logger() function that accepts a logging-level and use macros to shorten calling it.
I have a problem when I compile my code, it shows errors like :
main.c:33:5: warning: 'PORTE_INT0_vect' appears to be a misspelled signal handler
ISR(PORTE_INT0_vect)
^
In file included from main.c:8:0:
main.h:15:19: error: 'PORTE' undeclared (first use in this function)
#define DATA_PORT PORTE``
^
main.c:35:11: note: in expansion of macro 'DATA_PORT'
inbit = DATA_PORT.IN & DATA_PIN;
^
main.h:15:19: note: each undeclared identifier is reported only once for each function it appears in
#define DATA_PORT PORTE
^
main.c:35:11: note: in expansion of macro 'DATA_PORT'
inbit = DATA_PORT.IN & DATA_PIN;
I write this on terminal :
avr-gcc -g -Os -mmcu=atmega32 -c main.c
Can someone help me please and tell me what is the problem? I am new with aver so I dont understand anything about this errors.
Sorry my english sucks.
so this is the code :
main.h
#ifndef MAIN_H
#define MAIN_H
#include "ax25.h"
#ifdef DEBUG
#include "debug.h"
#endif
#define TRUE 1
#define FALSE 0
#define CLK_PORT PORTA
#define DATA_PORT PORTA
#define CLK_PIN PIN2_bm
#define DATA_PIN PIN0_bm
#define USART_PORT PORTC
#define USART USARTC0
/* States for the communication system */
enum states
{
CW_STATE,
RX_STATE,
TX_STATE,
TX_TEST_STATE
};
/* G3RUH scramble */
#define SCRAMBLE TRUE
/* Addresses, 6 ascii charaters, pad with white spaces */
#define SENDER "CBSTAR"
#define RECEIVER "EARTH"
/* Size of ring buffer for packets */
/* Must be of 2^n size */
#define RB_SIZE 8
#define TX_RB_SIZE 256
#define RX_RB_SIZE 256
#define USART_SIZE 258
/* Data buffer for receiving USART data */
typedef struct USART_BUFFER
{
uint8_t buffer[USART_SIZE];
uint16_t ptr;
}USART_BUFFER_t;
/* Ring buffer for buffering several packets prior to sending
*/
typedef struct TX_RING_BUFFER
{
uint8_t buffer[TX_RB_SIZE * RB_SIZE];
uint8_t count;
uint8_t buffer_fill;
uint8_t *head;
uint8_t *tail;
uint8_t *temp;
} TX_RING_BUFFER_t;
/* Ring buffer for buffering several received frames */
typedef struct RX_RING_BUFFER
{
uint8_t buffer[RX_RB_SIZE * RB_SIZE];
uint8_t count;
uint8_t *head;
uint8_t *tail;
}RX_RING_BUFFER_t;
/* Register for keeping frame configuration settings */
typedef struct FRAME_CONFIGURATION
{
uint8_t delay;
uint8_t preamble;
uint8_t add_head;
uint8_t add_tail;
}FRAME_CONFIGURATION_t;
/* Protocol identifiers for the CubeSTAR protocol */
/* Can be extended to other packet types here, e.g. ACK/NACK
*/
enum commands
{
CMD = 0x10, // command frames
HK = 0x20, // housekeeping frames
TEST = 0x30, // test frames
PAYLOAD = 0x40, //payload data frames
RAW = 0x50 // raw ascii frames
};
/* Function declarations */
void initialize();
void add_byte(RX_BUFFER_t *buf);
void handle_rx_buffer(RX_RING_BUFFER_t *rx_rb);
void handle_data(RX_BUFFER_t *buf, RX_FRAME_t *frame);
void init_clk();
void init_usart();
void config_frame(uint8_t preamble, uint8_t head, uint8_t tail, uint8_t delay);
void create_frame(enum commands id, uint8_t *data, uint8_t size);
void send_frame();
void resend_frames();
void bang_out(TX_BUFFER_t *buf);
void byte_out(uint8_t byte);
void bit_out(uint8_t bit);
void tx_ring_buffer_init(TX_RING_BUFFER_t *tx_rb);
uint8_t tx_ring_buffer_push(TX_RING_BUFFER_t *tx_rb, const uint8_t *tx_data);
uint8_t tx_ring_buffer_pop(TX_RING_BUFFER_t *tx_rb, uint8_t *tx_data);
void tx_ring_buffer_reset(TX_RING_BUFFER_t *tx_rb);
void tx_ring_buffer_set(TX_RING_BUFFER_t *tx_rb);
void rx_ring_buffer_init(RX_RING_BUFFER_t *rx_rb);
uint8_t rx_ring_buffer_push(RX_RING_BUFFER_t *rx_rb, uint8_t *rx_data);
uint8_t rx_ring_buffer_pop(RX_RING_BUFFER_t *rx_rb, uint8_t *rx_data);
void usart_buffer_clr();
void from_usart();
void test_frame(uint8_t preamble, uint8_t head, uint8_t tail,
uint8_t delay, uint8_t data, uint8_t frames_lo, uint8_t
frames_hi);
void test_frame_command(enum commands id, uint8_t data_length);
void test_1(uint8_t data, uint8_t frames_lo, uint8_t frames_hi);
void set_state(uint8_t next_state);
#endif
it is not my personal code, Im just using it for a project. this is all the errors I get.
In file included from main.c:3:0:
main.c: In function 'PORTA_INT0_vect':
main.c:33:5: warning: 'PORTA_INT0_vect' appears to be a misspelled signal handler
ISR(PORTA_INT0_vect)
^
In file included from main.c:8:0:
main.h:15:19: error: 'PORTE' undeclared (first use in this function)
#define DATA_PORT PORTE
^
main.c:35:11: note: in expansion of macro 'DATA_PORT'
inbit = DATA_PORT.IN & DATA_PIN;
^
main.h:15:19: note: each undeclared identifier is reported only once for each function it appears in
#define DATA_PORT PORTE
^
main.c:35:11: note: in expansion of macro 'DATA_PORT'
inbit = DATA_PORT.IN & DATA_PIN;
^
main.h:17:18: error: 'PIN0_bm' undeclared (first use in this function)
#define DATA_PIN PIN0_bm
^
main.c:35:26: note: in expansion of macro 'DATA_PIN'
inbit = DATA_PORT.IN & DATA_PIN;
^
In file included from main.c:3:0:
main.c: In function 'USARTC0_RXC_vect':
main.c:39:5: warning: 'USARTC0_RXC_vect' appears to be a misspelled signal handler
ISR(USARTC0_RXC_vect)
^
In file included from main.c:8:0:
main.h:19:15: error: 'USARTC0' undeclared (first use in this function)
#define USART USARTC0
^
main.c:41:16: note: in expansion of macro 'USART'
usart_data = USART.DATA;
^
main.c: In function 'init_usart':
main.c:170:13: error: request for member 'DIRCLR' in something not a structure or union
USART_PORT.DIRCLR = PIN2_bm;
^
main.c:170:23: error: 'PIN2_bm' undeclared (first use in this function)
USART_PORT.DIRCLR = PIN2_bm;
^
main.c:171:13: error: request for member 'DIRSET' in something not a structure or union
USART_PORT.DIRSET = PIN3_bm;
^
main.c:171:23: error: 'PIN3_bm' undeclared (first use in this function)
USART_PORT.DIRSET = PIN3_bm;
^
In file included from main.c:8:0:
main.h:19:15: error: 'USARTC0' undeclared (first use in this function)
#define USART USARTC0
^
main.c:174:3: note: in expansion of macro 'USART'
USART.BAUDCTRLA = 51; /* 19200 bps # 6 MHz clock */
^
main.c:177:18: error: 'USART_CHSIZE_8BIT_gc' undeclared (first use in this function)
USART.CTRLC |= USART_CHSIZE_8BIT_gc | USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc;
^
main.c:177:41: error: 'USART_CMODE_ASYNCHRONOUS_gc' undeclared (first use in this function)
USART.CTRLC |= USART_CHSIZE_8BIT_gc | USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc;
^
main.c:177:71: error: 'USART_PMODE_DISABLED_gc' undeclared (first use in this function)
USART.CTRLC |= USART_CHSIZE_8BIT_gc | USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc;
^
main.c:179:18: error: 'USART_RXCINTLVL0_bm' undeclared (first use in this function)
USART.CTRLA |= USART_RXCINTLVL0_bm;
^
main.c:180:3: error: 'PMIC' undeclared (first use in this function)
PMIC.CTRL |= PMIC_LOLVLEN_bm;
^
main.c:180:16: error: 'PMIC_LOLVLEN_bm' undeclared (first use in this function)
PMIC.CTRL |= PMIC_LOLVLEN_bm;
^
main.c:181:18: error: 'USART_RXEN_bm' undeclared (first use in this function)
USART.CTRLB |= USART_RXEN_bm | USART_TXEN_bm;
^
main.c:181:34: error: 'USART_TXEN_bm' undeclared (first use in this function)
USART.CTRLB |= USART_RXEN_bm | USART_TXEN_bm;
^
In file included from main.c:8:0:
main.c: In function 'bit_out':
main.h:14:18: error: 'PORTE' undeclared (first use in this function)
#define CLK_PORT PORTE
^
main.c:355:12: note: in expansion of macro 'CLK_PORT'
while(!(CLK_PORT.IN & CLK_PIN));
^
main.h:16:17: error: 'PIN2_bm' undeclared (first use in this function)
#define CLK_PIN PIN2_bm
^
main.c:355:26: note: in expansion of macro 'CLK_PIN'
while(!(CLK_PORT.IN & CLK_PIN));
^
main.c: In function 'handle_data':
main.h:19:15: error: 'USARTC0' undeclared (first use in this function)
#define USART USARTC0
^
main.c:373:13: note: in expansion of macro 'USART'
while(!((USART.STATUS & USART_DREIF_bm) !=0));
^
main.c:373:28: error: 'USART_DREIF_bm' undeclared (first use in this function)
while(!((USART.STATUS & USART_DREIF_bm) !=0));
^
main.c: In function 'init_clk':
main.c:557:3: error: 'OSC' undeclared (first use in this function)
OSC.XOSCCTRL = OSC_FRQRANGE_2TO9_gc | OSC_XOSCSEL_EXTCLK_gc;
^
main.c:557:18: error: 'OSC_FRQRANGE_2TO9_gc' undeclared (first use in this function)
OSC.XOSCCTRL = OSC_FRQRANGE_2TO9_gc | OSC_XOSCSEL_EXTCLK_gc;
^
main.c:557:41: error: 'OSC_XOSCSEL_EXTCLK_gc' undeclared (first use in this function)
OSC.XOSCCTRL = OSC_FRQRANGE_2TO9_gc | OSC_XOSCSEL_EXTCLK_gc;
^
main.c:558:15: error: 'OSC_XOSCEN_bm' undeclared (first use in this function)
OSC.CTRL |= OSC_XOSCEN_bm;
^
main.c:559:25: error: 'OSC_XOSCRDY_bm' undeclared (first use in this function)
while ( (OSC.STATUS & OSC_XOSCRDY_bm) == 0);
^
main.c:560:3: error: 'CCP' undeclared (first use in this function)
CCP=0xD8;
^
main.c:561:3: error: 'CLK' undeclared (first use in this function)
CLK.CTRL = CLK_SCLKSEL_XOSC_gc;
^
main.c:561:14: error: 'CLK_SCLKSEL_XOSC_gc' undeclared (first use in this function)
CLK.CTRL = CLK_SCLKSEL_XOSC_gc;
^
main.c:562:16: error: 'OSC_RC2MEN_bm' undeclared (first use in this function)
OSC.CTRL &= ~OSC_RC2MEN_bm;
^
In file included from main.c:8:0:
main.c: In function 'initialize':
main.h:14:18: error: 'PORTE' undeclared (first use in this function)
#define CLK_PORT PORTE
^
main.c:573:5: note: in expansion of macro 'CLK_PORT'
CLK_PORT.DIRCLR = CLK_PIN;
^
main.h:16:17: error: 'PIN2_bm' undeclared (first use in this function)
#define CLK_PIN PIN2_bm
^
main.c:573:23: note: in expansion of macro 'CLK_PIN'
CLK_PORT.DIRCLR = CLK_PIN;
^
main.c: In function 'set_state':
main.h:15:19: error: 'PORTE' undeclared (first use in this function)
#define DATA_PORT PORTE
^
main.c:606:7: note: in expansion of macro 'DATA_PORT'
DATA_PORT.DIRCLR = DATA_PIN;
^
main.h:17:18: error: 'PIN0_bm' undeclared (first use in this function)
#define DATA_PIN PIN0_bm
^
main.c:606:26: note: in expansion of macro 'DATA_PIN'
DATA_PORT.DIRCLR = DATA_PIN;
^
main.c:607:26: error: 'PMIC_LOLVLEN_bm' undeclared (first use in this function)
CLK_PORT.INTCTRL = PMIC_LOLVLEN_bm;
^
In file included from main.c:8:0:
main.h:16:17: error: 'PIN2_bm' undeclared (first use in this function)
#define CLK_PIN PIN2_bm
^
main.c:608:27: note: in expansion of macro 'CLK_PIN'
CLK_PORT.INT0MASK = CLK_PIN;
^
main.c:609:27: error: 'PORT_ISC_RISING_gc' undeclared (first use in this function)
CLK_PORT.PIN2CTRL = PORT_ISC_RISING_gc;
^
main.c: In function 'main':
main.c:657:3: error: 'PMIC' undeclared (first use in this function)
PMIC.CTRL = PMIC_LOLVLEN_bm;
^
main.c:657:15: error: 'PMIC_LOLVLEN_bm' undeclared (first use in this function)
PMIC.CTRL = PMIC_LOLVLEN_bm;
and finally this a part of main.c , the code is too long
main.c
#define F_CPU 8000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <inttypes.h>
#include <util/delay.h>
#include <string.h>
#include <stdio.h>
#include "main.h"
/* AX.25 UI frame info and buffers */
TX_FRAME_t tx_frame;
TX_BUFFER_t tx_buffer;
RX_BUFFER_t rx_buffer;
RX_FRAME_t rx_frame;
FRAME_CONFIGURATION_t frame_configuration;
TX_RING_BUFFER_t tx_packet_buffer;
RX_RING_BUFFER_t rx_packet_buffer;
USART_BUFFER_t usartrx_buffer;
/* Global declarations */
volatile uint8_t current_state;
volatile uint8_t inbit;
volatile uint8_t usart_data;
volatile uint8_t frame_counting;
volatile uint8_t frames_to_resend;
/* For testing only */
volatile uint16_t num_test_frames;
volatile uint8_t cont_test_frames;
volatile uint8_t num_test_data;
ISR(PORTE_INT0_vect)
{
inbit = DATA_PORT.IN & DATA_PIN;
add_bit(inbit, &rx_frame, &rx_buffer, SCRAMBLE);
}
The code you are trying to compile was written for an ATxmega128. This is a completely different line of microcontroller from the ATmega32 you're using, and does not have the same peripherals. For instance, the ATmega32 only has GPIO ports PORTA through PORTD, and entirely lacks the programmable multi-level interrupt controller (PMIC).
This code will require significant changes to run on your microcontroller, if it is possible at all. This is probably not a good introductory project for you.
I want to create a C macro that creates a function with a name based
on the line number.
I thought I could do something like (the real function would have statements within the braces):
#define UNIQUE static void Unique_##__LINE__(void) {}
Which I hoped would expand to something like:
static void Unique_23(void) {}
That doesn't work. With token concatenation, the positioning macros
are treated literally, ending up expanding to:
static void Unique___LINE__(void) {}
Is this possible to do?
The problem is that when you have a macro replacement, the preprocessor will only expand the macros recursively if neither the stringizing operator # nor the token-pasting operator ## are applied to it. So, you have to use some extra layers of indirection, you can use the token-pasting operator with a recursively expanded argument:
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define UNIQUE static void TOKENPASTE2(Unique_, __LINE__)(void) {}
Then, __LINE__ gets expanded to the line number during the expansion of UNIQUE (since it's not involved with either # or ##), and then the token pasting happens during the expansion of TOKENPASTE.
It should also be noted that there is also the __COUNTER__ macro, which expands to a new integer each time it is evaluated, in case you need to have multiple instantiations of the UNIQUE macro on the same line. Note: __COUNTER__ is supported by MS Visual Studio, GCC (since V4.3), and Clang, but is not standard C.
How to auto-generate unique variable names with the line number in them by using macros
This is a generic answer, not addressing the narrow specifics of the OP's question, since there are already adequate answers for that.
I learned this primarily from #Jarod42 here, but also from #Adam.Rosenfield here.
#define CONCAT_(prefix, suffix) prefix##suffix
/// Concatenate `prefix, suffix` into `prefixsuffix`
#define CONCAT(prefix, suffix) CONCAT_(prefix, suffix)
/// Make a unique variable name containing the line number at the end of the
/// name. Ex: `uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0;` would
/// produce `uint64_t counter_7 = 0` if the call is on line 7!
#define MAKE_UNIQUE_VARIABLE_NAME(prefix) CONCAT(prefix##_, __LINE__)
Example program:
macro_make_unique_variable_name_with_line_number.c:
#include <stdbool.h> // For `true` (`1`) and `false` (`0`) macros in C
#include <stdint.h> // For `uint8_t`, `int8_t`, etc.
#include <stdio.h> // For `printf()`
#define CONCAT_(prefix, suffix) prefix##suffix
/// Concatenate `prefix, suffix` into `prefixsuffix`
#define CONCAT(prefix, suffix) CONCAT_(prefix, suffix)
/// Make a unique variable name containing the line number at the end of the
/// name. Ex: `uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0;` would
/// produce `uint64_t counter_7 = 0` if the call is on line 7!
#define MAKE_UNIQUE_VARIABLE_NAME(prefix) CONCAT(prefix##_, __LINE__)
// int main(int argc, char *argv[]) // alternative prototype
int main()
{
printf("Autogenerate unique variable names containing the line number "
"in them.\n\n");
uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_54 = 0;
uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_55 = 0;
uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_56 = 0;
// Uncomment this to suppress the errors.
// (void)counter_54;
// (void)counter_55;
// (void)counter_56;
return 0;
}
SAMPLE OUTPUT:
Notice that the intentionally-produced build errors reveal the autogenerated variable names as counter_56, counter_55, and counter_54, as shown here!:
macro_make_unique_variable_name_with_line_number.c:56:40: error: unused variable ‘counter_56’ [-Werror=unused-variable]
macro_make_unique_variable_name_with_line_number.c:55:40: error: unused variable ‘counter_55’ [-Werror=unused-variable]
macro_make_unique_variable_name_with_line_number.c:54:40: error: unused variable ‘counter_54’ [-Werror=unused-variable]
Full output:
eRCaGuy_hello_world/c$ gcc -Wall -Wextra -Werror -O3 -std=gnu17 macro_make_unique_variable_name_with_line_number.c -o bin/a -lm && bin/a
macro_make_unique_variable_name_with_line_number.c: In function ‘main’:
macro_make_unique_variable_name_with_line_number.c:56:40: error: unused variable ‘counter_56’ [-Werror=unused-variable]
56 | uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_56 = 0;
| ^~~~~~~
macro_make_unique_variable_name_with_line_number.c:39:33: note: in definition of macro ‘CONCAT_’
39 | #define CONCAT_(prefix, suffix) prefix##suffix
| ^~~~~~
macro_make_unique_variable_name_with_line_number.c:45:43: note: in expansion of macro ‘CONCAT’
45 | #define MAKE_UNIQUE_VARIABLE_NAME(prefix) CONCAT(prefix##_, __LINE__)
| ^~~~~~
macro_make_unique_variable_name_with_line_number.c:56:14: note: in expansion of macro ‘MAKE_UNIQUE_VARIABLE_NAME’
56 | uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_56 = 0;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
macro_make_unique_variable_name_with_line_number.c:55:40: error: unused variable ‘counter_55’ [-Werror=unused-variable]
55 | uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_55 = 0;
| ^~~~~~~
macro_make_unique_variable_name_with_line_number.c:39:33: note: in definition of macro ‘CONCAT_’
39 | #define CONCAT_(prefix, suffix) prefix##suffix
| ^~~~~~
macro_make_unique_variable_name_with_line_number.c:45:43: note: in expansion of macro ‘CONCAT’
45 | #define MAKE_UNIQUE_VARIABLE_NAME(prefix) CONCAT(prefix##_, __LINE__)
| ^~~~~~
macro_make_unique_variable_name_with_line_number.c:55:14: note: in expansion of macro ‘MAKE_UNIQUE_VARIABLE_NAME’
55 | uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_55 = 0;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
macro_make_unique_variable_name_with_line_number.c:54:40: error: unused variable ‘counter_54’ [-Werror=unused-variable]
54 | uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_54 = 0;
| ^~~~~~~
macro_make_unique_variable_name_with_line_number.c:39:33: note: in definition of macro ‘CONCAT_’
39 | #define CONCAT_(prefix, suffix) prefix##suffix
| ^~~~~~
macro_make_unique_variable_name_with_line_number.c:45:43: note: in expansion of macro ‘CONCAT’
45 | #define MAKE_UNIQUE_VARIABLE_NAME(prefix) CONCAT(prefix##_, __LINE__)
| ^~~~~~
macro_make_unique_variable_name_with_line_number.c:54:14: note: in expansion of macro ‘MAKE_UNIQUE_VARIABLE_NAME’
54 | uint64_t MAKE_UNIQUE_VARIABLE_NAME(counter) = 0; // `uint64_t counter_54 = 0;
| ^~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
GCC doesn't require "wrapping" (or realizing) unless the result needs to be "stringified". Gcc has features but ALL can be done with plain C version 1 (and some argue Berkeley 4.3 C is so much faster it's worth learning how to use).
**Clang (llvm) DOES NOT DO WHITE SPACE CORRECTLY for macro expansion - it adds whitespace (which certainly destroy's the result as being a C Identifier for further pre-processing) **, clang simply doesn't do # or * macro expansion as a C Preprocessor is expected to for decades. The prime example is compiling X11, macro "Concat3" is broken, it's result is now MISNAMED C Identifier, which of course fails to build. and i'm beginning to thing build fails are their profession.
I think the answer here is "new C that breaks standards is bad C", these hacks always choose to (clobber namespaces) they change defaults for no reason but do not really "improve C" (excepting to their own say so: which i say is contraption made to explain why they get away with all the breakage no one yet has made them responsible for).
It's not a problem that the earlier C pre-processors did not support UNIq_()__ because they supported #pragma which allows "compiler brand hackery in code to be flagged as hackery" and also function just as well WITHOUT effecting standards: just as changing defaults is useless wonton breakage, and just as changing what a function does while using the same name (namespace clobbering) is ... malware in my opinion