2010-07-27 37 views
10

Tôi đang làm việc trong bộ điều khiển vi mô bằng cách sử dụng ngôn ngữ C. Trong vi cụ thể này, các ngắt phải được xác định bằng #pragma theo cách sau:#pragma bên trong #define

static void func(); 
#pragma INTERRUPT func <interrupt_address> <interrupt_category> 
static void func() { /* function body */ } 

Các <interrupt_address> là địa chỉ của ngắt trong bảng vector. Các <interrupt_category> là 1 hoặc 2. Ví dụ, để xác định một ngắt ở Port 0 pin 0:

static void _int_p00(); 
#pragma INTERRUPT _int_p00 0x10 1 
static void _int_p00() { (*isr_p00)(); } 

Chúng ta định nghĩa dịch vụ thường xuyên ngắt thực tế ở nơi khác và trỏ chức năng sử dụng (như isr_p00 trong ví dụ) để thực hiện chúng.

Sẽ thuận tiện nếu các ngắt có thể được xác định bằng macro. Tôi muốn làm định nghĩa một macro theo cách sau:

#define DECLARE_INTERRUPT(INT_NAME, INT_CAT) \ 
    static void _int_##INT_NAME(); \ 
    #pragma INTERRUPT _int_##INT_NAME INT_NAME##_ADDR INT_CAT \ 
    static void _int_##INT_NAME() { (*isr_##INT_NAME)(); } 

Trình biên dịch ném lỗi sau:

Formal parameter missing after '#' 

cho thấy dòng sau:

static void _int_##INT_NAME() { (*isr_##INT_NAME)(); } 

Tôi đoán chỉ thị tiền xử lý không thể được sử dụng trong #define s? Có bất kỳ công việc xung quanh?

+1

Vi điều khiển và trình biên dịch nào? Nếu nó dựa trên GCC, có thể có macro thuộc tính đặc biệt mà yo có thể sử dụng, như trong C32 của Microchip: 'void __ISR (_TIMER_5_VECTOR) SomeISR (void)' – detly

+1

Vi là OKI 431 và trình biên dịch là từ OKI: IDEU8. – Donotalo

Trả lời

11

C99 có _Pragma từ khóa mới cho phép bạn đặt #pragma macro bên trong. Về cơ bản nó mong đợi một chuỗi như là một đối số tương ứng với văn bản mà bạn sẽ cung cấp cho chỉ thị #pragma.

Nếu trình biên dịch của bạn không hỗ trợ tính năng này (gcc) và bạn muốn thực hiện bên ngoài những gì bạn cần (như đã nói, m4 có thể là lựa chọn) tốt nhất có thể là ở gần nhất có thể đến mức không phải như vậy mới _Pragma. Sau đó, khi trình biên dịch trình biên dịch của bạn bắt kịp với tiêu chuẩn, bạn có thể ngừng sử dụng tập lệnh của mình.

+0

Trình biên dịch không hỗ trợ _Pragma. :( – Donotalo

+1

@Donotalo, quá tệ.Chỉ 11 năm sau tiêu chuẩn này tồn tại ;-) Bạn có thể thử một giải pháp hỗn hợp chỉ bằng cách sử dụng 'gcc' làm tiền xử lý và sau đó sử dụng trình biên dịch gốc của bạn cho các giai đoạn biên dịch tiếp theo. –

1

Workround là sử dụng tạo mã hoặc một ngôn ngữ macro khác để xử lý trước mã của bạn.

tức là viết mã bằng một phần mở rộng khác.

Có makefile của bạn hoặc gọi tương tự như các ngôn ngữ vĩ mô (ví dụ m4) hoặc một kịch bản của một số hình thức để tạo ra một tập tin .c

Sau đó biên dịch đó.

+0

Tìm kiếm giải pháp sẽ không gọi tập lệnh khác. – Donotalo

0

Theo như tôi biết, bạn là gì cụ thể hỏi là không thể. Tôi giả sử một bộ tiền xử lý hoạt động giống như GNU C Preprocessor. Trong cuốn hướng dẫn cho rằng, it states:

The compiler does not re-tokenize the preprocessor's output. Each preprocessing token becomes one compiler token.

+0

Tôi cũng nghĩ rằng điều đó là không thể. Nhưng tôi tự hỏi nếu có bất kỳ cách nào khác nó có thể đạt được. – Donotalo

Các vấn đề liên quan