全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2438
推到 Plurk!
推到 Facebook!

keil C51_V706 compiler在記憶體分配上有bug??

缺席
dominicx
一般會員


發表:6
回覆:10
積分:13
註冊:2007-05-07

發送簡訊給我
#1 引用回覆 回覆 發表時間:2009-08-12 12:01:58 IP:222.156.xxx.xxx 訂閱
環境
chip: Atmel at89c51snd1
comipiler : keil C51_V706

小弟我最近遇到一個很神奇的問題
我在一個.h檔內宣告了一個global variable,
例如:
global.h
[code cpp]
_DECL xdata int Temp _SET(_at_ (0x0000));
[/code]

然後以下的程式執行結果卻很奇怪

[code cpp]
void fun1(){
......
......
Temp = 8;
printf("Temp = %d\r\n", Temp);
}

void fun2(){
int i, j;
printf("Temp = %d\r\n", Temp);
.....
.....
}

void main(){
fun1();
fun2();
}
[/code]

執行出來的結果竟然是
Temp = 8
Temp = 0

小弟我的想法是可能是compiler上的bug
將Temp的記憶體區塊重複分配給其他變數(i or j)
造成被改寫為0

想聽聽其他高手的意見
不知道有沒有人也遇過類似的情況?
或許有什麼解決方法可以避免這種問題呢?
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#2 引用回覆 回覆 發表時間:2009-08-13 10:12:24 IP:114.32.xxx.xxx 訂閱
你好:

>_DECL xdata int Temp _SET(_at_ (0x0000));
1.我想將「Temp」自行宣告在0x0000的位址是不必要的!
請修改為如下,讓編譯器來決定變數的位址。
_DECL xdata int Temp;

2.xdata是用於外部記憶體,
你電路上有裝SRAM-如6264 or 62256嗎?
如果沒有那當然會讀到Temp=0,
請把xdata拿掉 -> _DECL int Temp;

>將Temp的記憶體區塊重複分配給其他變數(i or j)
>造成被改寫為0
3.int i,j是宣告為內部RAM,xdata int Temp是外部RAM,
彼此是互相獨立的。

8051外部記憶體與XDATA使用
http://delphi.ktop.com.tw/board.php?cid=173&fid=1167&tid=82206

阿信~
dominicx
一般會員


發表:6
回覆:10
積分:13
註冊:2007-05-07

發送簡訊給我
#3 引用回覆 回覆 發表時間:2009-08-17 23:00:46 IP:218.167.xxx.xxx 訂閱

===================引 用 阿信 文 章===================
你好:

>_DECL xdata int Temp _SET(_at_ (0x0000));
1.我想將「Temp」自行宣告在0x0000的位址是不必要的!
請修改為如下,讓編譯器來決定變數的位址。
_DECL xdata int Temp;

其中g32CurrentDirStartSector這個變數發生了這個現像

2.xdata是用於外部記憶體,
你電路上有裝SRAM-如6264 or 62256嗎?
如果沒有那當然會讀到Temp=0,
請把xdata拿掉 -> _DECL int Temp;

我電路上沒外加Extra的RAM
不過根據AT89C51SND1的spec,
我有額外的expand RAM, 2048 bytes可以使用
這部份應該是xdata吧

>將Temp的記憶體區塊重複分配給其他變數(i or j)
>造成被改寫為0
3.int i,j是宣告為內部RAM,xdata int Temp是外部RAM,
彼此是互相獨立的。

8051外部記憶體與XDATA使用
http://delphi.ktop.com.tw/board.php?cid=173&fid=1167&tid=82206

阿信~


[code cpp]
#define FAT16 1
#define FAT32 2

