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.