Tag: 嵌入式

在为ARM7编译的C代码中,使用全局变量是增加还是降低性能?

在为ARM7嵌入式平台编译时,在C代码中使用大量全局变量是否会降低或提高性能? 代码库由多个C源代码文件组成,这些文件使用extern关键字引用彼此的全局变量。 来自不同源代码文件的不同函数指的是不同的全局变量。 一些变量是数组。 我正在使用的编译器是IAR的EW ARM kickstart版本(32kb)。

读取STM32 MCU的SPI数据寄存器的值

有很多类似的问题,但似乎都没有相同的问题。 我正在将STML4 MCU连接到6轴传感器(LSM6DS3)。 我已经成功地在I2C中实现了所有function,但是想要SPI的额外速度(以及DMA,如果我可以使这些第一步工作……)。 因此,对于第一步,我试图读取设备的WHO_AM_I寄存器( 0x0F ),该寄存器应以0x69回复。 这是代码: uint8_t who = 0; // Sanity check/debugging aid should get 0x5D who = 0x43 + 0x1A; // Set SS low GPIO_WritePin (GPIOB, LL_GPIO_PIN_7, GPIO_PIN_RESET); // while tx buffer is in use, wait while (!LL_SPI_IsActiveFlag_TXE(SPI1)); // Send READ command to the WHO_AM_I register (SPI1->DR) = 0x8F; // while […]

模式,以防止不断检查错误?

