可以说我有一个代表十进制数字的ASCII字符: char digit; // between 0x30 ('0') and 0x39 ('9') inclusive 我想获得它代表的数值(0和9). 我知道两种可能的方法: 减法: uint8_t value = digit - '0'; 位和: uint8_t value = digit & 0x0f; 在编译的代码尺寸方面,哪一个是最有效的? 执行时间处理时间?能源消耗?因为答案可能是 特定于平台的,我对那种架构最感兴趣 在运行低功率应用程序的微控制器中可能会发现: Cortex-M,PIC,AVR,8051等.我自己的 noreflowl noreferrer">对Arduino Uno 似乎表明在AVR上没有太大的不同,但是 我仍然想听听其他架构. 奖励问题:是否可以称为"行业标准"?是 在这里选择正确的情况是必不可少的? 免责声明:这是对的后续讨论 来自arduino; stackexc
以下是关于 embedded 的编程技术问答
我想在嵌入式环境上使用c与模板一起使用,我想知道使用C ++编译器编译C程序的成本是多少? 我有兴趣知道是否有比C编译器生成的代码更多的代码. 请注意,由于该程序是C程序,期望毫无例外地调用C ++编译器. 谢谢 维森特 解决方案 假设两个编译器的质量等效,可能没有"成本".传统的反对意见是C ++更为复杂,因此C ++编译器更有可能中有错误. 实际上,这是一个过去的问题,而我倾向于将大部分嵌入式内容作为一种可怕的C/C ++混合动力车 - 利用更强大的打字和更容易的变量声明规则,不产生RTTI或例外处理开销.如果您要使用给定的编译器(GCC等)并将其从C ++模式切换,那么无论如何,您必须担心的是两种语言的常见. 其他解决方案 C ++编译器可能需要更长的时间来编译代码(因为它必须构建用于超载分辨率的数据结构,因此无法提前知道程序不使用过载),但是结果二进制应该非常相似. 实际上,一个重要的优化差异是C ++默认情况下遵循严格的别名规则,而
当ARM7嵌入式平台编译时,在C代码中使用大量全局变量会降低或提高性能吗? 代码库由多个C源代码文件组成,这些文件使用Extern关键字参考彼此的全局变量.来自不同源代码文件的不同函数是指不同的全局变量.一些变量是数组. 我正在使用的编译器是IAR的EW Arm Kickstart Edition(32KB). 解决方案 这将始终降低性能并增加程序大小与static变量.您的问题并未特别询问您要比较什么.我可以看到各种替代方案 与静态变量. 与按值传递的参数. 与传递的数组或结构指针中的值相对于值. 在这里,编译器可以保留带有A 全局基础地址的寄存器,然后将不同的变量加载带有偏移;例如ldr rN, [rX, #offset].也就是说,如果您很幸运. RISC CPU的设计,例如ARM支持负载/存储单元,该装置可以处理所有内存访问.通常,负载/存储指令能够采用[register + offset]表格.同样,所有RISC寄存器均为对称.意味着任
从我的阅读中,由于存在守护程序,因此DBUS性能应比其他消息IPC机制慢两倍. 在讨论使用哪种Linux IPC技术有人提到性能问题.您是否看到速度较慢的因素以外的性能问题?您是否看到了防止DBU在嵌入式系统中使用的问题? 我理解dbus是否用于小消息.如果需要传递大量数据,则解决方案之一是将数据放入共享内存或堆中,然后使用DBU进行通知.根据所考虑的SO讨论,其他IPC机制是:信号,匿名管,名为Pipes或FIFOS,SYSV消息队列,POSIX消息队列,SYSV共享内存,POSIX共享内存,SYSV Smaphores,POSIX Semaphores,Posix Smemaphores,Futex锁,File-file-file-file-file-使用MMAP,UNIX域插座,NetLink插座,网络插座,插入机制,保险丝子系统,D-BUS子系统的支持和匿名共享内存. 我应该提及另一个列出要求的问题(尽管它以apache为中心): 数据包/消息方向 能够
我正在为嵌入式Linux的C ++/QT项目工作,在该项目中,我们在更新用户界面中的图形时会不断地针对处理器的局限性进行"决斗".由于这些限制(尤其是在情况更糟的时候我们的情况),我尝试在可能的情况下始终优化代码,以及优化成本是否最低.我要进行的这样的优化之一是始终在要处理的情况下使用正确的整数值:qint8,qint16和qint32取决于我需要的值. 但前一段时间,我在某个地方阅读了,而不是尝试在可能的情况下使用最小的整数大小,而是应该始终更喜欢使用与处理器能力相关的整数值,也就是说,如果我的处理器是32--位于位,那么即使不需要这样的大整数,我也应该始终使用Qint32.在第一瞬间,我不明白为什么,但是好吧,我不相信.首先,没有提供任何实际参考来证实这样的论文:我简直不明白为什么从32位记忆空间写和阅读会慢于32位整数(而给出的解释都不太可理解) , 顺便提一句).其次,我的应用程序上有一些时刻需要将数据从一侧传输到另一侧,例如使用QT的信号和插槽机制.由于我将数据从一个点传
在另一个线程中,我被告知switch在速度和紧凑性方面可能比查找表更好. 所以我想了解这之间的区别: 查找表 static void func1(){} static void func2(){} typedef enum { FUNC1, FUNC2, FUNC_COUNT } state_e; typedef void (*func_t)(void); const func_t lookUpTable[FUNC_COUNT] = { [FUNC1] = &func1, [FUNC2] = &func2 }; void fsm(state_e state) { if (state
我正在阅读 "重新排序a的成员变量 将最常用和最不使用的类别类." 我对C ++不熟悉,也不对其进行编译,但我想知道 是否 此语句准确? 如何/为什么? 它适用于其他(编译/脚本)语言? 我知道,这个技巧节省的时间(CPU)时间很小,这不是一个破坏交易的人.但是,另一方面,在大多数功能中,很容易识别哪些变量将是最常用的变量,并且默认情况下只是以这种方式开始编码. 解决方案 这里有两个问题: 将某些字段放在一起是一个优化. 如何实际做. 可能会有所帮助的原因是,将内存加载到称为"缓存线"的块中的CPU缓存中.这需要时间,而且通常说,对您的对象加载的缓存线越长,则需要的时间越长.另外,其他东西从缓存中扔出来腾出空间,这会以一种不可预测的方式减慢其他代码. 缓存线的大小取决于处理器.如果与对象的大小相比,它很大,则很少有对象跨越缓存线边界,因此整个优化非常无关.否则,您可能有时只在缓存中只有一部分对象,而其余部分则在主内存(或L2缓存)中.
如何计算一个从2个int值到代表一个百分比的int值的百分比(超准确性)? 背景/目的:使用没有FPU的处理器,浮点计算需要更长的时间. 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 would mean 25.0 percent res
我正在考虑在YOCTO项目上开发嵌入式Linux项目(工业应用程序),我对具有嵌入式Linux经验的人有一些问题 - Yocto - Yocto会经验丰富.只需要了解固件更新中通常所做的事情. 我有一些要求,即身份验证,安全的通信协议,如果更新失败,则某种类型的回滚.另外,如果有一种方法可以逐渐释放跨设备机队,那么这也很有趣,因为我想避免在现场中进行砖砌的设备. 您今天如何将更新/补丁部署到现场设备 - 开发它需要多长时间?我还有其他考虑吗? 解决方案 尽管您肯定可以使用RPM,DEB或IPK进行升级,但是我的首选方式(至少对于小到合理尺寸的图像)是将两个图像存储在Flash上,并且仅更新完整的Rootfs Images . 今天,如果我要使用OpenEmbedded/Yocto项目开始使用Embedded Linux,我可能会看Meta-Swupdate. 我为自己和多个客户使用的是这样的东西: 一个容器升级文件,该文件是一个由另一个TARBA
我正在Yocto的Dora分支(Poky 1.2)工作,只需要在该分支上工作. 我需要将空白的根密码更改为其他值,以防止在开发过程中图像中的安全孔. 如何设置root密码? 我想使用local.conf文件. 此处描述的方法不起作用: 如何在yocto/poky image上设置root密码? 解决方案 在您的build/conf/local.conf中添加以下行或转到您的meta-dir并添加以下git patch. INHERIT += "extrausers" EXTRA_USERS_PARAMS = "useradd admin; \ usermod -p $(openssl passwd abc123) admin; \ usermod -p $(openssl passwd knockknock) root; \
我正在为C上的嵌入式系统上的文本文件编写一个解析器.我需要每秒使用SSCANF函数数百次,这会造成性能麻烦.因此,我正在尝试找到SSCANF的快速替代方案. 我需要解析的文本文件包含"参数=%d,%d,%d,%d"的参数.参数名称的长度有所不同,但参数始终由4个整数值组成. 解析器在另一个文本文件的一行中读取一行,并将字符串存储在变量" token"中.变量"格式"包含表单的字符串"参数=%d,%d,%d,%d". void Parser_GetQuadToken( char* token, const char* format, int16_t* res1, int16_t* res2, int16_t* res3, int16_t* res4 ) { uint32_t var1, var2, var3, var4; sscanf( token, format, &var1, &var2, &var3, &var4 ) ); *res1 = v
我正在使用AVR-GCC工具链在C中为简单的基本语言(例如语言)作为练习. 如果我写这本书以在Linux盒子上运行,我可以使用Flex/Bison.现在我将自己限制在一个8位平台上,我将如何编码解析器? 解决方案 我已经实施了针对首先,我考虑使用Flex/Bison.我决定反对此选项的两个主要原因: 默认情况下,Flex&Bison取决于某些标准库功能(尤其是对于I/O),这些功能在AVR-LIBC中不可用或不可用.我很确定有支持的解决方法,但这是您需要考虑的额外努力. AVR具有 Harvard Architecture . C并非为此来解释这一点,因此即使是恒定变量也被加载到RAM中,默认情况下.您必须使用特殊宏/函数来存储和访问数据在和 eeprom "> eeprom . Flex&Bison创建了一些相对大型查找桌,这些桌子很快就会吞噬您的RAM.除非我错误(很可能),否则您将必须编辑输出源才能利用特殊的Flash&Eeprom接口. 拒绝Flex&
我正在开发一个Java桌面应用程序,并且想要可以与Hibernate一起使用的light database,并且可以用应用程序包装. 我要使用Derby数据库.它的尺寸接近2 MB.但是在此之前,我想对So有专家的看法. 它可以与Hibernate? 一起使用 实际上,我是冬眠的新手,正在研究数据库需要Dialect,所以Hibernate是否具有Derby的方言? 解决方案 javadb 开源Apache derby), hsqldb (不是很活跃)和 h2 ( HSQLDB的占地面积最小(〜700 kb).但特征明智(请参阅此比较),H2是明显的赢家及其足迹(〜1 MB)仍然小于德比的一(〜2 MB). 最终选择取决于您的需求,但H2是特征和大小的良好折衷(换句话说,是一个大竞争对手).看看上述比较. 其他解决方案 我会推荐 hsqldb .它又小又快速,可以与冬眠一起运行. Hibernate也有Derby DB的方言(虽然还没有使用过,但我认
我最近对代码进行了一些调整,其中我必须在函数中更改正式参数.最初,该参数与以下内容相似(注意,结构是较早的): 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从未更改其值.这导致了以下更改: sta
我有一个需要新功能的传统固件应用程序.该应用程序的大小已经接近设备的闪存容量有限,而几个新功能和变量将其推向边缘.打开编译器的优化确实可以解决问题,但是客户对此感到警惕,因为他们过去曾导致失败.那么,重构C代码产生较小的输出时,有什么常见的东西? 解决方案 在可能的情况下使用生成功能而不是数据表 禁用内联函数 将经常使用的宏变成函数 减少大于本机机器大小的变量的分辨率(即8位微型,尝试摆脱16和32位变量 - 双打和四倍的一些代码序列) 如果微型具有较小的指令集(手臂拇指)在编译器中启用它 如果记忆被分割(即,分页或非线性),则 重新安排代码,因此需要使用更少的全局呼叫(较大的呼叫说明) 重新安排代码和可变用法以消除全局内存调用 重新评估全局内存使用量 - 如果可以将其放在堆栈上,那么更好的 确保您正在使用调试打开编译 - 在某些处理器上,这会大大差异 压缩数据无法生成的数据 - 然后在启动时将其解压缩到RAM中以进行快速访问 钻探编译器选项 - 可能是
从这样的代码开始 void lib_memset( unsigned char *dest, unsigned char c, unsigned int n) { while(n--) { *dest=c; dest++; } } 使用LLVM作为交叉编译器 clang -Wall -m32 -emit-llvm -fno-builtin --target=arm-none-eabi -c lib_memset.c -o lib_memset.bc opt -std-compile-opts -strip-debug -march=arm -mcpu=mpcore -mtriple=arm-none-eabi lib_memset.bc -o lib_memset.opt.bc llc -march=arm -mcpu=mpcore -disable-simplify-libcalls lib_memset.op
我创建了一个小程序,作为要在嵌入式平台上实现的系统的概念验证.该程序用C ++ 11编写,并使用STD并编译以在笔记本电脑上运行.最终程序应稍后实施,是一个嵌入式系统.我们无法访问嵌入式平台的编译器. 我想知道是否有一种方法可以以明智且可比的方式确定程序静态内存(编译后的二进制文件的大小). 要求是二进制的大小小于10kb. 我们的二进制尺寸为700kb,并用以下标志剥离: g++ options: -Os -s -ffunction-sections -fdata-sections linker options: -s -Wl,--gc-sections strip libmodel.a -s -R .comment -R .gnu.version --strip-unneeded -R .note 在我们使用条带和优化选项之前,它占了4MB. 我仍然离去,这并不是一个很大的程序.我如何以任何方式与嵌入式平台上的等效程序进行比较. 解决方案 请
我有一个程序设计问题: 我有一个具有4个状态和6个任务的状态机.在每个状态中,必须执行不同的任务,除了始终处于活动状态的任务1外: 状态1:task1,task2,task3 状态2:task1,task2,task3,task4 状态3:任务1,任务5 状态4:任务1,任务6 task1,tast3,tast4,task5和task6是周期性的,每个都读取不同的传感器. Task2是Aperiodic,仅在达到阈值时才发送GPRS警报. 状态之间的切换由每个任务的传感器输入事件确定. Main()设计的初始方法是具有控制状态的开关,并取决于状态,暂停和激活相应的任务: void main () { /* initialisation of hw and variables*/ system_init(); /* creates FreeRTOS tasks and suspends all tasks except