// Structure of Boot sector information
// 26 bytes
struct BOOTSECTOR
{
IntegerByte BytePerSector; //offset 11
UINT8 SectorPerCluster; //offset 13
IntegerByte ReservedSectors; //offset 14
UINT8 FATCopies; //offset 16
IntegerByte RootEntries; //offset 17
IntegerByte TotSec16; //offset 19
IntegerByte FATSize16; //offset 22
//IntegerByte SectorsPerTrack; //offset 24
LongByte TotSec32; //offset 32
LongByte FATSize32; //FAT32 Offset 36
LongByte RootCluster; //FAT32 Offset 44
IntegerByte FSInfoSector; //FAT32 Offset 48
};

// Structure of Boot sector information
// 49 bytes
struct BOOTSECTOR_FULL
{
IntegerByte BytePerSector ; //offset 0B
UINT8 SectorPerCluster ; //offset 0D
IntegerByte ReservedSectors ; //offset 0E
UINT8 FATCopies ; //offset 10
IntegerByte RootEntries ; //offset 11
IntegerByte TotSec16 ; //offset 13
UINT8 MediaDescriptor ; //offset 15
IntegerByte FATSize16 ; //offset 16
IntegerByte SectorsPerTrack ; //offset 18
IntegerByte Heads ; //offset 1A
LongByte HiddenSectors ; //offset 1C
LongByte TotSec32 ; //offset 20
UINT8 SerialNumber[4] ; //offset 27
UINT8 DriveNumber ; //offset 24
UINT8 VolumeLabel[11] ; //offset 2B
UINT8 FileSystemType[8] ; //offset 36
};

// Structure of entry start position
// 6bytes
struct FILE_POS
{
UINT32 lSector;
UINT16 wOffset;
};


//Structure of Directory entry information
// 15bytes
struct FILE_ENTRY
{
UINT8 Attribute ; //offset 0B, File attribute
LongByte StartCluster ; //offset 1A, Start Custer
LongByte FileSize ; //offset 1C, File size in bytes
UINT32 Sector; //not entry data, the start sector of entry #defect#UINT32#
UINT16 Offset; //not entry data, the start offset of entry
};

// Structure of Directory entry information
// 28 bytes
struct FILE_ENTRY_FULL {
char FileName[8] ; //offset 00, File Name
UINT8 FileExtension[3] ; //offset 08, File Name extension
UINT8 Attribute ; //offset 0B, File attribute
IntegerByte CreateTime ; //offset 0E, Create Time
IntegerByte CreateDate ; //offset 10, Create Date
LongByte StartCluster ; //offset 1A, Start Custer
LongByte FileSize ; //offset 1E, File size in bytes
UINT32 Sector; // offset 22, not entry data, the start sector of entry #defect#UINT32#
UINT16 Offset; // offset 24, not entry data, the start offset of entry
};

