2012-06-08 15 views
5

Đầu tiên một số nền. Trong một avr nhỏ, dữ liệu có thể được lưu trữ trong sổ đăng ký, trong sram, trong eeprom hoặc trong không gian chương trình. Đăng ký và sram là lưu trữ dễ bay hơi trong khi không gian eeprom và chương trình thì không. (Ví dụ:. Dữ liệu nghỉ khi không được hỗ trợ)Trong một avr nhỏ, làm thế nào là dữ liệu có nghĩa là để được lưu trữ trong sram khởi tạo khi vi điều khiển được cấp nguồn?

Khi lập trình trong c (sử dụng các thư viện avr-gcc), một mã điển hình có thể trông giống như:

#define F_CPU 8000000UL 
#include <inttypes.h> 
#include <avr/io.h> 
#include <avr/pgmspace.h> 
#include <avr/eeprom.h> 

//This data is put in the eeprom 
const uint8_t dat_eeprom EEMEM= 0xab; 
//This data is put in the program space 
const uint8_t dat_pgm_space PROGMEM= 0xcd; 
//This data is stored in the sram 
uint8_t dat_sram = 0xef; 

int main(){ 
    while(1){ 
    ;; 
    } 
} 

Biên soạn với:

avr-gcc -g -mmcu=attiny44 -o test.elf test.c 

Và giải nén một hex intel từ elf:

avr-objcopy -j .text -j .data -O ihex test.elf test.hex 

Chúng tôi nhận được test.hex sau:

:1000000011C023C022C021C020C01FC01EC01DC0FF 
:100010001CC01BC01AC019C018C017C016C015C01C 
:1000200014C0CD0011241FBECFE5D1E0DEBFCDBF8F 
:1000300010E0A0E6B0E0EAE5F0E002C005900D9225 
:10004000A236B107D9F702D006C0DACFCF93DF933B 
:0A005000CDB7DEB7FFCFF894FFCF65 
:02005A00EF00B5 
:00000001FF 

Và sau dissassembly:

00000000 <.sec1>: 
0: 11 c0   rjmp .+34  ; 0x24 
     <...skipped interrupt vector table...> 
20: 14 c0   rjmp .+40  ; 0x4a 
22: cd 00   .word 0x00cd ; this is our data stored in the program mem. 
24: 11 24   eor r1, r1 
26: 1f be   out 0x3f, r1 ; 63 
28: cf e5   ldi r28, 0x5F ; 95 
2a: d1 e0   ldi r29, 0x01 ; 1 
2c: de bf   out 0x3e, r29 ; 62 
2e: cd bf   out 0x3d, r28 ; 61 
30: 10 e0   ldi r17, 0x00 ; 0 
32: a0 e6   ldi r26, 0x60 ; X register low byte ; address of dest. in 
34: b0 e0   ldi r27, 0x00 ; X register high byte; sram 
36: ea e5   ldi r30, 0x5A ; z register low byte ; address of data in 
38: f0 e0   ldi r31, 0x00 ; z register high byte; program memory 
3a: 02 c0   rjmp .+4   ; 0x40 
3c: 05 90   lpm r0, Z+ 
3e: 0d 92   st X+, r0 
40: a2 36   cpi r26, 0x62 ; 98 
42: b1 07   cpc r27, r17 
44: d9 f7   brne .-10  ; 0x3c 
      <...skipped rcall to main...> 
5a: ef 00   .word 0x00ef ; this is our data that 
             should be stored in the sram. 

Vậy làm thế nào là dữ liệu (0xef) mà chúng ta muốn đưa vào SRAM khởi tạo?
Câu trả lời là thông qua một thói quen trước khi chính.

Dữ liệu sẽ được lưu trữ trong SRAM tại địa chỉ 0x5a, trong không gian chương trình. Nó được đặt trong sram theo cách sau:

  1. Ký hiệu x cao và thấp được đặt thành địa chỉ nơi chúng tôi muốn đưa dữ liệu vào SRAM. (0x60) lưu ý rằng địa chỉ này không trong bộ nhớ chương trình nhưng trong bộ nhớ dữ liệu.
  2. Tương tự cho thanh ghi z, nhưng với địa chỉ nơi dữ liệu nằm trong không gian chương trình (0x5a)
  3. nội dung của bộ nhớ chương trình tại địa chỉ được lưu trữ trong thanh ghi z được nạp vào thanh ghi r0 qua lpm opcode. Lưu ý rằng giá trị đăng ký z được tăng lên để trỏ vào dữ liệu tiếp theo (cuối cùng, không có ở đây) để tải vào sram.
  4. dữ liệu trong r0 sau đó được lưu trữ trong sram tại địa chỉ được lưu trữ trong thanh ghi x.
  5. Lặp lại cho đến khi tất cả dữ liệu phải ở dạng sram đã được khởi tạo.

Điều này xảy ra trước khi diễn ra cuộc gọi chính.

Có câu trả lời tốt hơn/rõ ràng hơn không?

Trả lời

-1

Nếu bạn muốn dữ liệu trong bạn SRAM, chương trình của bạn phải đặt nó ở đó.

Có, đã làm điều đó cho bạn.

+0

Vâng, bây giờ điều đó hiển nhiên đối với tôi, nhưng tôi đã dành một chút thời gian để tìm ra lý do dữ liệu tôi muốn trong SRAM ở cuối .hex. Hy vọng nó sẽ giúp ai đó. – user1443332

1

Phải, trong thế giới công cụ gnu và các cách tương tự chắc chắn với các công cụ khác.

trình liên kết được cung cấp dữ liệu .text, .data, .bss và phải đặt nó vào nhị phân. cho một hệ thống dựa trên flash, không có gì cụ thể cho avr, tương tự cho tất cả các nền tảng, tất cả các thông tin không bay hơi phải được bật đèn flash. Kịch bản liên kết cho người liên kết biết rằng đoạn .data có hai ngôi nhà, một ngôi nhà được gắn với .text và bất kỳ thứ gì khác trong flash, và sau đó là một ngôi nhà trong không gian địa chỉ ram. Bạn tạo kịch bản trình liên kết của bạn với một số từ khóa mà trình liên kết sẽ điền vào các biến bên ngoài trong mã khởi động của bạn (mã asm gọi chính).Mã này sử dụng các biến này để sao chép .data thành ram và không ra .bss trước khi gọi chính để các giả định ngôn ngữ C (các biến đơn vị hóa là số không và các biến được khởi tạo là mã của bạn đã khởi tạo chúng). Nếu bạn viết mã của bạn để bạn không bao giờ giả định một biến được khởi tạo trước khi chính thì bạn sẽ không phải làm bất kỳ điều nào, mã init chính của bạn có thể chỉ đơn giản là đặt con trỏ ngăn xếp và nhánh thành chính.

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