完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
我用C30 v 3.31为PIC24FJ256GB206编码。现在我需要将一个配置结构保存到SDCard中,并且我想知道该结构实际上是如何组织的(我将其保存为二进制映像)。对于这种类型的变量,eof操作符报告的大小是42而不是40,并且得到的文件实际上也是42字节的长度。我已经通过将第一、第三和最后一个成员设置为某个非零值进行了测试,并且文件显示为十六进制内容:所以看起来在某个地方插入了一个额外的零,然后在末尾插入了一个。42,除了我原本期望它在文件中读为002A,但是现在它被列为2A00……我试图在将结构打包到内存中的方式上进行读取,并且我认为除非使用指令将结构设置为打包,否则成员将在大于1字节的一些边界上对齐,我没有做过。C30编译器有什么特殊的方法吗?我如何解码文件中的二进制文件呢?
以上来自于百度翻译 以下为原文 I am coding for PIC24FJ256GB206 using C30 v 3.31. Now I need to save a configuration struct to SDCard and I want to know how the struct is actually organized (I am saving it to file as a binary image). Here is my struct, with my byte count at the end of each line: typedef struct { UINT8 HVOLT_Num; // 1 UINT8 I_code; // 1 int Curr_num; // 2 int meastime; // 2 int INT_Time; // 2 int DelayTime; // 2 UINT8 TempLimit ; // 1 UINT8 MaxHV; // 1 UINT8 Samples; // 1 UINT8 BATT; // 1 UINT8 Temperature1; // 1 UINT8 Temperature2; // 1 UINT8 R_sense; // 1 UINT8 Polarity; // 1 UINT8 BLEEDERflag; // 1 UINT32 ICNT; // 4 UINT32 OFFSETCNT; // 4 float TxCurrent; // 4 float Rfb; // 4 float CalVal; // 4 UINT8 AutoRangeFlag; // 1 } SSTXSTATE; //Sum=40 Now the strange thing is that the sizeof operator on a variable of this type reports size as 42 instead of 40 and the resulting file is actually also 42 bytes in length. I have tested by setting the first, 3rd and last members to some nonzero value and the file shows up with this hex content: E7 00 2A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00 So it seems like somewhere there is one extra zero inserted and then one at the end too. Also the value I set for Curr_Num is the reported size of the struct variable, and 2A is 42, except I would have expected it to read as 00 2A in the file but now it is listed as 2A 00... I have tried to read up on the way structs are packed in memory and I thought the members would be aligned on some boundaries bigger than 1 byte unless one used a directive to set the struct as packed, which I have not done. Is there some special way for the C30 compiler to do this? And how can I decode binaries like this in the file? |
|
相关推荐
19个回答
|
|
|
PIC24要求所有内容都对齐在两字节边界上,这意味着一个结构,它包含,例如,一个uint8_t,后面跟一个uint16_t,在这两个字段之间插入一个pad字节来对齐uint16_t。在大型类型之间是奇数的8位值,因此是两个pad字节。除非您需要使用结构,否则不要使用结构。只需将单个项目一次写入文件即可。
以上来自于百度翻译 以下为原文 The PIC24 requires everything to be aligned on a two-byte boundary, which means a struct that contains, for example, a uint8_t followed by a uint16_t, there will be a pad byte inserted between those two fields to align the uint16_t. Given this, you can see in your struct where you have two instances of an odd-number of 8-bit values between larger types, hence two pad bytes. Unless you have a requirement to use a struct, don't use a struct. Just write the individual items to the file one at a time. |
|
|
|
|
|
默认情况下,编译器对类型进行对齐以确保更快的访问。在16位处理器中,16, 32位和64位类型被存储在偶数存储器地址中。在32位处理器中,32位和64位类型存储在4个可分割的地址,16位到偶数位的存储器地址。这意味着每次混合8位类型和其他大小类型时,编译器将添加填充字节以确保所有非8位类型都存储在偶数地址中。解决方案:您可以按大小对所有条目进行排序,从64位整数开始,然后是32位整数、指针、枚举、16位整数和8位整数。这样,在保持对齐和快速访问的同时,您将使用结构的最小可能大小。您可以将_u.((packed))添加到结构定义中。这指示编译器不添加填充物。通过这种方式,您的结构将精确地占据每个元素的大小之和,但是访问它的代码将越来越大,越来越慢。
以上来自于百度翻译 以下为原文 By default, the compiler aligns the types to ensure a faster access. In a 16 bit processor, 16, 32 and 64 bit types are stored at even memory addresses. In a 32 bit processor, 32 and 64 bit types are stored at 4-divisible addresses, and 16 bit to even memory addresses. This means that every time you mix 8 bit types and other-size types, the compiler will add padding bytes to ensure that all non-8 bit types are stored in even addresses. There are two solutions:
|
|
|
|
|
|
谢谢,然后我错误地解释了我在StackOverflow找到的信息……在那里,看起来任何1字节的结构成员都会被填充长达4个字节,长度为3个零,所以对齐将是4个字节。但我猜只有在从字节改变为int或double等时才会发生这种情况。我在我的文件中没有看到,所以我假设C30正在打包,但是还有额外的2个字节……在这种情况下(PIC24是16位),看起来它仍然将字节成员打包为连续的。比如,它在BLEEDERflag和ICNT之间的边界中每字存储2字节,但是没有这样做,所以添加一个零字节来使ICNT达到偶数地址。但是,最后一个字节成员AutoRangeFlag在最后一个单词中结束,没有伴随,所以在那里也添加了一个额外的字节。
以上来自于百度翻译 以下为原文 Thanks, then I interpreted the info I found at StackOverflow erroneously... There it looked like any 1-byte struct member would be padded up to 4 bytes in length with 3 zeros so the alignment would be 4-byte. But I guess that it only happens when there is a change from byte to say int or double etc. I did not see that in my file so I assumed C30 was packing it all, but then there were these extra 2 bytes... In this case (PIC24 being 16 bit) it looks like it still packs the byte members to be consecutive... Like it stores bytes 2 per word and fails to do that in the border between BLEEDERflag and ICNT so adding a zero byte to get ICNT to an even address. But then the last byte member AutoRangeFlag winds up in the last word without a companion so an extra byte is added there too. So by moving AutoRangeFlag to before ICNT the struct would become 40 bytes in length... |
|
|
|
|
|
这个话题是关于一个32位处理器!它只在16个地址和32个位项上输入偶数地址。“打包”是指消除任何填充。
以上来自于百度翻译 以下为原文 That topic is talking about a 32 bit processor! It only pads 16 and 32 bit entries to start at even addresses. "packing" refers to eliminating any padding. |
|
|
|
|
|
好的,谢谢你的解释!因此,如果可能的话,字节变量总是存储在每个内存字中2?我做了下列更改来检查:-移动成员AutoRangeFlag以跟踪BLEEDERflag,从而保持它与其他UINT8值。-强制值进入结构成员以进行测试:现在得到的文件有40字节长,并且包含这个(不再有填充字节):Curr_num=2800meastime=D2 04So i看起来in t数据首先与l***一起存储在PIC24上,这与Intel处理器的PC上一样……在我正在工作的电路板上被替换的处理器(摩托罗拉MC68HC11)以相反的顺序存储这些值……
以上来自于百度翻译 以下为原文 OK thanks for the explanation! So it means that if possible byte variables are always stored 2 in each memory word then? I did the following changes to check: - Moved member AutoRangeFlag to go after BLEEDERflag, thus keeping it with other UINT8 values. - Forced values into struct members for testing: cnt = sizeof TxState; TxState.HVOLT_Num = 231; //First member (byte) TxState.Curr_num = cnt; //3rd member (int) TxState.meastime = 1234; //4th member (int) TxState.AutoRangeFlag = 254; //Last byte member (byte) TxState.CalVal = 1.234; //Last member (float) Now the resulting file is 40 bytes long and contains this (no longer any pad bytes): E7 00 28 00 D2 04 00 00 00 00 00 00 00 00 00 00 00 00 00 FE 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 B6 F3 9D 3F Curr_num = 28 00 meastime = D2 04 So it seems like int data are stored with l*** first on a PIC24, the same as on a PC with Intel processor.... The processor that is being replaced on the board I am working on (Motorola MC68HC11) stores these values in the opposite order... |
|
|
|
|
|
|
|
|
|
|
|
是的,我相信汽车工业使用MC68HC11作为汽车分析工具等。但是,它进入我们的产品已经很久了,大约在1992年左右。由于年龄和CPU容量等原因,需要更新。最坏的情况是使用MC68HC711部件的仍然活跃的产品,带有一次性程序。船上可装EPROM!它是15年前设计的。这些部件已经过时很久了,售后市场上的可用性很差,所以我们投入PIC24FJ256GB206作为替换,并将代码从IAR移植到MPLAB。在HC11上的第三EEPROM,还在我工作的时候添加了SDCard套接字。如果需要的话,可能会切换到SD卡的SD卡,但现在不需要。B-B能够使用FatFs根据数据大小(每次写入的数据越多,速度越快)将近100kbytes/s。我们以前没有使用磁盘存储,所以它只会用于将来的想法和用途。
以上来自于百度翻译 以下为原文 Right, I believe the car industry used the MC68HC11 for car analysis tools etc. However, it got into our products a long time ago - about 1992 or so - and an update is needed due to age and CPU capacity etc. The worst case is a still active product using an MC68HC711 part, the one with one-time programmable EPROM on board! It was designed 15 years ago. Those parts are now obsoleted since a long time and availability is terrible on the after-market. So that is why we are throwing in a PIC24FJ256GB206 as replacement and are porting code from IAR to MPLAB. And I have had to use an external 24AA04 I2C connected EEPROM chip as replacement for the on-board EEPROM on the HC11, also added the SDCard socket while I was at it. Both the I2C and SDCard interfaces work with bit-bang code now. Might switch to SPI for the SDCard if needed for speed, but right now it is not needed. B-B is capable of write speed approaching 100 kbytes/s depending on data size (faster the more data you write each time) using FatFs. We did not use disk storage before anyway so it will only be there for future ideas and uses. |
|
|
|
|
|
BobAGI,你在这里经历的是我在PIC、PC和Android之间共享代码时遇到的一个常见问题。值得一读工程师的建议和最新版本C的指南。我试图打破的一个“习惯”是使用“int”。这可以是不同架构上的不同大小。PC编译器分配32位。您的PIC24将是16位。对于您的字节顺序,GoGoe'EndiaNess。但这应该是内部问题,不是你的节目的问题。
以上来自于百度翻译 以下为原文 @ BobAGI, What you experience here is a common problem I have while trying to share code between PIC, PC and Android. It is worth reading up on engineers suggestions and also the guidance on the latest version of C. One 'habit' I am trying to break is the use of 'int'. This can be different sizes on different architectures. PC compilers allocate 32 bits. Your PIC24 will be 16bit. For your byte order, google 'endianness'. But this should be internal and not be any issue to your program. For readers info, I think the term comes from Gulliver's Travels. T Yorky |
|
|
|
|
|
这不是阿加莎·克里斯蒂的作品吗?10个小印第安人
以上来自于百度翻译 以下为原文 Isn't it more of Agatha Christie? 10 little indians.. |
|
|
|
|
|
你在这里所做的事情通常被称为“序列化”。当我这样做时,我通常不使用打包结构,而是一个正确的大小和转换接口的内存缓冲区,它将内部(解压缩)结构和内存缓冲区之间转换。这样,代码将是不敏感的,可以很容易地被移植,内部结构尽可能高效地在内部使用。有时在序列化流中添加版本号或包含大小是有用的。这样你就可以用更多的成员升级你的结构,并且仍然保持向后兼容性。
以上来自于百度翻译 以下为原文 What you are trying to do here is commonly called "serialization". When I do this I usually don't use packed structures but rather a memory buffer of the correct size and translation interfaces that convert between the internal (unpacked) structures and the memory buffer. This way the code will be endianness insensitive, can easily be ported and the internal structures are used as efficiently as possible internally. Sometimes it is also useful to put a version number in the serialized stream or include the size. This way you can upgrade your structures with more members and still keep a backward compatibility. /Ruben |
|
|
|
|
|
在另一个基于HC11的产品中,数据收集系统使用RS232将数据传送到PC。为了节省时间,我们将整个结构化数据阵列作为二进制图像传送。然后,在PC上,将数据解压缩为适当的数据,这里我必须进行端点转换,因为PC上的HC11和英特尔是不同的。所以,是的,我知道转换的前后关系。现在我也知道,在PIC24中,我不需要EnDANI转换。但是另一个系统还没有成为转换板的目标…
以上来自于百度翻译 以下为原文 In another HC11 based product that is a data collection system the data are transferred out using RS232 to a PC. In order to save time we transfer the whole arrays of structured data as a binary image. Then on the PC this is unpacked into the proper data and here I had to do endian conversion because the HC11 and the Intel on PC are different. So, yes I know the ins and outs of the conversions. Now I also know that with the PIC24 I do not need endian conversions. But the other system has not been a target for conversion of the board yet... |
|
|
|
|
|
这不是阿加莎·克里斯蒂的作品吗?10个小印第安人按照高度顺序排列,一端是大印度语,另一端是小印度语:)https://www.ietf.org/rfc/ien/ien137.txt。
以上来自于百度翻译 以下为原文 Isn't it more of Agatha Christie? 10 little indians.. Line them up in height order and you have big indian at one end and little indian at the other end :) https://www.ietf.org/rfc/ien/ien137.txt |
|
|
|
|
|
所以当你看印度队列时,这条线就在右边?这样地?我总是要看名字,但我知道,在英特尔上,顺序是从最不重要的部分开始,以最重要的部分结束。所以42作为16位的值看起来像2A 00,而在摩托罗拉上,它开始像我们通常读的数字最重要的部分,导致00。2A有趣的EnDad战争链接
以上来自于百度翻译 以下为原文 So when you look at the indian queue the line ends to the right? Like this? o o 00 00 o o 00 00 00 00 o o 00 00 00 00 00 00 / / / / / / ^ Little End ---->| 00 2A ================== o o o o 00 00 o o 00 00 00 00 00 00 00 00 00 00 / / / / / / ^ Big End -----| 2A 00 I always have to look the name up but I know that on Intel the order is starting with the least significant part and end with the most significant part. So 42 as a 16 bit value looks like 2A 00 whereas on Motorola it starts like we usually read numbers with the most significant part, resulting in 00 2A. Interesting link to the endian war... |
|
|
|
|
|
它是Endiad,而不是印度(从Gulver游记)到包装结构:ByTeByTeTyByTeBee可以在16位CPU中自然打包,而不是其他的。ByTeTyByTebe通常会在16位CPU中拾取两个虚拟字节。8位CPU自然打包为8位,所以问题不来。包装通常被用来允许结构从外部系统发送和接收,而天然包装是不可知道的。
以上来自于百度翻译 以下为原文 it is endian not Indian (from Gulliver's travels) note as far a packing structs: byte byte int byte bye This can be naturally packed in some 16 bit CPUs, but not others. byte int byte This will usually pick up two dummy bytes in a 16 bit CPU. 8 bit CPUs are naturally packed to 8bits so the issue does not come up. Packed is usually used to allow structs to be sent to and received from external systems, were the natural packing can not be known. |
|
|
|
|
|
重新排列结构中的字段,以便所有16位实体具有2字节对齐(即它们从结构开始时的偏移量是偶数),所有32位实体具有4字节对齐(即它们从结构开始时的偏移量可被4整除)。这样,如果迁移到其他的处理器,就不会有任何问题。.-endian对于PIC来说更容易,并且现在更常见,但是许多协议(如TCP)使用.-endian。
以上来自于百度翻译 以下为原文 Re-arrange the fields in your stracture so that all 16-bit entities have 2-byte alignment (that is their offset from the beginning of the structure is even) and all 32-bit entities have 4-byte alignment (that is their offset from the beginning of the structure is divisible by 4). This way you won't have any problems if you migrate to a different processor. Little-endian is easier for PICs and much more common today, but many protocols (such as TCP) use big-endian. |
|
|
|
|
|
幽默感失败?你读过阿加莎·克里斯蒂作品吗?
以上来自于百度翻译 以下为原文 Sense of humour failure? Have you read any Agatha Christie? |
|
|
|
|
|
幽默感失败?你读过阿加莎·克里斯蒂作品吗?我想不是。但是,我很久以前就知道是印度人了。我需要在幽默方面做个自我测试。最近它一直在起作用。
以上来自于百度翻译 以下为原文 Sense of humour failure? Have you read any Agatha Christie? I guess not. But, I though it was Indian a long time ago. I will need to run a self test on the Sense of humor. It has been acting up lately. |
|
|
|
|
|
|
|
|
|
|
|
前几天我在电视上观看了Endianna Jones的再次演出。
以上来自于百度翻译 以下为原文 I watched a re-run of Endianna Jones on TV the other day. |
|
|
|
|
只有小组成员才能发言,加入小组>>
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
501 浏览 0 评论
5808 浏览 9 评论
2350 浏览 8 评论
2237 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3543 浏览 3 评论
1155浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
1119浏览 1评论
我是Microchip 的代理商,有PIC16F1829T-I/SS 技术问题可以咨询我,微信:A-chip-Ti
887浏览 1评论
MPLAB X IDE V6.25版本怎么对bootloader和应用程序进行烧录
501浏览 0评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-12 03:51 , Processed in 2.286939 second(s), Total 113, Slave 95 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
13968