C 소스에서 직접 AVR EEPROM 프로그래밍


11

AVR C 소스에 다음 코드를 포함 시키면 추가 명령이나 .hex 파일없이 퓨즈를 직접 프로그래밍 할 수 있습니다.

#include <avr/io.h>

FUSES = {
        .low =          LFUSE_DEFAULT ,
        .high =         HFUSE_DEFAULT ,
        .extended =     EFUSE_DEFAULT ,
};

EEPROM에서 값을 프로그래밍하는 것과 비슷한 트릭이 있습니까?

/usr/lib/avr/include/avr/fuse.h매크로에 대한 의견을 어디에서 찾을 수 있는지 확인 했지만 비슷한 의견을 찾을 수 없으며 /usr/lib/avr/include/avr/eeprom.h전 처리기 내용을 해석하는 것이 리그에서 약간 벗어났습니다.

C 소스 코드에 기본 EEPROM 값을 포함시킬 수 있다면 정말 유용 할 것입니다. 그것을 달성하는 방법을 아는 사람이 있습니까?

edit1 :

이 퓨즈 트릭은 실행 시간이 아닌 ISP 시간에만 실행됩니다. 따라서 컨트롤러의 결과 어셈블리 코드에 퓨즈가 프로그래밍되어 있지 않습니다. 대신 프로그래머는 자동으로 추가 FUSES 프로그래밍주기를 순환합니다.

edit2 :

Linux에서 avr-gcc 및 avrdude 도구 체인을 사용합니다.


ISP를 프로그래밍 할 때만 해당됩니까? 대부분의 부트 로더에서는 퓨즈를 프로그래밍 할 수 없습니다.
angelatlarge

2
나는 지금 완전한 답을 쓸 시간이 없지만 힌트로 EEMEM 지시어를 검색해보십시오. 또한 프로그래머가 사용할 별도의 .EPP 파일을 만들기 위해 링커 설정을 변경해야 할 수도 있습니다.
PeterJ

@angelatlarge ISP 프로그래밍 전용. 이 설정에는 부트 로더가 없습니다.
jippie

2
이에 대한 대답은 전적으로 툴체인이 출력에 기꺼이 기록 할 내용과 프로그래머가 파싱 할 내용에 달려 있습니다. 대부분의 툴체인은 특별한 섹션을 만들거나 가상의 주소에 데이터를 넣도록 구성 될 수 있으므로 궁극적으로 프로그래머는이를 추출하거나 그렇게하는 사용자 지정 스크립트에 의해 구동 될 수 있습니다.
Chris Stratton

답변:


7

avr-gcc를 EEMEM사용하면 변수 정의에 매크로를 사용할 수 있습니다. libc문서 및 예제는 다음을 참조 하십시오 .

#include <avr/eeprom.h>
char myEepromString[] EEMEM = "Hello World!";

".eeprom"이라는 섹션에있는 문자 배열을 컴파일합니다.이 섹션은 컴파일 후 프로그래머에게이 데이터가 EEPROM에 프로그래밍되어야 함을 알려줍니다. 프로그래머 소프트웨어에 따라 빌드 프로세스 중에 작성된 ".eep"파일의 이름을 프로그래머에게 명시 적으로 제공하거나 내재적으로 찾을 수 있습니다.


필자는 'supposed'와는 약간 다른 파일 이름을 사용했지만 다음은 명령 줄 (및 makefile)에서 EEPROM을 프로그래밍하기 위해 포함시킨 명령입니다.
jippie

1
프로그래머가 사용하는 Intel Hex 데이터를 포함하는 파일을 작성하십시오.avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 ihex $(src).elf $(src).eeprom.hex
jippie

1
실제 프로그래밍은 다음과 같이 수행됩니다.avrdude -p$(avrType) -c$(programmerType) -P$(programmerDev) -b$(baud) -v -U eeprom:w:$(src).eeprom.hex
jippie

7

