- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试修复 Fujitsu MB90F543 成熟程序中发现的错误。该程序至今运行了近10年,但人们发现,在某些特殊情况下,它一开始就未能做到两件事。其中之一至关重要。
低电平和高电平初始化(端口、引脚、外设、IRQ 处理程序)后,通过 SPI 从 EEPROM 读取配置数据,并且状态 LED 会打开一段时间(为了打开它们,数据会通过 SPI 发送到 LED 驱动器) )。当这些特殊情况首先发生且仅第一个函数调用时,仅少数 EEPROM 读取失败,另外一些本应点亮的 LED 也不会亮起。
该程序用 C 语言编写,并使用 Softune v30L32 编译。令人惊讶的是,在低级硬件 init 中添加单个 __asm("NOP ") 就足以使程序在上述情况下按预期工作。在优化设置中关闭“控制指针别名优化”就足够了。在不同的地方添加几行代码也有帮助。
我比较了带有和不带有 __asm("NOP ") 的版本以及带有上述优化器设置的编译程序的(DIFFed)ASM 列表,它们看起来都很好。
Softune编译器多年来在编译期间打印的唯一警告如下:
*** W1372L: The section is placed outside the RAM area or the I/O area (IOXTND)
我确实意识到这是一个相当普遍的问题,但也许有更大视野的人能够指出可能的原因。
您知道什么可能会导致这种奇怪的行为吗?如何定位bug并修复?
在初始化期间,使用了一些长(约20ms)延迟循环。尽管它们从大约 2ms 增加,但它们没有帮助,但硬件初始化函数的任何行中的单个 NOP 甚至在函数之前或之后都有帮助。
两个等待循环都有效。我已经用示波器检查过了。 (我添加了 LED 在之前打开和之后关闭)。
我通过将 SPI 时钟从 1MHz 减慢至 500kHz 来检查时序假设。它不会改变任何东西。减慢至 250kHz 会使看门狗重置,因为代码的某些部分执行时间太长(>25ms)。
还有一件事。我观察到,在任何源文件中添加局部变量有时会使问题消失或重新出现。初始化未初始化的局部变量也是如此。在任何文件中添加几行额外的代码可以帮助或揭示问题。
void main(void)
{
watchdog_init();
// waiting for power supply to stabilize
wait; // about 45ms
hardware_init();
clear_watchdog();
application_init();
clear_watchdog();
wait; // about 20ms
test_LED();
{...}
}
void hardware_init (void)
{
__asm("NOP"); // how it comes it helps? - it may be in any line of the function
io_init(); // ports initialization
clk_init();
timer_init();
adc_init();
spi_init();
LED_init();
spi_start();
key_driver_init();
can_init();
irq_init(); // set IRQ priorities and global IRQ enable
}
最佳答案
可能是很多事情之一,但我想到了两件事。
时机。
也许等待时间不够长,电源无法稳定,并且并非所有内容都与时钟同步。 NOP 让一切恢复同步。
对齐。
也许 NOP 会让您的指令在硬件期望的 32 或 64 位边界上对齐。 (我们过去经常在大型机汇编器上这样做,因为 IO 操作通常期望事情在双字边界上)。
关于c - 为什么 NOP/几行额外的代码/指针别名优化有帮助? [富士通MB90F543 MCU C代码],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28686099/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!