OpenOCD 在断点处退出
OpenOCD exit on breakpoint
我正在 STM32F042 上开发应用程序。
我从 makefile 驱动所有内容,包括我的单元测试。
我使用 OpenOCD 和 ST-LINK 来刷新目标。
我的单元测试 运行 在主机和目标上。
主机单元测试驱动程序 returns 来自 main() 的 0 表示成功,非零表示失败,因此 makefile 知道测试是否通过。
makefile 闪烁并开始对目标进行测试,但不知道它们是成功还是失败。
嵌入式测试应用程序打开红色 LED 表示失败,绿色表示通过,所以我知道——现在我想自动执行此步骤。
我想在代码中设置两个断点,一个在失败处理程序中,一个在 main 的末尾,并告诉 OpenOCD 在遇到一个或另一个断点时以零或非零状态退出。
所以我的问题归结为两个具体问题:
要设置断点,我需要知道特定代码行的 PC 值。我如何从 arm-gcc 工具链中获取该值?
我可以将 OpenOCD 配置为在特定断点处退出并具有特定状态吗?
这是我最终得到的结果。对于每个目标单元测试,我启动一个 OpenOCD 服务器并使用 gdb 连接到它。 gdb 运行s 一个脚本,设置了两个断点,一个成功,一个失败。如果它遇到任何一个断点,它就会关闭 OCD 服务器并退出,并带有一个将成功和失败传达给 shell 的代码。为了 运行 在主机上进行相同的测试,我只是将它们编译为常规可执行文件。
生成文件:
# target unit test binaries
foo_tests.elf bar_tests.elf baz_tests.elf bop_tests.elf: unit_test_runner.ao
# disable optimization for target unit test driver to avoid optimizing
# away functions that serve as breakpoint labels
unit_test_runner.ao: CFLAGS += -O0 -g
# link target unit test binaries for semihosting
%_tests.elf: ARM_LDLIBS += -specs=rdimon.specs -lrdimon
# host unit test binaries
foo_tests bar_time_tests baz_tests bop_tests: unit_test_runner.o
# run target unit test binaries through gdb and OpenOCD; redirecting stderr
# leaves printf output from `assert()' clearly visible on the console
%.tut: %.elf
openocd -f interface/stlink-v2-1.cfg -f target/stm32f0x.cfg 2> $@.log &
gdb-multiarc -batch-silent -x tut.gdb $< 2> $@-gdb.log
# run host binary
%.run: %
./$*
tests: foo_tests.run bar_time_tests.run baz_tests.run bop_tests.run \
foo_tests.tut bar_time_tests.tut baz_tests.tut bop_tests.tut
tut.gdb:
target remote localhost:3333
monitor arm semihosting enable # let assert()'s printf() through
monitor reset halt
load
monitor reset init
break success # set breakpoint on function `sucess()'
commands # on hitting this bp, execute the following:
monitor shutdown # shutdown OpenOCD server
quit 0 # exit GDB with success code
end
break failure # set breakpoint on function `sucess()'
commands
monitor shutdown
quit 1 # exit GDB with failure code
end
continue
unit_test_runner.c:
#include <stdlib.h>
/* These two functions serve as labels where gdb can place
breakpoints. */
void success() {}
void failure() {}
/* Implementation detail for `assert()' macro */
void assertion_failure(const char *file,
int line,
const char *function,
const char *expression)
{
printf("assertion failure in %s:%d (%s): `%s'\n",
file, line, function, expression);
failure();
exit(1);
}
/* This function is necessary for ARM semihosting */
extern void initialise_monitor_handles(void);
int main(int argc, char* argv[])
{
#ifdef __arm__
initialise_monitor_handles();
#endif
tests(); /* client code implements this function */
success();
return 0;
}
我正在 STM32F042 上开发应用程序。 我从 makefile 驱动所有内容,包括我的单元测试。 我使用 OpenOCD 和 ST-LINK 来刷新目标。 我的单元测试 运行 在主机和目标上。 主机单元测试驱动程序 returns 来自 main() 的 0 表示成功,非零表示失败,因此 makefile 知道测试是否通过。 makefile 闪烁并开始对目标进行测试,但不知道它们是成功还是失败。 嵌入式测试应用程序打开红色 LED 表示失败,绿色表示通过,所以我知道——现在我想自动执行此步骤。
我想在代码中设置两个断点,一个在失败处理程序中,一个在 main 的末尾,并告诉 OpenOCD 在遇到一个或另一个断点时以零或非零状态退出。
所以我的问题归结为两个具体问题:
要设置断点,我需要知道特定代码行的 PC 值。我如何从 arm-gcc 工具链中获取该值?
我可以将 OpenOCD 配置为在特定断点处退出并具有特定状态吗?
这是我最终得到的结果。对于每个目标单元测试,我启动一个 OpenOCD 服务器并使用 gdb 连接到它。 gdb 运行s 一个脚本,设置了两个断点,一个成功,一个失败。如果它遇到任何一个断点,它就会关闭 OCD 服务器并退出,并带有一个将成功和失败传达给 shell 的代码。为了 运行 在主机上进行相同的测试,我只是将它们编译为常规可执行文件。
生成文件:
# target unit test binaries
foo_tests.elf bar_tests.elf baz_tests.elf bop_tests.elf: unit_test_runner.ao
# disable optimization for target unit test driver to avoid optimizing
# away functions that serve as breakpoint labels
unit_test_runner.ao: CFLAGS += -O0 -g
# link target unit test binaries for semihosting
%_tests.elf: ARM_LDLIBS += -specs=rdimon.specs -lrdimon
# host unit test binaries
foo_tests bar_time_tests baz_tests bop_tests: unit_test_runner.o
# run target unit test binaries through gdb and OpenOCD; redirecting stderr
# leaves printf output from `assert()' clearly visible on the console
%.tut: %.elf
openocd -f interface/stlink-v2-1.cfg -f target/stm32f0x.cfg 2> $@.log &
gdb-multiarc -batch-silent -x tut.gdb $< 2> $@-gdb.log
# run host binary
%.run: %
./$*
tests: foo_tests.run bar_time_tests.run baz_tests.run bop_tests.run \
foo_tests.tut bar_time_tests.tut baz_tests.tut bop_tests.tut
tut.gdb:
target remote localhost:3333
monitor arm semihosting enable # let assert()'s printf() through
monitor reset halt
load
monitor reset init
break success # set breakpoint on function `sucess()'
commands # on hitting this bp, execute the following:
monitor shutdown # shutdown OpenOCD server
quit 0 # exit GDB with success code
end
break failure # set breakpoint on function `sucess()'
commands
monitor shutdown
quit 1 # exit GDB with failure code
end
continue
unit_test_runner.c:
#include <stdlib.h>
/* These two functions serve as labels where gdb can place
breakpoints. */
void success() {}
void failure() {}
/* Implementation detail for `assert()' macro */
void assertion_failure(const char *file,
int line,
const char *function,
const char *expression)
{
printf("assertion failure in %s:%d (%s): `%s'\n",
file, line, function, expression);
failure();
exit(1);
}
/* This function is necessary for ARM semihosting */
extern void initialise_monitor_handles(void);
int main(int argc, char* argv[])
{
#ifdef __arm__
initialise_monitor_handles();
#endif
tests(); /* client code implements this function */
success();
return 0;
}