2012-01-19 12 views
5

Tôi có vi điều khiển mà tôi đang làm việc. Khi gỡ lỗi nó là cần thiết để gọi một chức năng từ đó là khó mã hóa trong ROM. Kỹ thuật tham khảo cho thấy làm thế nào để làm điều này:Con trỏ hoạt động trong ROM

# define Device_cal (void(*)(void))0x3D7C80 

và kêu gọi thủ tục trông như thế này:

(*Device_cal)() 

Tôi không thể hiểu những gì thực sự xảy ra ở đây, vì vậy câu hỏi của tôi là: Làm thế nào nó hoạt động?

Trả lời

3

Các #define nguyên nhân (*Device_cal)() được mở rộng sang này ngay lập tức trước khi biên dịch:

(*(void(*)(void))0x3D7C80)() 

Các void(*)(void) là một tuyên bố cho một con trỏ hàm mang theo void và trả void loại. Các (*()) đại diện cho một diễn viên cho mã thông báo tiếp theo trong biểu thức (0x3D7C80). Do đó, điều này yêu cầu xử lý dữ liệu tại vị trí 0x3D7C80 như một hàm. Cuối cùng () gọi hàm không có đối số.

7

void (*) (void) là một loại. Đó là một con trỏ đến một hàm không có tham số và trả về void.

(void(*)(void)) 0x3D7C80 phôi số nguyên 0x3D7C80 vào con trỏ hàm này.

(*Device_cal)() gọi hàm.

(Device_cal)() sẽ làm chính xác như cũ.

Các dấu ngoặc đơn xung quanh *Device_calDevice_cal là bắt buộc vì nếu không, việc truyền tới số nguyên sẽ không có mức ưu tiên cao hơn.

2

tốt, bạn "xác định" con trỏ để hoạt động và gọi nó. void(*)(void) có nghĩa là con trỏ hoạt động, không có đối số và trả lại void. Nếu bạn nhập 0x3D7C80 vào loại đó và gọi nó, về cơ bản bạn gọi hàm đó là địa chỉ của nó là 0x3D7C80.

0

Biểu tượng được dán trong đó tạo con trỏ tạm thời (không được đặt tên) cho một hàm tại vị trí bộ nhớ cố định và sau đó gọi nó qua dereferencing.

2

Đây không phải là một câu trả lời (mà đã được thực hiện một cách thỏa đáng), nhưng một số lời khuyên:

tôi sẽ đề nghị các phương pháp sau đây thay vì:

typedef void (*tVOID_ROMFUNCTION_VOID)(void) ; 

tVOID_ROMFUNCTION_VOID Device_cal = (tVOID_ROMFUNCTION_VOID)0x3D7C80 ; 

Device_cal() ; 

Bằng cách đó bạn có thể tạo bất kỳ số lượng toàn cầu các con trỏ hàm trên khởi tạo trong khi các cuộc gọi trông giống như các hàm được liên kết tĩnh bình thường. Và bạn tránh nhầm lẫn voodoo macro xử lý trước cùng một lúc.

Bằng cách tạo các kiểu con trỏ hàm khác nhau với các chữ ký khác nhau, trình biên dịch sẽ có thể thực hiện một số kiểu tham số kiểm tra cho bạn.

+0

Tôi ngạc nhiên khi câu trả lời này không có nhiều phiếu bầu hơn. Nó sạch hơn nhiều so với các giải pháp vĩ mô. – tomlogic

+0

@tom: Cảm ơn, nhưng để công bằng như tôi đã nói, nó không thực sự là một câu trả lời cho câu hỏi được hỏi, chỉ là một cách tốt hơn để làm những gì đã được hỏi về. – Clifford