作者nevak (^o^)
看板C_and_CPP
标题Re: [问题] porting issue(32bits-->8bits)
时间Sun Apr 19 17:11:15 2020
※ 引述《galic (嘎利)》之铭言:
: ※ 引述《ando5566》之铭言:
: : 各位版友日安,
: : 最近小弟要将32bits平台的CAN protocol API, porting 至8bits平台上,
: : 遇到了一个问题, 如下:
: ...
: : 但是因为我的原意是porting, 所以我不希望影响任何其他写法,
: ^^^^^^^
: : 尝试过使用union的作法, 但是仍会面临无法使EID定址在第12bit的问题。
: : 想请教版上高手, 有其他方法吗?
: : 谢谢!
: 我不知道这篇为什麽没有人回正解...
: 在我念书的时候
: 记得老师曾经说过「C 的 bit-fields 不要乱用」
: 尤其是在涉及 memory format (layout) 相关操作的时候
: 像是 network package 的格式、操作 CPU registers …
: 一开始觉得没什麽
: 但後来真的有看过用 C 开发的 http APIs 竟然用 bit-fields 来 mapping 封包
: 也看过 Arduino 的教学文件竟然是用 bit-fields 在操作 LED 灯和 GPIO
: 所以我觉得推文只要一句「bit-fields 不要乱用」
: 应该就足够了
: 不然,
: 问 google 也会给你答案
: `c bit fields portability' 或 `bit fields portability'
: 有趣的是,差一个 C 搜出来的会是不同答案
: 不过观点是一致的
: 总之,你需要的是透过 bit manipulation 来操作
: (有时候打包成 macro 会直接叫 bitmask, bitset 或 bitops....)
: ref: https://stackoverflow.com/a/263738
先讲结论...
1. bit-field 真的满难用的
2. 原Po的问题,以C standard来看,我是找不到可以只改declaration不改其他code完成
porting的方法....
====
以下来自於C11 standard关於bit-field的章节
Section 6.7.2.1 paragraph 5 提到,Bit-field只能用在_Bool, signed int,
unsinged int以及其他implementation defined的型态上。先撇开_Bool不谈,
signed int以及unsigned int 在 section 5.2.4.2.1 中提到必须至少是16-bit。
因此原po提到bit-field width 11 编译不过,很可能是这compiler根本不合standard
不过8-bit compiler这种事也很常见,希望他有在说明书中写清楚就是了
再来是Section 6.7.2.1 paragraph 11提到,implementation可以自由选择allocate任意
addressable storage unit来装bit-field,只要足够大就可以了,後面虽然有加一个补
充说如果还有空间,紧邻的下一个bit-field应该被放到同一个storage unit,但最後又
补一句说,同一个unit里假如放了多个bit-field,它们的顺序,是implementation
defined
简单来说,假如我们定了一个总长32bit的一组bit-fields,分别是5bit, 9bit, 14bit,
4bit,首先standard并不保证这四组bit-fields会紧邻再一起塞在一个32-bit的storage
unit中,第二就算它们紧邻在一起,也不能保证他们的顺序就是5,9,14,4
bit-field在多数情况下确实是好用,只要能够确定compiler的行为,比方说透过
各种pragma去限制,用bit-field也没什麽不好 ,而用bit-field会让code porting到不同
平台上的难度变高,这个也是肯定的
最後如果我是老师,面对大一资工系刚接触C code的学生们,我应该也会选择跟他们说
bit-field暂时不要用,先学好bit operation比较重要。第一个避免用bit-field踩到洞
,第二个bit operation是许多公司的面试必考题,根据我以前在某晶片厂面试的经验
bit operation非常意外地可以刷掉很多名校并且成绩不错的人。我只是希望以後减少因
为bit operation被刷掉的人,真的满可惜的。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 36.231.44.180 (台湾)
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/C_and_CPP/M.1587287479.A.EB0.html
1F:推 LiloHuang: 任何东西存在都有它的意义,这篇文章的见解比较客观 04/19 17:22
2F:推 qscgy4: 能不能举个bit operation的题目来看看? 04/19 19:54
4F:→ nevak: 其实应该就大家能想到最简单的,set/clr某个bit,台清交成 04/19 23:24
5F:→ nevak: 资工系全部都挂掉过,我也是到那时知道,很多就算资工系毕 04/19 23:24
6F:→ nevak: 业的人,也没写过 | 或者是& 04/19 23:24
7F:推 Schottky: 推 04/20 00:54
8F:→ Schottky: 成大资工也挂掉过?我好像听成大的同学们说过 jserv 相 04/20 00:57
9F:→ Schottky: 当重视特训大家的 bit operation 熟练度 04/20 00:57
10F:推 LPH66: 特训是一回事, 能懂是另一回事... 04/20 04:13
11F:→ LPH66: 我在的某群组里有个现在正在修他的课的学生 04/20 04:27
12F:→ LPH66: 从他每周贴作业的感觉来看好像也不是很好地掌握这些东西.. 04/20 04:27
13F:→ hsnuyi: 去刷个LC 或是写个verilog就会懂bit op了 04/20 11:18
14F:→ MasterChang: 因为难懂,所以逃避,可以理解。 04/20 12:09
15F:→ MasterChang: 试过XC8可以编过,可能原PO是lite版的关系。 04/20 12:11
16F:→ Lipraxde: 我查了 XC8 C Compiler User's Guide for PIC,原 Po 04/20 17:39
17F:→ Lipraxde: 所看到的错误讯息应该是 Appendix B 中的 (741) bitfie 04/20 17:39
18F:→ Lipraxde: ld too large ... ,里面有说明 bitfield 的位元数不能 04/20 17:39
19F:→ Lipraxde: 超过 8,跟是不是 Lite 版应该没有关系? 04/20 17:39
20F:推 ucrxzero: 请问网路遮罩也算是一种应用吗 04/20 19:11
21F:→ protoss: 是啊~资工没修过网路也是蛮神奇的... 04/20 23:23
22F:推 ando5566: 我是原po我是用1.45 pro版 04/25 19:46
23F:推 ando5566: 用pragma pack(1)也没编译成功,已经硬改code把专案 04/25 19:49
24F:→ ando5566: 完成了,一个pic18 的mcp2517 spi to CANFD的driver api 04/25 19:49
25F:推 ando5566: #pragma pack 1 有效 04/26 13:30