问题描述
我有一个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 (将#修改为@)