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ó.
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
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
@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