如何处理与硬件更改相关的特定情况

时间:2013-10-05 21:59:33

标签: c linux linux-device-driver embedded-linux fpga

我正在维护与FPGA器件相关的生产代码.FPGA上的早期寄存器为32位,对这些寄存器的读/写工作正常。但硬件已更改,FPGA器件和最新版FPGA器件也已更改我们在读取和写入FPGA寄存器时遇到了麻烦。在一些R& D之后,我们发现FPGA寄存器不再是32位,现在是31位寄存器,并且已经被FPGA设备供应商所声称。

因此需要更改小代码。早些时候我们检查寄存器的地址是否为4字节对齐(因为寄存器为32位)现在我们必须检查地址是31位对齐。所以我们要检查一下 如果设置了地址的最高位(这意味着它不是有效的31位)。 我想我们在这里很好。

现在第二种情况对我来说有点棘手。 如果多个寄存器的读/写将超过0x7fff-fffc(这是31位方案中的最大地址)边界,则必须小心处理请求。

多个寄存器的读取和写入需要长度作为参数,这只是要读取或写入的寄存器的数量。

例如,如果读取以0x7fff-fff8开始,并且读取的长度为5.那么实际上,我们只能读取2个寄存器(即0x7fff-fff8和0x7fff-fffc)。

现在可以有人建议我使用某种伪代码来处理这种情况

有人认为如下

while(lenght>1)
{
  if(!(address<<(lenght*31) <= 0x7fff-fffc))
   {
     length--;
   }
}

我知道这不够好,但我可以使用相同的内容。

修改

我想出了一条可满足我要求的代码

 int count;

 Index_addr=addr;

 while(Index_add <= 7ffffffc)
 {   
  /*Wanted to move register address to next register address,each register is 31 bit   wide and are at consecutive location. like 0x0,0x4 and 0x8 etc.*/

  Index_add=addr<<1; // Guess I am doing wrong here ,would anyone correct it.

  count++;

 }

 length=count;

2 个答案:

答案 0 :(得分:1)

我不确定我是否正确地解释了给定的场景。但是这里有一个镜头:

// Assuming "address" starts 4-byte aligned and is just defined as an integer
unsigned uint32_t address; // (Assuming 32-bit unsigned longs)

while ( length > 0 )    // length is in bytes
{
    // READ 4-byte value at "address"
    // Mask the read value with 0x7FFFFFFF since there are 31 valid bits

    // 32 bits (4 bytes) have been read
    if ( (--length > 0) && (address < 0x7ffffffc) )
        address += 4;
}

答案 1 :(得分:1)

根本问题似乎是程序没有正确处理FPGA寄存器 数据封装将有所帮助,而不是将31位FPGA寄存器视为存储器位置,它们应该被抽象化。

FPGA应被视为寄存器的向量(一维数组) N FPGA寄存器的向量应该由register index在0x0000到 N-1 的范围内寻址。
FPGA寄存器在base addr处进行存储器映射 所以memory address = 4 * FPGA register index + base addr

应通过读写程序封装对FPGA寄存器的访问:

int read_fpga_reg(int reg_index, uint32_t *reg_valp)
{

    if (reg_index < 0 || reg_index >= MAX_REG_INDEX)
        return -1;  /*  error return */

    *reg_valp = *(uint32_t *)(reg_index << 2 + fpga_base_addr);
    return 0;
}

只要正确定义了MAX_REG_INDEX和fpga_base_addr,此代码就永远不会生成无效的内存访问。