2012-03-21 36 views
18

Tôi đang làm việc với một chip ARM Cortex M3 (STM32F2) và ST cung cấp một "thư viện ngoại vi tiêu chuẩn". Nó có một số tệp .c và .h hữu ích. Nó cũng có các tệp .s.Vai trò của tệp .s trong dự án C là gì?

Mục đích của các tệp .s này trong ngữ cảnh của dự án C là gì? Làm thế nào để tôi nhận được trình biên dịch/liên kết /? để đưa họ vào tài khoản?

Trả lời

27

Phần mở rộng .s là quy ước được sử dụng bởi GNU và nhiều chuỗi công cụ khác cho các tệp lắp ráp.

Cuối cùng tôi xem thư viện chuẩn ngoại vi STM32 không chứa tệp lắp ráp, tuy nhiên thư viện CMSIS chứa mã khởi động cho các phần STM32 khác nhau, ví dụ startup_stm32f2xx.s là mã khởi động cho tất cả các thiết bị dòng STM32F2xx. Có các cách triển khai khác nhau cho các chuỗi công cụ khác nhau; bạn cần xây dựng và liên kết tệp được liên kết với phần cụ thể và chuỗi công cụ của bạn. Nếu bạn đang sử dụng một dự án ví dụ xây dựng và chạy hoặc một IDE tạo ra các dự án cụ thể cho bạn, điều này có thể đã được thực hiện - nếu bạn có mã chạy nó chắc chắn có.

Cách bạn tạo và liên kết mã sẽ tùy thuộc vào chuỗi công cụ bạn đang sử dụng. Hầu hết các công cụ dựa trên IDE sẽ tự động nhận ra phần mở rộng và gọi trình kết hợp để tạo ra một tệp đối tượng sẽ được liên kết như bất kỳ tệp nào khác. Nội dung chính xác hơi khác nhau giữa các phiên bản chuỗi công cụ, nhưng chủ yếu tạo ra môi trường thời gian chạy C (ngăn xếp và đống), khởi tạo bộ xử lý, xác định bảng vectơ ngắt/ngắt ban đầu, khởi tạo dữ liệu tĩnh và nhảy tới main().

Cốt lõi của tập tin cho các phiên bản RealView Keil/ARM ví dụ như sau:

; Reset handler 
Reset_Handler PROC 
       EXPORT Reset_Handler    [WEAK] 
     IMPORT SystemInit 
     IMPORT __main 
       LDR  R0, =SystemInit 
       BLX  R0 
       LDR  R0, =__main 
       BX  R0 
       ENDP 

Reset_Handler là địa chỉ Chương trình Counter (PC) đăng ký sẽ được thiết lập để sau khi cài lại xử lý.

SystemInit là một hàm mã C bên ngoài thực hiện phần lớn quá trình khởi tạo - điều này có thể cần tùy chỉnh cho phần cứng của bạn. Cortex-M là bất thường ở chỗ nó có thể bắt đầu chạy mã C ngay lập tức sau khi đặt lại vì bảng vectơ bao gồm cả địa chỉ đặt lại và địa chỉ con trỏ ngăn xếp ban đầu, được tự động nạp vào thanh ghi SP khi đặt lại. Kết quả là bạn không cần nhiều kiến ​​thức lắp ráp để có được một hoạt động.

__main() là điểm nhập cung cấp trình biên dịch cho mã C của bạn.Nó không phải là hàm main() mà bạn viết, nhưng thực hiện khởi tạo cho thư viện chuẩn, dữ liệu tĩnh, vùng heap trước khi gọi hàm `main() 'của bạn.

Phiên bản GCC có liên quan nhiều hơn vì nó thực hiện nhiều công việc được thực hiện bởi __main() trong phiên bản RealView của Keil/ARM, nhưng về cơ bản nó thực hiện cùng chức năng.

Lưu ý rằng trong CMSIS SystemInit() được xác định trong system_stm32f2xx.c và có thể cần tùy chỉnh cho bo mạch của bạn (tần số tinh thể chính xác, thiết lập PLL, cấu hình SRAM bên ngoài, v.v.). Bởi vì đây là mã C, và cũng nhận xét, bạn có thể sẽ cảm thấy thoải mái hơn với nó.

+0

Ngoại trừ tôi vừa mới nhận thấy bạn đã chỉ định STM32F2xx. Câu trả lời vẫn được áp dụng, ngoại trừ các tên tệp tương ứng là startup_stm32f2xx.s và system_stm32f2xx.c trong trường hợp của bạn. Tôi đã sửa đổi câu trả lời để làm cho nó cụ thể hơn cho STM32F2. – Clifford

+0

Clifford - trong tài liệu trên trang web của ARM, nó đề cập đến các thói quen khác trong startup_xxx.s, __user_initial_stack_heap, không được sử dụng nhiều hơn 88 byte chồng. Bạn có biết giới hạn đó đến từ đâu không? Xem http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.kui0099a/armlib_cihhdahf.htm – NickHalden

+0

@NickHalden: Bạn có nghĩ rằng có lẽ điều đó xứng đáng được đăng tải dưới dạng câu hỏi không? Câu hỏi này đã hơn hai tuổi, và thậm chí không câu hỏi của bạn. Đây không phải là những gì ông ý kiến ​​phần là cho - SO không phải là một diễn đàn thảo luận. Ngoài ra; bạn sẽ có được một lượng khán giả lớn hơn theo cách đó. – Clifford

7

Chúng thường chứa mã lắp ráp. Các assembler biến chúng thành các file đối tượng mà sau đó được liên kết bởi linker với các công cụ chính. Nhưng tôi tưởng tượng nó phụ thuộc vào trình biên dịch, toolchain, vv

1

Bạn có thể có một môi trường phát triển dựa trên Keil cho bộ ST của bạn. Tùy thuộc vào phiên bản trình biên dịch của bạn, tệp dự án nên có các phần khác nhau cho C, C++ và mã trình lắp ráp. Trong IDE của bạn, mở dự án của bạn và tìm "Project Properties" hoặc một cái gì đó giống như nó.

Bạn có thể nhập và xuất các ký hiệu đến và đi từ mã bộ mã hóa sao cho mã đó và mã C/C++ sẽ liên kết. Với Keil, tất cả đều tích hợp tốt.

Chỉ thị XUẤT KHẨU yêu cầu người lắp ráp tạo biểu tượng được chỉ định công khai để mã C/C++ của bạn có thể liên kết với nó.

Chỉ thị IMPORT cho bộ lắp ráp biết rằng biểu tượng được chỉ định được xác định ở nơi khác và sẽ được giải quyết tại thời gian liên kết.

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