如何安全地传递最终传递给内联汇编的IO地址?

问题描述

我有一个AVR项目的简短摘要:

DELETE FROM dist
  WHERE hexbin1,hexbin2,source NOT IN (
    SELECT hexbin1,source FROM dist INNER JOIN (
      SELECT hexbin1 as h1,hexbin2 as h2,min(distance) as m
      FROM dist GROUP BY hexbin1,hexbin2)
    ON hexbin1==h1 AND hexbin2==h2 AND distance==m);

此块后面的想法是在短时间内(T1H_NOOP)启用特定的引脚(实际的物理微处理器引脚),然后将其关闭。上面的代码实际上可以完美地工作。

但是,在上面的代码中,确切的引脚是硬编码的:PORTB,引脚0( uint8_t high = _BV(0); uint8_t low = ~high; uint8_t port_value = 0; asm volatile ( "in %0,%1 \n\t" "or %0,%3 \n\t" "out %1,%0 \n\t" T1H_NOOP "and %0,%2 \n\t" "out %1,%0 \n\t" T1L_NOOP : "=r" (port_value) : "I" (_SFR_IO_ADDR(PORTB)),"r" (low),"r" (high)); )。我想要的是传递这样的地址:

_BV(0)

只要我留在C代码中,那实际上是可行的。

struct IO_ADDR {
    volatile uint8_t *port;
    uint8_t pin
}

当我这么说的时候,我的意思是我已经通过模拟器运行了这个程序,并且看到销钉按预期方式工作了,再加上我将该代码段与上面的程序集配对并在硬件上运行它。因此,很明显, struct IO_ADDR addr = { .port = &PORTB,.bit = 0 }; latch(&addr); void latch(struct IO_ADDR *addr) { if (addr->bit >= 8) return; *(addr->port) &= ~(_BV(addr->bit)); _delay_us(50); } 在寻址引脚本身,而不是指针。很好。

但是,当我这样做时,出现组装错误:

*(addr->port) &= ...

此错误:

        asm volatile (
            "in %0,%1   \n\t"
            "or %0,%3   \n\t"
            "out %1,%0  \n\t"
            T1H_NOOP
            "and %0,%2   \n\t"
            "out %1,%0   \n\t"
            T1L_NOOP
        : "=r" (port_value)
        : "I" (_SFR_IO_ADDR(*(addr->port))),"r" (high));

如果我用/nix/store/j31yaksw2dh82by2lgz1ysgh494cz6j2-src/neopixels.c: In function 'write_value': /nix/store/j31yaksw2dh82by2lgz1ysgh494cz6j2-src/neopixels.c:29:9: warning: asm operand 1 probably doesn't match constraints 29 | asm volatile ( | ^~~ /nix/store/j31yaksw2dh82by2lgz1ysgh494cz6j2-src/neopixels.c:29:9: error: impossible constraint in 'asm' 替换addr-> port参数,也会发生这种情况。

_SFR_IO_ADDR(addr->port)对此进行了预处理:

SFR_IO_ADDR(*(addr->port))

: "I" ( # 38 "src/neopixels.c" 3 4 (((uint16_t) &( # 38 "src/neopixels.c" *(addr->port) # 38 "src/neopixels.c" 3 4 )) - 0x20) # 38 "src/neopixels.c" ) 的情况下,最终组装应该是这样的,地址在此特定硬件上为0x24(并且忽略编译器选择的确切寄存器):

PORTB

要将该特定IO地址传递给我的汇编代码,我需要做什么?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)