编译器如何知道C中的指针地址是端口映射还是RAM?

时间:2017-08-23 11:14:24

标签: c io

我知道端口映射的IO是通过CPU指令访问的,而内存(和内存映射寄存器)是通过加载/存储CPU指令(类似于内存)访问的。但是,使用C代码中的指针,编译器如何知道地址是否是端口映射IO寄存器或内存然后插入正确的CPU指令?

示例:

function grab_page($site){
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_TIMEOUT, 40);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_URL, $site);
ob_start();
return curl_exec($ch);
ob_end_clean();
curl_close ($ch);

2 个答案:

答案 0 :(得分:4)

如果您有非内存映射的I / O,那么您将无法从C访问它,就好像它是内存一样。

您必须使用某些特定于平台的技巧来获取正确的I / O指令。这很痛苦,可能是现代硬件似乎更倾向于内存映射I / O的一个原因。

具有端口映射I / O的平台的C编译器必须包含它,例如参见旧版Turbo C ++ for DOS中的inp()函数。

答案 1 :(得分:-1)

两个步骤:

  1. 为目标硬件安装正确的工具链。
  2. 使用提供的头文件以及所有必要的正确圆顶定义
  3. 例如,如果您想编写ARM STM uC裸机gcc编译器 - 使用arm-none-eabi-gcc和工具。使用STM& amp;提供的标题CMSIS头文件。 ARM(如果您选择"现成的#34;工具链,通常会包括它们)

    示例声明和定义(仅适用于ADC1):

    #define FLASH_BASE            ((uint32_t)0x08000000U) /*!< FLASH base address in the alias region */
    #define CCMDATARAM_BASE       ((uint32_t)0x10000000U) /*!< CCM(core coupled memory) data RAM base address in the alias region     */
    #define SRAM_BASE             ((uint32_t)0x20000000U) /*!< SRAM base address in the alias region */
    #define PERIPH_BASE           ((uint32_t)0x40000000U) /*!< Peripheral base address in the alias region */
    #define SRAM_BB_BASE          ((uint32_t)0x22000000U) /*!< SRAM base address in the bit-band region */
    #define PERIPH_BB_BASE        ((uint32_t)0x42000000U) /*!< Peripheral base address in the bit-band region */
    #define AHB3PERIPH_BASE       (PERIPH_BASE + 0x10000000U)
    #define ADC1_BASE             (AHB3PERIPH_BASE + 0x00000000U)
    
    #define ADC1                ((ADC_TypeDef *) ADC1_BASE)
    
    #ifdef __cplusplus
      #define   __I     volatile             /*!< Defines 'read only' permissions */
    #else
      #define   __I     volatile const       /*!< Defines 'read only' permissions */
    #endif
    #define     __O     volatile             /*!< Defines 'write only' permissions */
    #define     __IO    volatile             /*!< Defines 'read / write' permissions */
    
    /* following defines should be used for structure members */
    #define     __IM     volatile const      /*! Defines 'read only' structure member permissions */
    #define     __OM     volatile            /*! Defines 'write only' structure member permissions */
    #define     __IOM    volatile            /*! Defines 'read / write' structure member permissions */
    typedef struct
    {
      __IO uint32_t ISR;              /*!< ADC Interrupt and Status Register,                 Address offset: 0x00 */
      __IO uint32_t IER;              /*!< ADC Interrupt Enable Register,                     Address offset: 0x04 */
      __IO uint32_t CR;               /*!< ADC control register,                              Address offset: 0x08 */
      __IO uint32_t CFGR;             /*!< ADC Configuration register,                        Address offset: 0x0C */
      uint32_t      RESERVED0;        /*!< Reserved, 0x010                                                         */
      __IO uint32_t SMPR1;            /*!< ADC sample time register 1,                        Address offset: 0x14 */
      __IO uint32_t SMPR2;            /*!< ADC sample time register 2,                        Address offset: 0x18 */
      uint32_t      RESERVED1;        /*!< Reserved, 0x01C                                                         */
      __IO uint32_t TR1;              /*!< ADC watchdog threshold register 1,                 Address offset: 0x20 */
      __IO uint32_t TR2;              /*!< ADC watchdog threshold register 2,                 Address offset: 0x24 */
      __IO uint32_t TR3;              /*!< ADC watchdog threshold register 3,                 Address offset: 0x28 */
      uint32_t      RESERVED2;        /*!< Reserved, 0x02C                                                         */
      __IO uint32_t SQR1;             /*!< ADC regular sequence register 1,                   Address offset: 0x30 */
      __IO uint32_t SQR2;             /*!< ADC regular sequence register 2,                   Address offset: 0x34 */
      __IO uint32_t SQR3;             /*!< ADC regular sequence register 3,                   Address offset: 0x38 */
      __IO uint32_t SQR4;             /*!< ADC regular sequence register 4,                   Address offset: 0x3C */
      __IO uint32_t DR;               /*!< ADC regular data register,                         Address offset: 0x40 */
      uint32_t      RESERVED3;        /*!< Reserved, 0x044                                                         */
      uint32_t      RESERVED4;        /*!< Reserved, 0x048                                                         */
      __IO uint32_t JSQR;             /*!< ADC injected sequence register,                    Address offset: 0x4C */
      uint32_t      RESERVED5[4];     /*!< Reserved, 0x050 - 0x05C                                                 */
      __IO uint32_t OFR1;             /*!< ADC offset register 1,                             Address offset: 0x60 */
      __IO uint32_t OFR2;             /*!< ADC offset register 2,                             Address offset: 0x64 */
      __IO uint32_t OFR3;             /*!< ADC offset register 3,                             Address offset: 0x68 */
      __IO uint32_t OFR4;             /*!< ADC offset register 4,                             Address offset: 0x6C */
      uint32_t      RESERVED6[4];     /*!< Reserved, 0x070 - 0x07C                                                 */
      __IO uint32_t JDR1;             /*!< ADC injected data register 1,                      Address offset: 0x80 */
      __IO uint32_t JDR2;             /*!< ADC injected data register 2,                      Address offset: 0x84 */
      __IO uint32_t JDR3;             /*!< ADC injected data register 3,                      Address offset: 0x88 */
      __IO uint32_t JDR4;             /*!< ADC injected data register 4,                      Address offset: 0x8C */
      uint32_t      RESERVED7[4];     /*!< Reserved, 0x090 - 0x09C                                                 */
      __IO uint32_t AWD2CR;           /*!< ADC  Analog Watchdog 2 Configuration Register,     Address offset: 0xA0 */
      __IO uint32_t AWD3CR;           /*!< ADC  Analog Watchdog 3 Configuration Register,     Address offset: 0xA4 */
      uint32_t      RESERVED8;        /*!< Reserved, 0x0A8                                                         */
      uint32_t      RESERVED9;        /*!< Reserved, 0x0AC                                                         */
      __IO uint32_t DIFSEL;           /*!< ADC  Differential Mode Selection Register,         Address offset: 0xB0 */
      __IO uint32_t CALFACT;          /*!< ADC  Calibration Factors,                          Address offset: 0xB4 */
    
    } ADC_TypeDef;
    

    并扩展为:((ADC_TypeDef *) ((((uint32_t)0x40000000U) + 0x10000000U) + 0x00000000U))

    不值得手动完成。