XC16 .map Dosyasından Değişken Adresi Çekmek

Başlatan Tagli, 04 Ağustos 2014, 11:08:21

Tagli

XC16 derleme işleminden sonra hangi değişkeni nereye yerleştirdiğini proje_adi.X.production.map diye bir dosyada adrese ve isme göre sıralayarak listeliyor. Dosyada başka bir dolu işime yaramayacak bilgi de var. Ben sadece değişken adresleri ile ilgileniyorum. Şu bölümle örneğin:
External Symbols in Data Memory (by address):
                    0x0800                  __txBufSpace
                    0x0828                  __rxBufSpace
                    0x0850                  _txBuffer
                    0x085e                  _rxBuffer
                    0x086c                  _state
                    0x086d                  _checksum
                    0x086e                  _payloadSize

Değişken adlarını bildiğimi varsayalım. Bunların adreslerini bir C programıyla çekmenin en zahmetsiz ve temiz yolu nedir sizce? Yani şöyle bir fonksiyon olmalı:
unsigned int getAddress(FILE* mapFile, char* varName);


Elbette ki GNU/Linux ortamında çalışıyorum. İlk aklıma gelen awk kullanmak oldu, aslında pek bildiğim bir araç değil ama bu işi halletmek için çok derin bir awk bilgisi gerekmiyor sanırım. Kabukta şunu yazmayı denedim (çıktılar da verilmiştir):
$> awk '/state/ {print $1}' proje_adi.X.production.map
0x086c
0x086c
0x086c

Değişken 3 yerde geçtiği için çıktıyı da 3 kez alıyorum. Bunu C'ye fazla uğraşmadan nasıl aktarabilirim? fork-exec ile awk'yı çağırıp çıkışını da kendi programımda bir fd'ye yönlendirirsem (pipe) olur belki ama ne yalan söyleyeyim, üşendim. Daha kolay bir yol var mıdır önerebileceğiniz?
Gökçe Tağlıoğlu

Tagli

Zaman zaman bu forumda kendimi çok yalnız hissettiğim oluyor. Sorduğum soruların pek kazık olduğunu sanmıyorum ama görülen o ki kimsenin ilgisini çekmiyor.

Neyse, yukarıda bahsettiğim fork-dup2-exec olayını gayet sadeleştiren bir fonksiyon varmış zaten: popen. Görünce adını hatırladım ama hem var olduğunu hem de ne iş yaptığını tamamen unutmuşum. Özetle, bir programı ayrı bir process olarak çalıştırmanıza ve çıktısını da dosya üzerinden okur gibi okumanıza olanak veriyor. Tabi aslında dosya değil pipe üzerinden okuyor.

Örnek kod:
#include <stdio.h>

unsigned int getMemAdr(char* fileName, char* varName);

int main() {
	unsigned int adr = getMemAdr("keler.X.production.map", "sysTick");
	printf("Address: %#06x\n", adr);
}

unsigned int getMemAdr(char* fileName, char* varName) {
	char cmd[150];
	sprintf(cmd, "awk \'/%s/ { if (i == 0) { print $1; ++i } }\' %s",
			varName, fileName);
	FILE* mapFile = popen(cmd, "r");
	unsigned int address;
	fscanf(mapFile, "%x", &address);
	pclose(mapFile);
	return address;
}
Gökçe Tağlıoğlu