//----Not used---------------
struct FAT_FORMAT_POINTER {
UINT8 MBSStart ;
UINT8 NotInUseStart ;
UINT8 PBSStart ;
UINT8 FAT1Start ;
UINT8 FAT2Start ;
UINT8 RootStart ;
UINT8 DataStart ;
};
struct FAT_MBS_PARAMS {
UINT8 BootID ;
UINT8 StartHead ;
UINT8 StartSector ;
UINT8 StartCylinder ;
UINT8 SystemID ;
UINT8 EndHead ;
UINT8 EndSector ;
UINT8 EndCylinder ;
LongByte StartLogicalSector ;
LongByte ParationSize ;
};
struct FAT_PBS_PARAMS {
UINT8 SectorPerCluster ;
IntegerByte RootEntries ;
//UINT16 RootEntries;
LongByte TotalSectors ;
IntegerByte FATSize16 ;
IntegerByte SectorsPerTrack ;
IntegerByte Heads ;
LongByte HiddenSectors ;
UINT8 FileSystemType ;
} ;
//----end not used-----------
typedef struct
{
U8 key;
U8 asc;
U8 ascq;
} s_scsi_sense;
_DECL bit rx_bank;
_DECL bit gState; //FredYu_EnableUSBFunction_00
_DECL xdata UINT8 DMA_BUF[512] _SET(_at_ (0x0000));
_DECL xdata struct FILE_POS gFileList[1] _SET(_at_ (0x0200));
_DECL xdata struct FILE_ENTRY_FULL fl[1] _SET(_at_ (0x0206));
_DECL xdata struct BOOTSECTOR gBootSector _SET(_at_ (0x0224));
_DECL xdata UINT32 g32RootStartSector _SET(_at_ (0x023E));
_DECL xdata UINT16 g16RootSectors _SET(_at_ (0x0242));
_DECL xdata UINT16 g16FirstFATStartSector _SET(_at_ (0x244));
_DECL xdata UINT16 g16SecondFATStartSector _SET(_at_(0x246));
_DECL xdata UINT16 g16DataStartSector _SET(_at_(0x248));
_DECL xdata UINT32 g32DataClusters _SET(_at_ (0x24A));
_DECL xdata UINT32 g32CurrentDirStartSector _SET(_at_(0x24E));
_DECL xdata UINT32 g32FatEOC _SET(_at_(0x252));
_DECL xdata UINT8 gDiskFileSystemType _SET(_at_(0x256));
_DECL xdata UINT32 g32SectorNo _SET(_at_(0x257));
_DECL xdata UINT32 gl_ptr_mem _SET(_at_(0x25B));
_DECL xdata UINT8 gl_mem_tick _SET(_at_(0x25F));
_DECL xdata UINT32 gSD_RCA _SET(_at_(0x260));
_DECL xdata UINT32 mmc_mem_size _SET(_at_(0x264));
_DECL bit gl_mem_failure;
_DECL xdata UINT32 g32CurrentDirSector _SET(_at_(0x268));
_DECL xdata UINT16 g16RealOffset _SET(_at_(0x26C));
_DECL xdata UINT8 g8Temp _SET(_at_(0x26E));
_DECL xdata int CurrentFile _SET(_at_(0x26F));
//Add-for-USB-FredYu_01
_DECL xdata USB_CTRL_COMMAND UsbCtrlCmd _SET(_at_(0x275));
_DECL UINT32 xdata gCBWDataLen _SET(_at_(0x27D));
_DECL bit gbUsbReadError;
_DECL bit gbUsbWriteError;
_DECL idata UINT8 *G_pucCtrlDataPointer;
_DECL UFICMDBlock xdata gCmdBlock _SET(_at_(0x281));
_DECL UINT32 xdata gOrgCBWDataLen _SET(_at_(0x29C));
_DECL UINT8 xdata gCBWFlags _SET(_at_(0x2A0));
_DECL UINT32 xdata gCBWTag _SET(_at_(0x2A1));
_DECL UINT8 xdata gActiveCard _SET(_at_(0x2A5));
_DECL U8 xdata dCBWTag[4] _SET(_at_(0x2A6));
_DECL xdata U32 g_scsi_data_remaining _SET(_at_(0x2AA));
_DECL xdata U8 g_scsi_status _SET(_at_(0x2AE));
_DECL xdata s_scsi_sense g_scsi_sense;
static idata UINT8 ep_status[3];
//Add-for-USB-FredYu_01 -
[/code]
編輯記錄
dominicx 重新編輯於 2009-08-17 23:06:49, 註解 無‧
dominicx 重新編輯於 2009-08-17 23:08:37, 註解 無‧
阿信
版主


發表:111
回覆:983
積分:813
註冊:2005-03-10

發送簡訊給我
#4 引用回覆 回覆 發表時間:2009-08-18 13:04:01 IP:114.32.xxx.xxx 訂閱

其中g32CurrentDirStartSector這個變數發生了這個現像

我在想,既然程式很長,那可能是:
1.其它地方修改了該變數,如中斷或其它副程式。
2.因為指定位址,導致變數在記憶體中是重疊的。
3.寫出如下的判斷式:
if (g32CurrentDirStartSector=0) {
//執行某些程式



我電路上沒外加Extra的RAM
不過根據AT89C51SND1的spec,
我有額外的expand RAM, 2048 bytes可以使用
這部份應該是xdata吧

看了spec,是xdata沒錯!
系統時間:2024-05-02 13:38:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!