2010-09-21 28 views
5

Tôi có một dự án được nhúng bằng cách sử dụng STM32F103 (ARM Cortex M3), thỉnh thoảng sẽ gặp phải lỗi nghiêm trọng trong chế độ phát hành. Là một phần của phục hồi, tôi muốn lấy giá trị máy tính từ trước khi lỗi cứng và lưu trữ nó để gỡ lỗi sau trong vùng được hỗ trợ pin.ARM Cortex M3 Làm cách nào để xác định giá trị bộ đếm chương trình trước một lỗi cứng?

Làm cách nào để xác định giá trị của bộ đếm chương trình tại điểm của lỗi cứng? Rõ ràng, PC giờ đây được đặt ở vị trí của nó trong ngắt kết nối của hardfault.

Tôi nên tìm ở đâu? Nó có một địa chỉ cho ngân hàng đăng ký chế độ bình thường không?

Cảm ơn!

+0

Tôi cũng muốn biết, nhưng bạn có thể nhận được câu trả lời tốt hơn trên chiphacker.com. – leppie

Trả lời

6

Cortex-M3 sử dụng một mô hình xử lý ngoại lệ khá khác với ARM "cổ điển", ví dụ: nó không có "chế độ hủy bỏ" được đề cập trong bài đăng khác. Tôi khuyên bạn nên đọc this app note . Ví dụ, đối với các lỗi cứng:

giá trị của SCB-> BFAR chỉ ra địa chỉ bộ nhớ mà gây ra một lỗi Bus và có giá trị nếu các bit BFARVALID vào sổ đăng ký SCB-> CFSR được thiết lập các.Giá trịcủa SCB-> MMFAR cho biết địa chỉ bộ nhớ gây ra lỗi Bộ nhớ quản lý và hợp lệ nếu bit MMFARVALID trong thanh ghi SCB-> CFSR được đặt.

Để xác định giá trị PC tại thời điểm ngoại lệ, bạn cần kiểm tra ngăn xếp; bộ xử lý đẩy R0-R3, R12, PC và LR trước khi thực hiện xử lý. Ngăn xếp được sử dụng có thể là Main (nếu bit 2 của LR là 0) hoặc Process (nếu không). Xem trang 13 của ghi chú ứng dụng để biết chi tiết.

+0

Cảm ơn Igor, làm cách nào để tìm nạp PC từ ngăn xếp? – JeffV

+1

Bạn cần phải lấy PSP hoặc MSP và nhận được một từ tại offset 0x18 từ nó. Xem ví dụ về triển khai tại đây: http://embdev.net/topic/170640#1636052 –

+0

Vẫn đang cố gắng tìm hiểu điều này. Điều này có bù đắp 24 byte trên MSP không ?: uint32_t * pc = (uint32_t *) ((char *) _ get_MSP() + 24); – JeffV

3

Bạn nên xem xét ARM Architecture Reference Manual trong phần Ngoại lệ. Bạn cần phải đăng ký để có được nó.

Thông thường một địa chỉ có liên quan sẽ được đặt trong thanh ghi liên kết LR (R14), nhưng ý nghĩa chính xác thay đổi tùy theo ngoại lệ và có chênh lệch khác nhau.

W.r.t. truy cập vào ngân hàng đăng ký chế độ Người dùng/Hệ thống, tôi nghĩ bạn cần chuyển sang chế độ để truy cập nó.

+0

Ahh, tuyệt! Chỉ cần kiểm tra nó trong khi gỡ lỗi (không có đầu mối làm thế nào để gọi một lỗi cứng hiện tại; p) và nó thực sự cho thấy địa chỉ của người gọi. Cảm ơn rất nhiều! – leppie

+0

OK, tôi thấy nó không phải là người gọi, mà là địa chỉ trả lại. – leppie

+1

Tôi đã tạo ra lỗi do: * ((char *) 0x00) = 5; – JeffV

0

Tôi tìm thấy nguyên nhân phổ biến cho các sự cố này là sự chậm trễ 'vòng lặp'. Khi sử dụng -O3, chúng chỉ đơn giản được tối ưu hóa nếu bạn không đề cập đến các biến dễ bay hơi. Cá nhân tôi thích phương pháp SysTick hơn.

+0

Cảm ơn @leppie, hết lòng đồng ý.Không có sự chậm trễ vòng lặp ở đây, tôi; m cũng sử dụng SysTick để đếm của tôi. Mọi thứ đều ở trong máy trạng thái, để tránh bị chặn. Tôi nghĩ rằng vấn đề sẽ hiện diện trong chế độ gỡ lỗi nếu tôi đã cho nó đủ thời gian. – JeffV

1

Khi ngoại lệ xảy ra, trạng thái bộ xử lý thay đổi từ trạng thái hiện tại thành trạng thái hủy bỏ trạng thái. Trong trạng thái hủy bỏ, bộ xử lý thay đổi để sử dụng một bộ thanh ghi mới cho sp và lr (sp_abt và sp_lr tương ứng. Để hủy bỏ dữ liệu, hướng dẫn vi phạm có thể được tìm thấy trong lr_abt + 8 cho một trưởng trong lr_abt + 4 (theo Cẩm nang tham khảo ARMv7 Architecure)

+0

Tuyệt vời, cảm ơn! – JeffV

+0

thay đổi sp_abt thành lr_abt là một sai lầm nghiêm trọng đối với phần của tôi - cố định – doron

+2

Điều này có giá trị đối với ARM cổ điển nhưng không phải Cortex-M3 –

1

Tôi có Câu hỏi thường gặp về chính chủ đề này. Trang được liên kết đến từ Câu hỏi thường gặp bao gồm fault handler code sẽ nhận được bộ đếm chương trình từ ngăn xếp cho bạn.

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