2016-01-20 77 views
-1

我试图模拟需要将数据复制到外设,裸机,无OS的系统。将地址存储为值并稍后将其用于指针

该约定规定复制函数是一个C函数,它将外设的地址作为写入某个寄存器的8位地址。外设在内部使用。不过,我在模拟C中的事情,并测试所有功能我在做类似如下的MWE:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc,char *argv[]){ 

    //stack-array to copy 
    char array[4] = {3,32,-12,99}; 
    //naive emulation of the peripheral memory space 
    char peripheral_array[4]; 

    //herein lies the address send as a value 
    char address_reg = (char*)(peripheral_array); 

    //assume this is the peripheral side 
    //set ptr to the address of the peripheral_array 
    char *ptr = (char*) address_reg; 
    memcpy((void*)ptr,array,sizeof(char)*4); 

    return EXIT_SUCCESS; 
} 

我得到segmentation fault

  • 这里有什么问题?

  • 如何将数组的指针作为值存储并发送,将其作为地址重新写入数组并执行memcpy

+0

更换

char address_reg = (char*)(peripheral_array); 

我想,如果它是代表外围地址空间'char'更改为'无符号char'。 –

+0

另外:你不需要用'(void *)ptr'强制转换为'void *','memcpy'的'void *'类型的意思是它接受任何指针类型。 –

+1

代码不会编译。 address_reg与地址相同吗? – Ctx

回答

3

您想在具有32位或64位地址空间的环境中使用8位地址空间来模拟某些内容,因此您会遇到一些困难,因为它不会轻松转换。具体来说,这行char address_reg = (char*)(peripheral_array)将一个宽指针转换为一个8位值,并丢失大部分指针,这意味着您将无法将其转换回来。

的解决方案是,以进一步推动你的仿真和模拟您的目的地的8位的地址空间:

  • 的typedef一个8位指针(清洁器):typedef uint8_t ptr8;
  • 声明你的8位目标地址空间:uint8_t my_destination_memory[256]
  • 定义你自己的memcpy复制到这个地址空间:
    void my_memcpy(ptr8 addr_dest, const void * src, int len) { 
        memcpy(my_destination_memory + addr_dest, src, len); 
    } 
    

这种方式可以面议在类型为ptr8(或任何你命名的)的8位指针周围,然后复制到它没有问题。
请注意,我假定您的源地址空间不重要,因为您可以模拟它。您应该能够以相同的方式模拟16位甚至24位地址空间(如果您需要32位,您可以使用本机指针)。

+0

将追求这一个。 –

1

为什么把它存入char?可以保存地址为char的变量是char* - 在两台机器上 - 您的PC和嵌入式MCU!

在你的MCU上sizeof(char*)可能是1或2,在你的电脑上它可能是4或8;

如果要编写平台兼容代码,请使用char*

如果您想进一步模拟机器地址空间,那么您必须提供自己的standard-lib函数实现。以便他们将机器地址空间中的地址解释为指向您定义的某些内存数组的索引。

然而,更好的方法主要是提供一些硬件抽象层(HAL),它封装了系统特定的任务,而不是在业务逻辑中使用机器specifica。

0

首先,请注意,在char类型中存储整数值是危险的,因为它是一种具有实现定义的签名类型。它不应该用于任何东西,但字符串。

而是始终使用int8_t(带符号)或uint8_t(无符号)。


问题的原因是,char(或int8_t对于这个问题)是不是大到足以容纳一个地址。

然而,在stdint.h这是保证足够大,包含一个地址。

只需使用

uintptr_t address_reg = (uintptr_t)peripheral_array; 
相关问题