我正在使用Keil uVision v4.74并启用了"All Warnings"选项.
我写了以下故意代码:
if(condition matched)
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
当我重建我的项目时,我得到0个错误,0个警告.
但是,当我不小心写道:
if(condition matched);
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
我也有0个错误,0个警告.
我几乎不可能发现;if条件下的一小部分是问题的根源.
为什么编译器不把它当作警告并通知我?
RealView ARM C编译器支持使用变量属性将变量放在给定的内存地址at(address):
int var __attribute__((at(0x40001000)));
var = 4; // changes the memory located at 0x40001000
Run Code Online (Sandbox Code Playgroud)
GCC是否具有类似的变量属性?
Keil与GCC的ARM7开发相比如何?我正在为一个中等规模的项目选择hw顾问,有些人使用keil,有些人使用gcc.我想知道参与任何一个选项的陷阱......
我正在使用mbed的LPC 1768板(带有cortex M3 cpu),我正在尝试在这里实现一些功能,主要是从SD卡升级用户应用程序,我正在编写两个程序,首先是一个bootloader/nano-kernel,以及一个用户应用程序(helloworld将开始):
Sd卡很容易锻炼,我遇到了跳跃部分的问题.这是跳跃函数的代码.
void run(void) {
void (*user_code_entry)(void);
unsigned *p;
SCB->VTOR = (USER_FLASH_START & 0x1FFFFF80);
// Load contents of second word of user flash - the reset handler address
// in the applications vector table
p = (unsigned *)(USER_FLASH_START +4); // USER_FLASH_START is 0x9000
user_code_entry = (void (*)(void))p;
// Jump to user application
user_code_entry();
Run Code Online (Sandbox Code Playgroud)
}
所以我编译了(我使用Keil uvision4)用户应用程序将起始地址更改为0x9000.如果我编程我的电路板(使用flashmagictool),然后手动跳转(仍使用flashmagictool)到0x9004(0x9000 + 4),用户应用程序将运行,所以我相信编译工作正常,因此用户应用程序可以在0x9000运行.
但是,如果我运行bootloader/nano-kernel,这个没有跳转到用户应用程序,不幸的是因为我无法调试,我不知道发生了什么...我也试过不使用SD副本部分,所以我首先编程引导加载程序,基本上只是跳转到0x9004.然后我编写将位于0x9000的用户应用程序.如果我重启电路板,bootloader会运行,但不会跳转到用户应用程序.我检查了内存,似乎两个程序(bootloader + user-app)都是正确的并且位于正确的位置.
我相信我在这里遗漏了一些东西,是否有任何我应该关注的低级代码?我已经在线阅读了文档的音调,从我发现的例子中,他们以与我相同的方式跳转到用户代码...非常感谢任何帮助.
我准备在STM32处理器上为我的项目使用C开发Cortex-M内核的一些固件,并在网上搜索我发现了很多不同的编译器:Keil,IAR,Linaro,Yagarto和ARM嵌入式GNU工具处理器.
我想知道,这些可能影响我选择的编译器之间存在哪些功能差异?例如,作为发烧友,我不需要供应商的支持或帮助,目前对代码大小的限制是可以的.此外,易用性并不是主要关注点,因为我喜欢学习(目前我已经配置了Keil Lite和Eclipse以及GNU ARM配置和工作).
生成的代码在这些编译器之间的大小/速度方面是如此不同?有比较表吗?(我在网上发现只有陈旧的信息)
当我给Keil编译器提供"--callgraph"选项时,它会静态计算出我的"最大堆栈使用率".
唉,今天它给了我一个"最大堆栈使用= 284字节+未知(没有堆栈大小的函数......)"消息,以及"没有堆栈信息的函数"列表.
奈杰尔琼斯说,递归在嵌入式系统中是一个非常糟糕的主意("计算你的堆栈大小" 2009),所以我一直小心不要在这段代码中做任何相互递归的函数.
另外,我确保我的中断处理程序都没有重新启用中断,直到它们最终从中断返回指令,所以我不需要担心重入中断处理程序.
如果没有递归或重入中断处理程序,它应该能够静态地确定最大堆栈使用情况.(所以大多数答案 如何确定最大堆栈使用量? 不适用).我的理解是,处理"--callgraph"选项的软件首先找到每个中断处理程序在没有被更高优先级的中断打断时的最大堆栈深度,以及main()函数的最大堆栈深度.不打断 然后它将它们全部加起来以找到总(最坏情况)最大堆栈深度.当main()后台任务在被最低优先级中断中断时处于最大深度时会发生这种情况,并且当该中断被下一个最低优先级中断中断时,该中断处于其最大深度,依此类推.
我怀疑处理--callgraph的软件对"无堆栈信息的功能"列表中的小型汇编语言函数感到困惑.该--callgraph文档似乎暗示我需要手动计算(或作出保守估计),他们多少堆栈使用-他们是很短的,所以这应该是简单的-然后"使用汇编语言框架指令用于描述代码如何使用堆栈的代码." 其中之一是初始启动代码,在跳转到main()之前将堆栈重置为零 - 因此,实际上,这会消耗零堆栈.另一个是"故障"中断处理程序,它锁定在一个无限循环中,直到我循环上电 - 假设这消耗零堆栈是安全的.
我正在使用Keil uVision V4.20.03.0来编译LM3S1968 ARM Cortex-M3的代码.
那么我如何使用"框架指令"来告诉处理"--callgraph"的软件这些函数使用了多少堆栈?或者是否有更好的方法来确定最大堆栈使用量?
(有关针对gcc编译器的几乎相同的问题,请参阅如何使用gcc确定嵌入式系统中的最大堆栈使用量.)
我熟悉GCC和Keil的警告抑制pragma(它们不同,但用法几乎相同).对于第三方标题,我可以这样做:
#pragma push
#pragma suppress warning
#include "whatever.h"
#pragma pop
Run Code Online (Sandbox Code Playgroud)
但是,如何抑制来自第三方来源的警告?Eclipse + GCC和Keil都会生成它们.我提出的唯一解决方案是制作whapper .c文件,其中包含其他.c文件,这似乎是非常脏的技巧.
还有其他解决方案吗?
也许我不正确理解C++或者它是编译器的错误?
uint8_t a = 0x00;
uint8_t b = 0xFF;
if( a - b == 1 )
{
doNothing();
}
Run Code Online (Sandbox Code Playgroud)
doNothing未被调用(如预期的那样),因为(ab)的结果在比较操作中被隐式地转换为第二个操作数的类型.对于数字,它是签名int.好的.
if( a - b == (uint8_t)1 )
{
doNothing();
}
Run Code Online (Sandbox Code Playgroud)
doNothing STILL没有被调用,但现在我不明白它的原因!我已经明确地将数字转换为uint8!
if( (uint8_t)(a - b) == 1 )
{
doNothing();
}
Run Code Online (Sandbox Code Playgroud)
现在doNothing终于被召唤了,但为什么呢?如何减去两个uint8返回一个int?
编译器是用于ARM Cortex M3的uVision ARMCC.
我正在使用uVision 5的教育/评估版本.在调试项目时,反汇编窗口标记下一个将在边距中用黄色箭头执行的语句.
当达到该行代码时,每行文本编辑器中的边距将变为绿色.这似乎意味着文本编辑器知道当前正在执行的代码行.
但是,文本编辑器不会更新,除非它丢失并重新获得焦点,因此很难跟踪调试时我所处的代码行.我必须按F11,然后单击文本编辑器中的滚动条,看到下一行变为绿色,以便能够跟踪我所处的位置.
我知道有一些方法可以使文本编辑器与当前正在执行的代码保持同步,因为我已经在同学的计算机上看了几个项目,每次按F11都会更新编辑器(下一个声明) ).但是,他和我都不知道如何启用此功能.
我正在开发一个需要至少500 kB内存的项目.我有一个SDK,用这个代码定义堆栈和堆,它工作正常.
Stack_Size EQU 0x00004000
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00200000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
Run Code Online (Sandbox Code Playgroud)
但是,我正在尝试将相机和LCD屏幕功能集成到此SDK中,当我这样做时,至少会调出LCD屏幕的堆栈和堆的最高值如下所示.任何高于此值且LCD屏幕保持黑色且应用程序似乎不运行.
Stack_Size EQU 0x00004000
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00002B50
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
Run Code Online (Sandbox Code Playgroud)
我需要在第二个代码示例中使用堆栈和堆的大小来匹配第一个代码示例中的大小,这样我就不会因为没有可用内存而陷入硬故障异常循环.为什么增加堆大小会使我的项目变得更糟?这意味着当我增加堆大小时,它甚至不会出现? …