代码之家  ›  专栏  ›  技术社区  ›  old_timer

是否有人在Xcore基于汇编程序的LED闪烁器上取得了成功?

  •  2
  • old_timer  · 技术社区  · 14 年前

    我喜欢 http://www.xmos.com 但想对正在发生的事情有一个较低层次的了解。基本上是装配工。我正在尝试解决一些简单的问题,比如LED闪光灯,设置LED,计数为N,清除LED,计数为N,永远循环。

    当然,我可以反汇编一个10行XC程序,但是如果你尝试过,你会发现在每个程序中都有很多膨胀,支持编译器输出的是什么位,实际设置GPIO的是什么位?

    编辑:

    XC代码

    #include 
    out port bled = PORT_BUTTONLED ;
    int main () {
       bled <: 0b0011 ;
       while (1)
         ;
       return 0;
    }
    

    要生成的命令

    source SetEnv
    xcc bob.xc -target=XC-1A -o bob.xe
    xsim --max-cycles 2000 --vcd-tracing "-o bob.vcd -ports -cycles -threads -timers -instructions -functions" bob.xe
    

    编辑5

    这是答案

    .globl _start
    _start:
        ldc r0,4
        ldc r2,8
        ldc r3,16
        ldc r1, 100
    notmain:
        sub r1,r1,1
        bt r1, notmain
    
        ldap r11,constants
        set  dp,r11
    
        ldc  r3, 0x6
        setc res[r3], 0x8
        setc res[r3], 0xf
    
        ldw r3,dp[0x0]
        setc res[r3],0x8
        ldc r1,0x6
        setclk res[r3],r1
    
    top:
    
        ldc    r0, 0x8
        out    res[r3], r0
        bl delay
    
        ldc    r0, 0x4
        out    res[r3], r0
        bl delay
    
        ldc    r0, 0x2
        out    res[r3], r0
        bl delay
    
        ldc    r0, 0x1
        out    res[r3], r0
        bl delay
    
        ldc    r0, 0x2
        out    res[r3], r0
        bl delay
    
        ldc    r0, 0x4
        out    res[r3], r0
        bl delay
    
        bu top
    
    constants:
    .word 0x00040200
    
    delay:
        ldc r2, 1000
    da:
        ldc r1, 10000
    db:
        sub r1,r1,1
        bt r1, db
        sub r2,r2,1
        bt r2, da
        retsp 0x0
    
    

    建造和装载上述装配机M.S:

    xcc m.s -target=XC-1A -nostartfiles -o m.xe
    xrun m.xe
    

    如果你能消除延迟,你就可以模拟并查看芯片的焊盘/引脚,这样你就能在一个合理长度的模拟中看到一些事情发生。

    xsim --max-cycles 2000 --vcd-tracing "-o m.vcd -ports -cycles -threads -timers -instructions -functions -pads" m.xe
    

    但是gtkwave不喜欢这种语法,所以要用gtkwave查看m.vcd文件,我必须编辑.vcd文件,然后

    from:
    $var wire 1 paa10 0:X0D61 $end
    to:
    $var wire 1 paa10 X0D61 $end
    

    基本上删除所有PAA变量定义行的0:

    使用上面的汇编程序X0D14、X0D15、X0D19、X0D20,可以通过它们的文档查看连接。

    这个幻数来自一个include文件:

    #define XS1_PORT_4C 0x40200
    

    编辑6

    谢谢你跳进来帮忙。我在回顾我已经走了多远,我不理解0x6和setclk的东西,我将不得不再问一个问题或更深入地挖掘。下面的代码确实开始晃动端口,但是xcore似乎执行了线程交换并挂起,因此它仍然不是我希望的简单程序。我明白这不是一个简单的核心(这就是为什么我想在这个层次上理解它,以充分利用它)。

    .globl _start
    _start:
        ldc r1, 100
    notmain:
        sub r1,r1,1
        bt r1, notmain
    
        ldc r3,0x4020
        shl r3,r3,4
        setc res[r3],0x8
    top:
        ldc    r0, 0x8
        out    res[r3], r0
        ldc    r0, 0x4
        out    res[r3], r0
        ldc    r0, 0x2
        out    res[r3], r0
        ldc    r0, 0x1
        out    res[r3], r0
        ldc    r0, 0x2
        out    res[r3], r0
        ldc    r0, 0x4
        out    res[r3], r0
        bu top
    
    
    3 回复  |  直到 14 年前
        1
  •  1
  •   Andrew    14 年前

    把集会贴上去,我会帮你看的。听起来很有趣。

    编辑:

       0x000100ac: 00 f0 45 58: ldw (lru6)      r1, dp[0x5]
       0x000100b0: d2 a6:       mkmsk (rus)     r0, 0x2
       0x000100b2: c1 ae:       out (r2r)       res[r1], r0
    

    我想这就是你要找的部分。我需要找到一个XMOS参考手册,但是根据主控制流程,这必须是访问出血通道的部分。要确认它,您可以在XC代码中添加一个标志,并在while循环中翻转LED。这应该将对上述内容的类似访问添加到程序集输出中。

    根据指令集引用(pg 123),out的第一个操作数是端口,第二个操作数是数据。这个 dp[0x5] 操作数看起来像是将端口的句柄从某个全局库中取出,然后使用它查找关联的资源。

    一位知情人士建议我,你试着用-o2来清除代码。如果你试图跟踪正在发生的事情,我会跳过所有初始化代码,这在大多数平台上总是一团糟。如果你只关注主标签和下一个步骤之间的行( DoException )然后,您应该看到一个可管理的代码量,它映射到您编写的部分上。较小的 btxx 标签是控件构造(while循环、if语句)的跳转目标。

        2
  •  1
  •   Henk    14 年前

    假设您对机器进行原始编程,您需要获取端口ID,您可以在工具中的xs1.h include文件中找到该端口ID。

    将端口ID加载到寄存器中,然后使用setc打开端口,使用out将值驱动到端口。不需要设置端口的时钟。假设您使用的是端口0x1000,下面的序列应该会给您一个非常短的脉冲。使用计时器获得更长的脉冲;如果使用循环,实际时间取决于处理器的时钟速度和线程数。计时器给你实时的。

    ldc r0, 1
    shl r0, r0, 16 // Makes 0x10000
    setc res[r0], 8
    ldc r1, 1
    out res[r0], r1
    ldc r1, 0
    out res[r0], r1
    

    希望这有帮助…

        3
  •  1
  •   Henk    14 年前

    抱歉,是的,您需要打开参考时钟块并启动它。所以你需要我添加到程序中的三行。

    格式为0x00000Y06的资源是时钟块Y,因此0x6表示时钟块0。SETC 8打开它,SETC 0XF设置时钟运行。当时钟为“开”而不是“运行”时(在SETC 8和SETC 0XF之间),您可以执行诸如更改除法器设置之类的操作。取消两行的注释,给时钟一个分隔符,这将减慢输出速度。

    .globl _start
    _start:
        ldc r1, 100
    notmain:
        sub r1,r1,1
        bt r1, notmain
    
        ldc r3,0x4020
        shl r3,r3,4
        setc res[r3],0x8
        ldc r1,0x6
        setc res[r1],0x8
        // ldc  r2, 8
        // setd res[r1], r2
        setc res[r1],0xf
    
    top:
        ldc    r0, 0x8
        out    res[r3], r0
        ldc    r0, 0x4
        out    res[r3], r0
        ldc    r0, 0x2
        out    res[r3], r0
        ldc    r0, 0x1
        out    res[r3], r0
        ldc    r0, 0x2
        out    res[r3], r0
        ldc    r0, 0x4
        out    res[r3], r0
        bu top
    

    希望这有帮助。

    亨克

    PS-SETC值列表见第172页 XS1 Architecture Manual .