标签: keil

为什么编译器没有警告我一个空的if语句?

我正在使用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条件下的一小部分是问题的根源.

为什么编译器不把它当作警告并通知我?

c if-statement compiler-warnings keil

26
推荐指数
1
解决办法
2万
查看次数

如何将变量放在内存中的给定绝对地址(使用GCC)

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是否具有类似的变量属性?

c variables gcc arm keil

25
推荐指数
5
解决办法
5万
查看次数

Keil vs GCC for ARM7?

Keil与GCC的ARM7开发相比如何?我正在为一个中等规模的项目选择hw顾问,有些人使用keil,有些人使用gcc.我想知道参与任何一个选项的陷阱......

embedded gcc arm keil arm7

14
推荐指数
2
解决办法
1万
查看次数

Cortex M3的Bootloader

我正在使用mbed的LPC 1768板(带有cortex M3 cpu),我正在尝试在这里实现一些功能,主要是从SD卡升级用户应用程序,我正在编写两个程序,首先是一个bootloader/nano-kernel,以及一个用户应用程序(helloworld将开始):

  • 在0x00地址运行的Bootloader/nano-kernel,它会进行一些检查并最终获取SD卡上的二进制文件
  • Bootloader/nano-kernel会将这个二进制文件复制到地址0x9000(以后可能需要更改,但bootloader/nano-kernel不使用此空间,所以应该没问题)
  • Bootloader跳转到0x9000 + 4的用户应用程序

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)都是正确的并且位于正确的位置.

我相信我在这里遗漏了一些东西,是否有任何我应该关注的低级代码?我已经在线阅读了文档的音调,从我发现的例子中,他们以与我相同的方式跳转到用户代码...非常感谢任何帮助.

c arm bootloader keil cortex-m

11
推荐指数
1
解决办法
1万
查看次数

ARM Cortex-M编译器的差异

我准备在STM32处理器上为我的项目使用C开发Cortex-M内核的一些固件,并在网上搜索我发现了很多不同的编译器:Keil,IAR,Linaro,Yagarto和ARM嵌入式GNU工具处理器.

我想知道,这些可能影响我选择的编译器之间存在哪些功能差异?例如,作为发烧友,我不需要供应商的支持或帮助,目前对代码大小的限制是可以的.此外,易用性并不是主要关注点,因为我喜欢学习(目前我已经配置了Keil Lite和Eclipse以及GNU ARM配置和工作).

生成的代码在这些编译器之间的大小/速度方面是如此不同?有比较表吗?(我在网上发现只有陈旧的信息)

gcc arm stm32 keil cortex-m

11
推荐指数
2
解决办法
5930
查看次数

如何确定嵌入式系统中的最大堆栈使用量?

当我给Keil编译器提供"--callgraph"选项时,它会静态计算出我的"最大堆栈使用率".

唉,今天它给了我一个"最大堆栈使用= 284字节+未知(没有堆栈大小的函数......)"消息,以及"没有堆栈信息的函数"列表.

奈杰尔琼斯说,递归在嵌入式系统中是一个非常糟糕的主意("计算你的堆栈大小" 2009),所以我一直小心不要在这段代码中做任何相互递归的函数.

另外,我确保我的中断处理程序都没有重新启用中断,直到它们最终从中断返回指令,所以我不需要担心重入中断处理程序.

如果没有递归或重入中断处理程序,它应该能够静态地确定最大堆栈使用情况.(所以大多数答案 如何确定最大堆栈使用量? 不适用).我的理解是,处理"--callgraph"选项的软件首先找到每个中断处理程序在没有被更高优先级的中断打断时的最大堆栈深度,以及main()函数的最大堆栈深度.不打断 然后它将它们全部加起来以找到总(最坏情况)最大堆栈深度.当main()后台任务在被最低优先级中断中断时处于最大深度时会发生这种情况,并且当该中断被下一个最低优先级中断中断时,该中断处于其最大深度,依此类推.

我怀疑处理--callgraph的软件对"无堆栈信息的功能"列表中的小型汇编语言函数感到困惑.该--callgraph文档似乎暗示我需要手动计算(或作出保守估计),他们多少堆栈使用-他们是很短的,所以这应该是简单的-然后"使用汇编语言框架指令用于描述代码如何使用堆栈的代码." 其中之一是初始启动代码,在跳转到main()之前将堆栈重置为零 - 因此,实际上,这会消耗零堆栈.另一个是"故障"中断处理程序,它锁定在一个无限循环中,直到我循环上电 - 假设这消耗零堆栈是安全的.

我正在使用Keil uVision V4.20.03.0来编译LM3S1968 ARM Cortex-M3的代码.

那么我如何使用"框架指令"来告诉处理"--callgraph"的软件这些函数使用了多少堆栈?或者是否有更好的方法来确定最大堆栈使用量?

(有关针对gcc编译器的几乎相同的问题,请参阅如何使用gcc确定嵌入式系统中的最大堆栈使用量.)

embedded code-analysis static-analysis keil

10
推荐指数
1
解决办法
5846
查看次数

如何抑制第三方源文件中的警告?

我熟悉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 c++ eclipse gcc keil

10
推荐指数
1
解决办法
1001
查看次数

将uint8_t与数字进行比较

也许我不正确理解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.

c c++ keil

10
推荐指数
1
解决办法
6775
查看次数

在Keil uVision 5中,如何在逐步调试调试器时保持文本编辑器行的最新状态?

我正在使用uVision 5的教育/评估版本.在调试项目时,反汇编窗口标记下一个将在边距中用黄色箭头执行的语句.

当达到该行代码时,每行文本编辑器中的边距将变为绿色.这似乎意味着文本编辑器知道当前正在执行的代码行.

但是,文本编辑器不会更新,除非它丢失并重新获得焦点,因此很难跟踪调试时我所处的代码行.我必须按F11,然后单击文本编辑器中的滚动条,看到下一行变为绿色,以便能够跟踪我所处的位置.

我知道有一些方法可以使文本编辑器与当前正在执行的代码保持同步,因为我已经在同学的计算机上看了几个项目,每次按F11都会更新编辑器(下一个声明) ).但是,他和我都不知道如何启用此功能.

ide debugging arm keil

9
推荐指数
1
解决办法
168
查看次数

STM32板的RAM,堆和堆栈存储器

我正在开发一个需要至少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)

我需要在第二个代码示例中使用堆栈和堆的大小来匹配第一个代码示例中的大小,这样我就不会因为没有可用内存而陷入硬故障异常循环.为什么增加堆大小会使我的项目变得更糟?这意味着当我增加堆大小时,它甚至不会出现? …

c++ embedded stm32 keil

8
推荐指数
1
解决办法
2万
查看次数