Tag: 嵌入式

我应该使堆栈段大或堆段大吗?

我正在为内存非常有限的微处理器编程设计,我必须在不同的function中使用“大量”内存。 我不能有一个大的堆栈段,堆段,数据段,我必须选择哪个做大,哪个做小。 我总共大约32KB, 我使用大约20KB的文本段,其余为12KB。 我需要一个4KB的缓冲区来传递给不同的函数(SPI Flash扇区大小)。 应该在哪里初始化那个大缓冲区? 所以我的选择是: 1)如果我在函数的开头声明缓冲区,则需要使堆栈变大 spiflash_read(…) { u8 buffer[4096]; // allocated on stack syscall_read_spi(buffer,…) } 2)动态分配,堆需要变大 spiflash_read(…) { u8 *buffer = (u8*) malloc(4096); // allocated in heap syscall_read_spi(buffer,…) } 3)静态分配,巨大的下方不能在“SPI库”之外使用。 static u8 buffer[4096]; // allocated in data section. spiflash_read(…) { syscall_read_spi(buffer,…) } 我的问题是哪种方法是实现这种设计的最佳方式? 有人可以解释一下推理吗?

擦除外部FLASH

我正在使用MCF51EM256飞思卡尔微控制器,我有一些问题要将数据存储在外部闪存中以使其持久化。 我需要存储这个结构: typedef struct { ui64_s Ea_ps; ui64_s Ea_ng; ui64_s Er_q1; ui64_s Er_q2; ui64_s Er_q3; ui64_s Er_q4; uint16 F_ea; uint16 F_er; }Ws_EnergyAcc64; 哪里: typedef union{ uint64 v; uint32 p[2]; } ui64_s; 和: typedef unsigned long long int uint64; typedef unsigned long int uint32; typedef unsigned short int uint16; 为此,我实现了这个function: void Save_Flash_WsEnergyAcc(long addr, Ws_EnergyAcc64* Acc) { […]

C – 无法访问地址处的内存

调试GDB时告诉我以下错误: 0x800c99ed00000001 如果在调试时调用ConvertByteArrayToFloat时放置断点,则会产生错误。 但该程序没有问题退出并给我一个好的结果? 我的主要档案: #include “Local.h” int main(void) { if(HandleReceivedMessages() == OP_COMPLETED){ printf(“Main Completed \n” ); } else { printf(“Main Failed \n”); } return 0; } Local.h #ifndef LOCAL_H_ #define LOCAL_H_ #include “Common.h” T_OP_STATUS HandleReceivedMessages(void); #endif Local.c #include “Handler.h” #include “Local.h” uint8_t message[] = {0x86, 0x9a, 0xa0, 0x00, 0x00, 0x01, 0x01, 0x07, 0x00, 0x10, […]

如何从嵌入式C中的GSM调制解调器读取消息?

我目前正在“物联网”领域开展我的迷你项目。 我选择使用GSM模块设计无线公告板。 我将项目分为两个模块。 首先,Arduino-LED板接口完美完成。 二,GSM-Arduino接口。 基本上,消息/ SMS将从移动电话发送到GSM模块,然后我们必须使用Arduino从GSM模块读取该消息。 我在这里面临一个问题。 该消息正被发送到GSM调制解调器,但我无法读取它。 我尝试编写不同的代码,但它不起作用。 消息未显示。 这是我试过的代码片段。 `#include SoftwareSerial.h SoftwareSerial SIM900A(2,3);// RX | TX // Connect the SIM900A TX to Arduino pin 2 RX // Connect the SIM900A RX to Arduino pin 3 TX. void setup() { SIM900A.begin(9600); // Setting the baud rate of GSM Module Serial.begin(9600); // Setting the […]

如何使用内联汇编写入闪存?

我正在使用带有PIC18F87J11的 MPLAB C18编译器,我正在尝试使用内联汇编将一些值保存到闪存中,这是C和汇编代码的组合。 看起来我可以正确地写入和读取闪存,但是一旦我重新启动PIC然后尝试读取我之前从特定地址保存的内容,我就得不到相同的值。 我将0x09保存到0xB22A地址。 就像我说的,如果我保存值然后立即读取它,一切都正确,但重置PIC后我得到0x00 。 我不是永久保存到闪存或这里真的发生了什么? 这是我的代码: 擦除内存行 _asm MOVLW 0x00 MOVWF TBLPTRU,BANKED MOVLW 0xB2 MOVWF TBLPTRH,BANKED MOVLW 0x2A MOVWF TBLPTRL,BANKED _endasm EECON1bits.FREE = 1; INTCONbits.GIE = 0; _asm MOVLW 0x55 MOVWF EECON2,BANKED MOVLW 0xAA MOVWF EECON2,BANKED _endasm EECON1bits.WR = 1; INTCONbits.GIE = 1; 写入闪存 _asm MOVLW 0x00 MOVWF TBLPTRU,BANKED MOVLW 0xB2 MOVWF […]

PID反馈和位置控制器,带直流电机/编码器

我很难让PID反馈和定位同时运行。 我计算RPM的想法是: 启动定时器并使用中断计数编码器脉冲。 使用一些简单的数学转换为RPM。 重置变量使用并重新开始。 我可以计算RPM,但之后我只能在计算后调用我的PID控制器(不管我想等多长时间才能获得良好的分辨率。)这会导致代码非常混乱。 是否有更简单的方法或我缺少的东西? 关于我的应用的信息:我正在使用直流电机/双磁编码器对Atmel ATmega328P进行编程,每转约600个脉冲(在齿轮箱之后)。 我想调用GoToTarget(#)并让电机在更新PID参数时转到该位置。 此外,它必须双向进行。

printf支持MSP430微控制器

我正在使用不同的C编译器升级经过全面测试的德州仪器(TI)MSP430微控制器C程序,从Quadravox,AQ430开发工具改为VisualGDB C编译器。 该程序使用VisualGDB编译零错误和零警告。 中断服务程序,定时器,UART控制等等都似乎正在工作。 但是,sprintf的某些用途不起作用。 例如: unsigned int duration; float msec; msec = (float)duration; msec = msec / 125.0; sprintf(glb_response,”break: %3.1f msec”,msec); 返回: break: %3.1f msec 这是预期的: break: 12.5 msec 我已经了解了以下内容(来自维基百科): 编译器选项–printf_support = [full | 最小| nofloat]允许您使用较小的,function受限的printf / sprintf变体,并在构建时进行选择。 有效值为: full:支持所有格式说明符。 这是默认值。 nofloat:不包括对打印浮点值的支持。 支持除%f,%g,%G,%e和%E之外的所有格式说明符。 minimal:支持打印整数,字符或字符串值,不带宽度或精度标记。 具体而言,仅支持%%,%d,%o,%c,%s和%x格式说明符 我需要对printf的全力支持。 我知道我的产品上的MSP430将支持这一点,因为这个C程序已服务多年。 我的问题是我无法弄清楚1)如果VisualGDB有将printf支持设置为full的方法,2)如果是这样,在哪里设置它。 任何和所有的评论和答案将不胜感激。

如何防止ARM编译器5 armcc内联汇编程序中的LDM / STM指令扩展?

我正在尝试使用ARM编译器5 armcc编译的.c文件中的内联汇编中的STM / LDM指令生成AXI总线突发访问。 inline void STMIA2(uint32_t addr, uint32_t w0, uint32_t w1) { __asm { STMIA addr!, { w0, w1 } } } 但ARM编译器armcc用户指南第7.18段说:“所有LDM和STM指令都扩展为LDR和STR指令序列,效果相同。但是,编译器可能会在优化期间将单独的指令重新组合成LDM或STM。 “ 这就是实践中真正发生的事情,LDM / STM在某些情况下会扩展为一组LDR / STR,这些指令的顺序是任意的。 这会影响性能,因为我们使用的HW针对突发处理进行了优化。 这也打破了function正确性,因为我们使用的HW考虑了单词序列并忽略了偏移(但编译器认为改变指令的顺序是安全的)。 要解决这个问题,可以使用嵌入式汇编程序而不是内联汇编程序,但这会导致额外的函数调用 – 返回影响性能的因素。 所以我想知道是否有办法在不损失性能的情况下正确生成LDM / STM? 我们能够在GCC中做到这一点,但没有找到任何armcc的解决方案。 目标CPU:Cortex M0 +(ARMv6-M)。 编辑:从设备都是片上设备,大多数都是非内存设备。 对于支持突发访问区域的非内存从站的每个寄存器都保留了地址空间(例如[0x10000..0x10100]),我不完全确定为什么,也许CPU或总线不支持固定(非增量) )地址。 HW忽略该区域内的偏移。 例如,完整请求可以是16字节,并且完整请求的第一个字是第一个字写入的(即使偏移是非零)。

对于任何真实数据集,数据压缩比的最小可能值是什么

我正在为嵌入式硬件压缩器编写ZLIB就像使用deflate算法压缩给定输入流一样。 在进一步说明之前,我想解释数据压缩率。 数据压缩比定义为未压缩大小和压缩大小之间的比率。 压缩比通常大于1。 这意味着压缩数据通常小于未压缩数据,这是压缩的全部要点。 但情况并非总是如此。 例如,使用ZLIB库和某些Linux机器上生成的伪随机数据,压缩比大致为0.996。 这意味着压缩成10000字节的9960字节。 我知道ZLIB通过使用类型0块来处理这种情况,它只返回带有大约5字节头的原始未压缩数据,因此它只能提供5字节的开销直到64KB的数据块。 这是这个问题的智能解决方案但由于某些原因我不能在我的API中使用它。 我必须提前提供额外的安全空间来处理这种情况。 现在,如果我知道尽可能少的已知数据压缩率,我将很容易计算出我必须提供的额外空间。 否则为了安全起见,我必须提供超过所需的额外空间,这在嵌入式系统中至关重要。 在计算数据压缩率时,我不关心页眉,页脚,极小的数据集和系统特定的细节,因为我单独处理它。 我特别感兴趣的是,是否存在最小尺寸为1K的真实数据集,并且使用deflate算法可以提供小于0.99压缩比。 在这种情况下,计算将是: 压缩比=未压缩的大小/(使用deflate压缩的大小,不包括页眉,页脚和系统特定的开销) 请提供反馈。 任何帮助,将不胜感激。 如果可以提供对这样的数据集的引用,那将是很好的。 编辑: @MSalters评论指出硬件压缩器没有正确地遵循deflate规范,这可能是微代码中的一个错误。

快速串口从处理写入Arduino

我需要一些帮助来加速写入串口。 我发现了一些类似的问题,但没有涉及处理语言或Java,所以我希望有人可以帮我解决这个问题。 编辑 正如John在下面指出的那样,看起来串行的速度还不够快,无法以我想要的速度发送这么多数据。 有谁知道其他可用的arduino接口? 结束编辑 我正在使用arduino来控制我连接的400个RGB LED的网格。 为了向arduino发送命令,我在Processing中编写了一个小程序来操作代表LED的大型数组。 然后我尝试通过串行发送800字节的数据,每隔20分钟以115200波特率向arduino发送更新网格。 每20ms调用的处理代码是: noStroke(); int dataPos = 0; // position in LED data array byte[] dataLedGrid = new byte[400*2]; // array for bytes to send for(int j=0; j<LEDS_TALL; j++) { for(int i=0; i<LEDS_WIDE; i++) { int pos = j*20+i; int r = ledGrid[LEDS_WIDE-i-1][LEDS_TALL-j-1][0], g = ledGrid[LEDS_WIDE-i-1][LEDS_TALL-j-1][1] ,b […]