2016-01-20 75 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; 
相關問題