2012-12-05 35 views
6

Tôi đang cố gắng xây dựng một dự án đơn giản bằng Yagarto và Eclipse cho nền tảng vi điều khiển ARM. Trong mã khởi động của tôi, tôi có điều này (mà tôi tin là khá chuẩn và nhàm chán):Tại sao tôi có một tham chiếu không xác định đến _init trong __libc_init_array?

void Reset_Handler(void) 
{ 
    /* Initialize data and bss */ 
    __Init_Data(); 

    /* Call CTORS of static objects */ 
    __libc_init_array(); 

    /* Call the application's entry point.*/ 
    main(); 

    while(1) { ; } 
} 

Trừ khi tôi nhận xét ra các cuộc gọi đến __libc_init_array(), tôi nhận được sau lỗi từ mối liên kết:

arm-none-eabi-g++ -nostartfiles -mthumb -mcpu=cortex-m4 -TC:/Users/mark/workspace/stm32_cpp_test/STM32F40x_1024k_192k_flash.ld -gc-sections -Wl,-Map=test_rom.map,--cref,--no-warn-mismatch -o stm32_cpp_test "system\\syscalls.o" "system\\startup_stm32f4xx.o" "system\\mini_cpp.o" "system\\cmsis\\system_stm32f4xx.o" main.o 
d:/utils/yagarto/bin/../lib/gcc/arm-none-eabi/4.7.2/../../../../arm-none-eabi/lib/thumb/v7m\libg.a(lib_a-init.o): In function `__libc_init_array': 
C:\msys\1.0\home\yagarto\newlib-build\arm-none-eabi\thumb\v7m\newlib\libc\misc/../../../../../../../newlib-1.20.0/newlib/libc/misc/init.c:37: undefined reference to `_init' 
collect2.exe: error: ld returned 1 exit status 

Tại sao tôi nhận được lỗi "tham chiếu không xác định" này? Tôi đang thiếu gì? Tôi cho rằng có một số lá cờ liên kết mà tôi đang thiếu, nhưng tôi không thể cho cuộc sống của tôi tìm ra cái gì.

Trả lời

5

Tôi không phải chuyên gia, nhưng:

lẽ _init (runtime nhập điểm bình thường) tham chiếu mã thực thi các bảng ctor và dtor.

Bạn sử dụng -nostartfiles để tránh khởi động chuẩn và có thể toàn bộ mã khởi đầu sẽ bị loại bỏ bởi các phần --gc. Cuộc gọi rõ ràng sẽ thêm lại tham chiếu.

Nếu bỏ qua --gc-phần không giải quyết nó, nó cũng có thể là một pháo đài() tuyên bố mất tích trong (nhúng) kịch bản mối liên kết của bạn mà giữ mã nhập vào mọi lúc, hoặc mã khởi động của riêng bạn (startup_ *) nên tham khảo nó

+0

Vì vậy, nếu tôi thêm void _init (void) {} ​​vào mã khởi động của tôi, nó sẽ biên dịch tốt. Tôi tự hỏi chức năng này được cho là phải làm gì? – Mark

+0

_init thường là điểm trong hệ nhị phân mà hệ điều hành nhảy đến nếu một tệp nhị phân đã được tải. Nhãn mặc định cho điểm nhập nhiều hơn hoặc ít hơn. Cách khắc phục sự cố phụ thuộc vào cách thiết lập hệ thống trình tải nhúng của bạn. Đối với tôi, có vẻ như công cụ này không được chuyển hoàn toàn. –

+0

Tôi không có "hệ thống trình tải nhúng", tôi đã tự viết mã khởi động (hoặc, cụ thể hơn là tôi sao chép + dán từ internet) ... Đây là Cortex-M4 và ResetHandler là lần đầu tiên (và chỉ) điều được thực hiện. – Mark

4

Câu hỏi cũ, nhưng tôi gặp phải vấn đề tương tự và giải pháp như Marco van de Voort đã nêu, nếu bạn định sử dụng __libc_init_array, bạn nên bỏ qua tùy chọn liên kết -nostartfiles, để bao gồm thông thường các hàm initc libc. Câu trả lời trùng lặp. Thứ hai, tôi khuyên bạn nên bao gồm cờ --specs=nano.specs khi liên kết với gcc-arm (Tôi tin yargarto là một ngã ba hoặc thậm chí chỉ là một biên dịch trước của gcc-arm), vì nó làm giảm tiêu thụ mã libc vv.

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