2013-07-31 58 views
5

Sử dụng avr-gcc có thể lưu trữ dữ liệu trên Bộ nhớ chương trình để tiết kiệm RAM. Điều này được hoàn thành bằng cách sử dụng PROGMEM attribute. AVR-libc cũng cung cấp một macro, PSTR(), có thể được sử dụng với các chuỗi ký tự.PSTR() trên __FUNCTION__

Bây giờ tôi đang cố gắng sử dụng PSTR() với __func__, __FUNCTION__ or __PRETTY_FUNCTION__.

Các mã sau công trình như mong đợi,

display.message(__func__, 2); 
display.message(__FUNCTION__, 2); 
display.message(__PRETTY_FUNCTION__, 2); 

, trong khi biên soạn của bất kỳ của những dòng này thất bại,

display.messageP(PSTR(__func__), 2); 
display.messageP(PSTR(__FUNCTION__), 2); 
display.messageP(PSTR(__PRETTY_FUNCTION__), 2); 

, với lỗi sau:

initializer fails to determine size of '__c' 

Định nghĩa của PSTR, từ WinAVR/avr/include/avr, giải thích các biến được giới thiệu trên các thông báo lỗi:

# define PSTR(s) (__extension__({static char __c[] PROGMEM = (s); &__c[0];})) 

Đây không phải là một cái gì đó chung để macro, như __FILE__ biên dịch và hoạt động tốt:

display.messageP(PSTR(__FILE__), 2); 

Bất kỳ ý tưởng nào về nguyên nhân gây ra lỗi này và nếu có thể sử dụng PSTR() để chèn tên hàm vào bộ nhớ chương trình?

+0

Có vẻ như không thể đặt các chuỗi ký tự chuỗi đó vào không gian đó khi chúng yêu cầu các chức năng đặc biệt? để truy cập chúng. Thật ra, những cái tên này khá nhỏ bé nên tôi tự hỏi liệu có một lợi thế thực sự để di chuyển chúng ở đó hay không. Tôi nói điều này mà không có ý tưởng về số lượng RAM thực tế bạn có mặc dù. –

+0

@MichaelDorgan avr-libc cung cấp các chức năng truy cập biến trong bộ nhớ chương trình; điều này được xác nhận bởi dòng cuối cùng của mã trên câu hỏi, mà hoạt động tốt. Tôi đồng ý rằng các chuỗi này là nhỏ, nhưng chúng rất quan trọng trong các hệ thống nhúng (chỉ với một vài Kbytes RAM). – mMontu

Trả lời

8

__func__, __FUNCTION____PRETTY_FUNCTION__ không chuỗi literals, như __FILE__, nhưng được tạo ra như biến mảng char địa phương tĩnh để các chức năng bạn đang sử dụng chúng từ. Vì vậy, các PSTR() vĩ mô sẽ thất bại vì bạn không thể sử dụng một biến mảng để khởi tạo một biến mảng như thế.

__func__ được mô tả trong C11, § 6.4.2.2 ¶ 1:

The identifier __func__ shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration

static const char __func__[] = "function-name";
appeared, where function-name is the name of the lexically-enclosing function.

According to the GCC manual, __FUNCTION____PRETTY_FUNCTION__ chỉ là từ đồng nghĩa cho __func__ trong C (__PRETTY_FUNCTION__ là tiết hơn cho C++).

+0

Có cách nào để đưa __func__ vào bộ nhớ chương trình không? Theo mặc định định nghĩa đặt nó trong RAM. Rõ ràng mọi người không muốn lãng phí RAM trên dữ liệu gỡ lỗi tĩnh. –

+0

Câu hỏi là về avr-gcc, ngụ ý nền tảng AVR. Nó là một kiến ​​trúc Harvard với hai không gian bộ nhớ. Bộ nhớ chương trình là bộ nhớ flash của thiết bị, thường chỉ đọc. Vì các thiết bị chỉ có RAM giới hạn (16k là giới hạn, thường là 2-4k), bạn không muốn lấp đầy nó bằng các chuỗi gỡ lỗi. –

+0

@MoJo: Cảm ơn vì đã làm rõ. Có vẻ như bạn sẽ cần phải khai báo các biến riêng của bạn theo từng trường hợp nếu bạn có yêu cầu này, hoặc bạn phải sửa đổi trình biên dịch để mở rộng nó cho phép bạn chỉ định đích bộ nhớ cho biến '__func__'. – jxh