gpt4 book ai didi

c - eeprom 空间中的变量地址作为 C 中的函数参数

转载 作者:太空宇宙 更新时间:2023-11-04 03:37:11 25 4
gpt4 key购买 nike

我在 PIC24f16ka102 和 xc16 编译器中遇到一个简单而快速的 C 问题。

我想将变量引用传递给我的函数。变量在eeprom空间:

   int __attribute__ ((space(eedata))) eeData; // Variable located in EEPROM,declared as a global variable.

通过这个序列,我可以在 eeprom 内存中保存一些数据:

unsigned int offset;
// Set up NVMCON to erase one word of data EEPROM
NVMCON = 0x4004;
// Set up a pointer to the EEPROM location to be erased
TBLPAG = __builtin_tblpage(&eeData2); // Initialize EE Data page pointer
testDebug = TBLPAG;

offset = __builtin_tbloffset(&eeData); // Initizlize lower word of address
__builtin_tblwtl(offset, 0x9876); // Write EEPROM data to write latch
asm volatile ("disi #5"); // Disable Interrupts For 5 Instructions
__builtin_write_NVM(); // Issue Unlock Sequence & Start Write Cycle
while(NVMCONbits.WR == 1);

通过这种方式,我将值 0x9876 写入 eeprom 的前 16 位。但我需要将它作为 &eeData

我想写我自己的函数:

void eeprom_writeWord(unsigned int __attribute__ ((space(eedata)))  addresOfMyEEpromVariable, unsigned int value)
{
unsigned int offset;
// Set up NVMCON to erase one word of data EEPROM
NVMCON = 0x4004;
// Set up a pointer to the EEPROM location to be erased
TBLPAG = __builtin_tblpage(&addresOfMyEEpromVariable); // Initialize EE Data page pointer
offset = __builtin_tbloffset(&addresOfMyEEpromVariable); // Initizlize lower word of address
__builtin_tblwtl(offset, value); // Write EEPROM data to write latch
asm volatile ("disi #5"); // Disable Interrupts For 5 Instructions
__builtin_write_NVM(); // Issue Unlock Sequence & Start Write Cycle
while(NVMCONbits.WR == 1);
}

但是如何将我的地址作为函数参数传递,以便我的函数可以看到它仍然是 eeprom 空间中的地址?它不能只是地址,因为如果是这样我会出错。 __内置函数需要具有某些属性的地址,它是 eeprom 内存。

如何将带有属性的 eeprom 地址传递给我的函数?请帮忙

编辑:

谢谢你的建议,但我仍然得到同样的错误:

    error: Argument to __builtin_tbloffset() is not the address
of an object in a code, psv, or eedata section;

函数 __builtin_tbloffset 需要一个 eeprom 存储器的地址,而不仅仅是某个地址。如果我使用整个序列而不是在一个函数中(我指的是我第一篇文章中的序列),它会很好地工作。

现在我按照你说的做了:

void eeprom_writeWord(unsigned int *addresOfMyEEpromVariable, unsigned int value)
{
//write word
// Set up NVMCON to write one word of data EEPROM
NVMCON = 0x4004;
// Set up a pointer to the EEPROM location to be written
TBLPAG = __builtin_tblpage(*addresOfMyEEpromVariable);
unsigned int offset = __builtin_tbloffset(*addresOfMyEEpromVariable);
// Write Data Value To Holding Latch
__builtin_tblwtl(offset, 0x9999);
// Disable Interrupts For 5 Instructions
asm volatile ("disi #5");
// Issue Unlock Sequence & Start Write Cycle
__builtin_write_NVM();
while(NVMCONbits.WR == 1);
}

甚至没有“*”符号:

void eeprom_writeWord(unsigned int *addresOfMyEEpromVariable, unsigned int value)
{
//write word
// Set up NVMCON to write one word of data EEPROM
NVMCON = 0x4004;
// Set up a pointer to the EEPROM location to be written
TBLPAG = __builtin_tblpage(addresOfMyEEpromVariable);
unsigned int offset = __builtin_tbloffset(addresOfMyEEpromVariable);
// Write Data Value To Holding Latch
__builtin_tblwtl(offset, 0x9999);
// Disable Interrupts For 5 Instructions
asm volatile ("disi #5");
// Issue Unlock Sequence & Start Write Cycle
__builtin_write_NVM();
while(NVMCONbits.WR == 1);
}

结果还是一样。 __builtin_tblpage 和其他 __builtin_(...) 函数是 xc16 编译器内置的函数。

最佳答案

可能内置例程可以处理硬编码地址(如您的第一个示例 - 编译器/链接器知道 eeData 所在的位置),但不能处理变量地址。

您可以尝试两件事:

(1) 使 eeprom_writeWord 成为内联函数(这样编译器可以再次对地址进行硬编码)。请注意,如果这可行,它仍然可能会在“复杂”情况下失败,例如存储在索引数组中的地址。

(2) 查看为工作示例中的内置例程生成的汇编程序代码,并根据需要重写它们(使用 C 或内联汇编程序)。这些例程只有几条指令长。例如__builtin_tblpage 只是剥离地址的上半部分 - 在 C 中通过屏蔽和/或右移很容易完成的事情。

关于c - eeprom 空间中的变量地址作为 C 中的函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31698696/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com