在C中,是否有一种模式可以不再检查调用其他函数的函数中的错误? 例如,如果函数foo()依次调用a(),b()和c(),则必须在继续之前检查每个函数的返回值。 如果a(),b()或c()也调用其他函数,这些函数也可能调用其他函数,这会留下一长串错误检查,可能出现相同的错误…… int16_t a(x_t x) {return DO_SOME_WORK(x);} int16_t b(y_t y) {return DO_OTHER_WORK(y);} int16_t c(z_t z) {return DO_MORE_WORk(z);} foo (x_t x, y_t y, z_t z) { int16_t err = 0; // I can handle errors returned by either: err = a(x)); if (err) return err; err = b(y); if (err) return err; err = c(z); […]

如何通过慢速CAN总线进行printf样式调试 – 在远程工具上使用常量字符串,而不是嵌入式系统

目前,在我的嵌入式系统(用C编码)中,我有很多调试辅助打印语句,当远程工具连接到可以向PC显示消息的系统时执行。 这些有助于理解一般系统状态,但由于消息通过慢速CAN总线,我相信它们可能会堵塞管道并导致其他问题,试图获取任何有用的数据。 它的基本要点是: 它就像一个printf,但最终采用特殊的消息格式,通过CAN总线从嵌入式系统发送到工具。 为此,我可以使用特殊的调试消息替换此通用打印消息,该消息向其发送唯一ID,后跟仅变量参数(即argc / argv)。 我想知道这是否是正确的方法,或者是否有一个我错过的魔法子弹,或者其他我没有想到的东西。 所以,我发现这个问题很适合我的目的: printf()使用字符串表“解码器环”调试库 但我没有限制使它像printf一样简单。 我可以在远程工具端维护一个字符串表(因为它是Windows可执行文件,因此不受代码大小限制)。 我是负责此代码的唯一负责人,并且希望在调试时尝试减轻代码大小以及CAN总线流量。 我现在的想法是这样的: printf(“[%d] User command: answer call\n”, (int)job); 这变成了 debug(dbgUSER_COMMAND_ANSWER_CALL, job); dbgUSER_COMMAND_ANSWER_CALL是可能的调试消息枚举的一部分 而遥远的一面有类似的东西 switch(messagetype) { case dbgUSER_COMMAND_ANSWER_CALL: /* retrieve an integer from the data portion of the message and put it into a variable */ printf(“[%d] User command: answer call\n”, (int)avariable); } 这是相对简单的,如果我的所有消息都采用相同的格式,那就太棒了。 […]

在C中等待中断的有效方法

我在树莓派上使用WiringPi。 有了它,我分配了一个稍后调用的中断函数。 我不确定在等待中断被呼叫时该怎么做。 示例使用(自旋锁?) for (;;)例如 int main() { // register interrupt wiringPiISR( 18, INT_EDGE_BOTH, &myInterrupt ); for (;;) { // really? } return 0; } 而且我注意到sleep也有效。 无论睡眠如何,都会调用中断 int main() { // register interrupt wiringPiISR( 18, INT_EDGE_BOTH, &myInterrupt ); for (;;) { sleep(1000000); } return 0; } 使用最少的资源保持程序运行的最佳做法是什么(比如这是用于背景恶魔)? 来自其他语言,我原以为for(;;)会占用资源。 我想知道该怎么做或指示做什么(线程等)。

PIC16F883 Led Blink

我需要对PIC16F883进行编程,以同时闪烁/点亮LED。 振荡器运行在3,2768,我正在使用TIMER0来帮助我计时。 现在,我有一个预分频器设置为1:256,所以我每50ms得到一个中断,并且我有一个由此计算的变量,以显示已经过了多少秒。 如果输入已更改,则当然会再次重置seconds变量。 这是我老师的作业: 如果输入为0(关闭):红色和绿色LED应同时打开15秒。 此后,绿色LED应完全关闭,红色LED应每隔五秒闪烁10分钟 如果输入为1(打开):红色LED应完全关闭,绿色LED应打开10分钟,之后应关闭。 我的计时器工作正常。 我测试过了。 该程序运行正常,并保持2个LED关闭15秒,然后关闭它,但我的红色LED不闪烁。 我一整天都坐在办公桌前拼命想找到代码中的错误。 印刷图片: 这是我的C代码。 我正在使用MPLab和HI-TECH C编译器:) #include //Variabler int B = 0; //Definerer variablen B, used as a flag int A = 0; //Definerer veriablen A, used as a flag int E = 0; int savedstatus = 1; //Definere variablen savedstatus used to check last […]

C如何计算没有浮点精度的百分比(perthousands)

如何计算从2个int值到表示百分比的int值的百分比(为了更准确度,数百个)? 背景/目的:使用没有FPU的处理器,浮点计算需要花费100倍的时间。 int x = 25; int y = 75; int resultPercentage; // desire is 250 which would mean 25.0 percent resultPercentage = (x/(x+y))*1000; // used 1000 instead of 100 for accuracy printf(“Result= “); printf(resultPercentage); 输出: 结果= 0 当我真正需要的是250.我不能使用任何浮点计算。 正常fpu计算的示例: int x = 25; int y = 75; int resultPercentage; // desire is 250 which […]

嵌入式C:注册访问

假设我们要写地址为0xc000 ,我们可以在C中定义一个宏: #define LCDCW1_ADDR 0xc000 #define READ_LCDCW1() (*(volatile uint32_t *)LCDCW1_ADDR) #define WRITE_LCDCW1(val) ((*(volatile uint32_t *)LCDCW1_ADDR) = (val)) 我的问题是,当使用任何微控制器时,请考虑一个示例MSP430,P1OUT寄存器地址为0x0021。 但是当我们使用P1OUT = 0xFFFF时; //它为P1OUT赋值0xFFFF。 我的问题是它是如何写入该地址的,例如在这种情况下为0x0021。 IDE是IAR。 我在头文件msp430g2553.h中找到了以下定义: #define P1OUT_ (0x0021u) /* Port 1 Output */ DEFC( P1OUT , P1OUT_) 我想它是定义地址,但其他宏写入或读取的位置。 任何人都可以解释P1OUT如何在该特定地址位置写入的流程? 另外请告诉我你在0x0021u中的含义是什么? 谢谢 到目前为止,我发现的细节是: 在msp430g2553.h中 #ifdef __IAR_SYSTEMS_ICC__ #include “in430.h” #pragma language=extended #define DEFC(name, address) __no_init volatile unsigned […]

声明指向const的指针或指向const的const指针作为forms参数

我最近对代码进行了一些调整,其中我不得不在函数中更改forms参数。 最初,参数类似于以下(注意,结构是之前的typedef): static MySpecialStructure my_special_structure; static unsigned char char_being_passed; // Passed to function elsewhere. static MySpecialStructure * p_my_special_structure; // Passed to function elsewhere. int myFunction (MySpecialStructure * p_structure, unsigned char useful_char) { … } 之所以进行更改,是因为我可以在编译时定义并初始化my_special_structure,而myFunction从未更改过它的值。 这导致了以下变化: static const MySpecialStructure my_special_structure; static unsigned char char_being_passed; // Passed to function elsewhere. static MySpecialStructure * p_my_special_structure; // Passed […]

指向ROM中的function

我有微控制器,我正在与他合作。 调试时,必须调用ROM中硬编码的函数。 技术参考显示了如何执行此操作: # define Device_cal (void(*)(void))0x3D7C80 和调用过程看起来像这样: (*Device_cal)() 我无法理解这里究竟发生了什么,所以我的问题是:它是如何工作的?