예, 소스 코드에서 기본 데이터를 EEPROM에 수동으로 쓸 수 있습니다. 먼저, AVR : Dean의 AVR EEPROM Tutorial 과 함께 EEPROM에 대한이 멋진 안내서를 확인하십시오 . 또한 소스 파일과 함께 장치에 프로그래밍되는 makefile을 사용하여 EEPROM 데이터를 포함하는 .eep 파일을 만드는 것이 더 좋습니다. 그러나 다양한 makefile 및 링커 작업에 익숙하지 않은 경우 소스 코드 파일 내에서 계속 수행 할 수 있습니다. 회로에 전원을 공급하자마자 초기 프로그램 작업이 중단됩니다.

프로그램 시작시 (모든 종류의 메인 루프 이전에) 다음과 같은 작업을 수행 할 수 있습니다.

#include <avr/eeprom.h>

#define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_2 52  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_3 68  // This could be anything from 0 to the highest EEPROM address

uint8_t dataByte1 = 0x7F;  // Data for address 1
uint8_t dataByte2 = 0x33;  // Data for address 2
uint8_t dataByte3 = 0xCE;  // Data for address 3

eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);

"업데이트"기능은 먼저 EEPROM 수명을 유지하면서 불필요한 쓰기를 저장하기 위해 해당 값이 이미 있는지 확인합니다. 그러나 매우 많은 위치에서이 작업을 수행하려면 시간이 다소 걸릴 수 있습니다. 단일 위치를 확인하는 것이 좋습니다. 원하는 값이면 나머지 업데이트를 완전히 건너 뛸 수 있습니다. 예를 들면 다음과 같습니다.

if(eeprom_read_byte((uint8_t*)SOME_LOCATION) != DESIRED_VALUE){
  eeprom_write_byte((uint8_t*)SOME_LOCATION, DESIRED_VALUE);
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
  eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
  eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);
}

대량의 데이터를 업데이트하려는 경우와 같은 다른 기능을 사용해보십시오 eeprom_update_block(...). 그리고 그 튜토리얼을 확실히 읽으십시오. 잘 작성되었습니다.

모든 EEPROM 업데이트 명령문을 단일 전 처리기 조건문에 넣을 수 있습니다. 이것은 매우 간단합니다.

#if defined _UPDATE_EEPROM_
  #define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
  uint8_t dataByte = 0x7F;  // Data for address 1
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
#endif // _UPDATE_EEPROM_

이 코드는 다음을 수행하지 않으면 컴파일되지 않습니다.

#define _UPDATE_EEPROM_

주석으로 남겨두고 기본 EEPROM 값을 변경해야하는 경우 주석을 해제하십시오. C 전처리기에 대한 자세한 내용은이 온라인 설명서를 확인하십시오 . 매크로 및 조건문 섹션에 가장 관심이 있다고 생각합니다.


정답은 연결된 PDF의 마지막 단락에있는 것 같습니다. Ch. 7 Setting Initial Values.
jippie

그래 정확 해. 나는 첫 번째 단락에서 언급했지만 make 파일의 .eep 파일과 링커에 익숙하지 않은 경우에 계속되었습니다!
Kurt E. Clothier

1
정적 EEPROM 주소를 사용하는 것은 좋지 않습니다. 대신 EEMEM 속성을 사용하고 컴파일러가 주소 배포를 관리하도록하는 것이 좋습니다. 또한 각 섹션에 대해 CRC 검사를 구현 / 수행하는 것이 좋습니다. CRC가 실패하면 해당 섹션에 초기화되지 않았거나 손상된 데이터가 포함됩니다. 이렇게하면 데이터가 손상된 경우 이전 구성에 대한 폴백 메커니즘을 구현할 수도 있습니다.
Rev1.0

"정적 EEPROM 주소를 사용하는 것은 좋지 않습니다." 왜?
angelatlarge

1
EEMEM변수를 사용할 때 컴파일러는 EEPROM의 어느 변수가 상주하는지 관리합니다. 이렇게하면 데이터에 액세스 할 때 변수에 대한 (상수, 컴파일러 생성) 포인터 만 작동합니다. 반면에 각 변수가 상주하는 주소를 명시 적으로 정의한 경우 실수로 동일한 주소를 사용하는 변수가 없는지 확인하고 서로 겹쳐 쓰는 등의 주소를 직접 관리해야합니다. 또는 미래에 변수의 스토리지 크기가 변경 될 경우를 대비하여 모든 주소를 다시 계산하십시오.
JimmyB
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.