2

我正在关注Baking Pi,在 ARMv6 程序集中为 Raspberry Pi 构建一个非常基本的操作系统。我们已经从通过 GPIO 控制器打开 OK LED 到使用系统计时器使其闪​​烁,再到根据存储在.int值中的位图表示的模式使其闪烁。最后一个解决方案似乎不起作用。起初我以为我一定是错误地解决了问题,但无论我用这里提供的功能解决方案检查我的解决方案,我都看不出有什么明显的不同。

我屈服了,最后下载了实际的解决方案,编译并安装在我的 Pi 上。它表现出与我自己的解决方案相同的损坏行为。也就是说,LED 会亮起,但会一直亮着。我假设程序已经崩溃,或者and指令没有按照导师的要求做。

像这样的解决方案:

bitmap   .req r4
seq      .req r5
ldr bitmap,=pattern
ldr bitmap,[bitmap]
mov seq,#0         /* start at the zeroth bit */

loop$:
  mov r0,#16       /* set gpio pin 16: OK LED */
  mov r1,#1        /* bitmask starts with a 1 */
  lsl r1,seq       /* shift to the correct bit */
  and r1,bitmap    /* mask according to the pattern */
  bl SetGpio       /* set the LED state (r1 zero = off, non-zero = on) */
  bl Wait          /* wait for a short interval */
  add seq,#1       /* increment the sequence counter */
  and seq,#0b11111 /* reset seq to 0 if >= 32 */
  b loop$          /* loop forever */

.section .data

.align 2
pattern:
  .int 0b11111111101010100010001000101010

现在我知道WaitandSetGpio函数可以正常工作,因为上一课只是按设定的时间间隔闪烁 LED 灯,我是通过EOR在每次迭代loop$. 这里引入的唯一重要的新概念是表示 SOS 模式的位图。我对位图和位掩码很满意,因为我经常在高级语言中使用它们,所以我认为逻辑没问题,但还有其他问题,也许.int是存储/填充的方式?

上面的逻辑有什么问题吗?的合同SetGpio是:

  • r0 必须设置为 GPIO 引脚号,在本例中为 16
  • 如果 LED 应该打开,r1 必须设置为非零,否则设置为零以将其关闭
  • 返回值不重要

Wait函数如下所示:

/* Sleep for 500 milliseconds */
Wait:
  push {lr}
  ldr r0,=500
  bl SleepForDelay
  pop {pc}

编辑 | 实际上,我和导师的解决方案中的行为是:

  1. LED 会短暂亮起(我猜是一个点)
  2. LED 再次熄灭
  3. LED 亮起并一直亮着

我实际上认为第一次闪烁只是引导加载程序在运行,但如果我在程序早期故意引入崩溃,LED 根本就不会亮起。

4

1 回答 1

1

原来这与代码无关,实际上是 Raspberry Pi 上的配置设置。

/config.txt 需要kernel_old=1

于 2013-06-23T12:26:52.637 回答