搜索
bottom↓
12
返回列表 发新帖
楼主: Gorgon_Meducer

[交流][拍砖]新版驱动接口风格调查(一):IO配置

  [复制链接]

出0入0汤圆

发表于 2013-10-13 16:32:59 | 显示全部楼层
Gorgon_Meducer 发表于 2013-10-13 16:06
我没有强制别人用我的规范哦,我只是说,这种风格的库大家会有什么想法。如果你仔细看库,你发现,基本的 ...

楼上的几位网友的观点,跟我说的都是一样的,我们都是觉得没有必要用 IO_CFG 这样的宏,因为这个宏没有带来任何的好处?仅仅是省敲几下键盘而已?

官方库的使用,要尽可能达到望文达意,所以变量名、宏定义长一点没关系,将意思写清楚,这样更让用户能够快速上手。阅读代码的时候,也是跟看文章一样。既然是为了尽可能达到这个效果,为什么还要人为的加上需要特殊识别的宏,而且仅仅是个人风格化的宏呢?

你提出这个仅仅是风格化的东西,而不是强制要求的规范,但是有一个前提啊,客户在使用这个库的时候,就不得不先学习了解你的这个风格,然后在做出选择,是否跟进……

都是程序员,何苦为难程序员呢?直接写成标准的展开语句,有什么不好?

出0入296汤圆

 楼主| 发表于 2013-10-13 16:40:56 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-10-13 16:56 编辑
STM32_Study 发表于 2013-10-13 16:32
楼上的几位网友的观点,跟我说的都是一样的,我们都是觉得没有必要用 IO_CFG 这样的宏,因为这个宏没有带 ...


哈哈哈……是的……直接展开……
你说的一句话我觉得合情合理“程序员何必为难程序员”,这句话让我觉得非常感动……

请听我解释下,我一直认为,程序望文生义是最重要的,IO_CFG 再清楚不过了……但我忽略了,陌生的东西
比如语法会让人不安,而这种不安是人最害怕的东西,不安就会带来急躁,不信任,等等……所以,我从这个
事情上学到,以后例子代码一定会提供两个版本——完全绽开的版本,和用宏封装的版本。因为我相信,除了
会对这种代码背后隐藏的东西感到不安的人存在,也会有习惯性用黑盒子的人存在,二者我都应该尊重。

最后也请大家尊重我的努力,更猛烈的拍砖吧!

以下是展开形式,是不是亲切了很多呢?

  1. do {
  2.     io_cfg_t tCFG[] = {
  3.         {PA1, IO_WORKS_AS_SPI0_MOSI & IO_WRITE_ONLY,   IO_PULL_UP | IO_RAW_LOOP_BACK},
  4.         {PA1, IO_WORKS_AS_SPI1_MOSI & IO_READ_ONLY,    IO_PULL_UP | IO_RAW_LOOP_BACK},

  5.         {PA2, IO_WORKS_AS_SPI0_SCK  & IO_WRITE_ONLY,   IO_PULL_UP | IO_RAW_LOOP_BACK},
  6.         {PA2, IO_WORKS_AS_SPI1_SCK  & IO_READ_ONLY,    IO_PULL_UP | IO_RAW_LOOP_BACK},

  7.         {PA3, IO_WORKS_AS_SPI0_CS   & IO_WRITE_ONLY,   IO_PULL_UP | IO_RAW_LOOP_BACK},
  8.         {PA3, IO_WORKS_AS_SPI1_CS   & IO_READ_ONLY,    IO_PULL_UP | IO_RAW_LOOP_BACK},

  9.         {PA4, IO_WORKS_AS_SPI0_MISO & IO_READ_ONLY,    IO_PULL_UP | IO_RAW_LOOP_BACK},
  10.         {PA4, IO_WORKS_AS_SPI1_MISO & IO_WRITE_ONLY,   IO_PULL_UP | IO_RAW_LOOP_BACK},
  11.     };
  12.     IO.Config(tCFG, UBOUND(tCFG))
  13. } while(0);
复制代码

出0入0汤圆

发表于 2013-10-13 16:47:11 | 显示全部楼层
菜鸟一枚,看见很多宏技巧都要用到 do{...}while(0); 这个结构,但我一直都不明白这个的用意。
大神,能否解释一下这个结构的用意?

出0入0汤圆

发表于 2013-10-13 16:47:12 | 显示全部楼层
Gorgon_Meducer 发表于 2013-10-13 16:40
哈哈哈……是的……直接展开……
你说的一句话我觉得合情合理“程序员何必为难程序员”,这句话让我觉得 ...

泪流满面啊~~这个就是我想要的~~~说了那么多,终于得到了楼主的共鸣,幸福感满满的~~~

完全展开版本,看起来很直观,很情切,有木有!

出0入0汤圆

发表于 2013-10-13 16:51:12 | 显示全部楼层
YuWan 发表于 2013-10-13 16:47
菜鸟一枚,看见很多宏技巧都要用到 do{...}while(0); 这个结构,但我一直都不明白这个的用意。
大神,能否 ...

因为宏定义是预处理器直接文本替换的,为了保证不会因为各种语法的组合而造成语法歧义,所以加上do while(0)

这样可以确保宏定义的语句是完整独立的

出0入296汤圆

 楼主| 发表于 2013-10-13 16:52:45 | 显示全部楼层
按照大家的要求,更新了两个风格的代码到楼住位。可怜我是处女座……你们应该能理解我这是做了一个多么艰难的决定啊……
TAT

出0入93汤圆

发表于 2013-10-13 20:36:08 | 显示全部楼层
Gorgon_Meducer 发表于 2013-10-13 16:52
按照大家的要求,更新了两个风格的代码到楼住位。可怜我是处女座……你们应该能理解我这是做了一个多么艰难 ...

再来吐槽一下。

1、展开版本的do...while...zero真心的没必要,一个{}就搞定,因为使用者完全自己知道后面有没有分号,弄个do...while...zero看着怪寒碜人的。
2、从这一句:while (fsm_rt_cpl != SPI1.DataExchange(s_hwSlaveOut,&s_hwSlaveIn)) 就可以看出来,傻孩子大虾的代码风格非常不统一,K&R风格的fsm_rt_cpl 和MS风格的DataExchange交替使用,看得犯晕。您能不能稍微统一一下,要么全部K&R风格,要么全部MS风格?就我个人而言,更接受MS风格Pascal命名法,对于camel命名法和K&R风格总有一种抵触感,难道是强迫症?

出0入0汤圆

发表于 2013-10-13 20:39:26 | 显示全部楼层
takashiki 发表于 2013-10-13 20:36
再来吐槽一下。

1、展开版本的do...while...zero真心的没必要,一个{}就搞定,因为使用者完全自己知道后 ...

程序员都有强迫症

我也有强迫症,花括号一定要另起一行,Tab一定要用四个空格替代,否则会崩溃宕机

出0入0汤圆

发表于 2013-10-13 20:41:48 | 显示全部楼层
话说,我也喜欢  DataExchange 这种风格,小写字母简写的方式,感觉很难看

出0入296汤圆

 楼主| 发表于 2013-10-13 22:00:16 | 显示全部楼层
takashiki 发表于 2013-10-13 20:36
再来吐槽一下。

1、展开版本的do...while...zero真心的没必要,一个{}就搞定,因为使用者完全自己知道后 ...

我如果告诉你,你说的这两种命名风格我都不知道,你会不会抓狂?
我没有模仿别人,这就是我自己的风格。我有自己一套统一的编码
风格,不要用别人的风格来套我的风格。

出0入296汤圆

 楼主| 发表于 2013-10-13 22:01:19 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-10-13 22:04 编辑
takashiki 发表于 2013-10-13 20:36
再来吐槽一下。

1、展开版本的do...while...zero真心的没必要,一个{}就搞定,因为使用者完全自己知道后 ...


一个{}看着怪怪的…浑身不自在。像这种易可亦不可的东西,你不舒服,改过来我也不舒服…
既然我付出了劳动,那么依着我可不可以嘛?我没有责怪的意思,吐槽也是我鼓励的,但我也可以
吐槽的嘛。

出0入296汤圆

 楼主| 发表于 2013-10-13 22:05:53 | 显示全部楼层
STM32_Study 发表于 2013-10-13 20:39
程序员都有强迫症

我也有强迫症,花括号一定要另起一行,Tab一定要用四个空格替代,否则会崩溃宕机 ...

你说的这个强迫症我也有。

出0入0汤圆

发表于 2013-10-13 23:01:22 | 显示全部楼层
啊喂,你们跑题跑远了吧!

还有LZ你,你自己也跟着跑了你知道吗?!



------------------
BTW,其实那些强迫症神马的,我也有。

出100入85汤圆

发表于 2013-10-13 23:11:55 | 显示全部楼层
本帖最后由 whatcanitbe 于 2013-10-13 23:15 编辑

哪位看懂的用KEIL4弄个完整的工程给大家学习学习

出0入296汤圆

 楼主| 发表于 2013-10-14 00:22:15 | 显示全部楼层
eduhf_123 发表于 2013-10-13 23:01
啊喂,你们跑题跑远了吧!

还有LZ你,你自己也跟着跑了你知道吗?!

跑跑更健康

出0入0汤圆

发表于 2013-10-14 08:55:23 | 显示全部楼层
1、第一眼给你的感受IO_CFG 到 END_IO_CFG之间的语句太长了,楼主想通过{PA1, IO_WORKS_AS_SPI0_MOSI & IO_WRITE_ONLY,   IO_PULL_UP | IO_RAW_LOOP_BACK},一句话就完成PA1引脚的所有配置,我是觉得有些长,其实分开来写也不错,出错了也好检查
2、顺次阅读代码后,基本清晰,SPI0.Open()这种语句很喜欢
3、有什么你觉得疑惑的地方? while (fsm_rt_cpl != SPI1.DataExchange(s_hwSlaveOut,&s_hwSlaveIn)) {
        SPI0.DataExchange(s_hwMasterOut,&s_hwMasterIn);不是很懂,感觉不直观
4、有什么改进意见?建议楼主参考ICCAVR或CVAVR的代码生成器生成的代码来做自己的代码生成器,stm32我没用过,用过一段时间的dsp2812 感觉它的库不错,它里面的枚举类型的定义和楼主的差不多,而且有输入的智能提示功能,就像C#的提示一样
5、有一个地方不太懂 不知道为什么用do{}while{0},  难道do{P1.0=0}while{0},比P1.0=0的效率要高吗?它翻译成汇编语言后应该比直接使用生成的语句要多吧?

出0入296汤圆

 楼主| 发表于 2013-10-14 09:56:23 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-10-14 10:00 编辑
sbk100 发表于 2013-10-14 08:55
1、第一眼给你的感受IO_CFG 到 END_IO_CFG之间的语句太长了,楼主想通过{PA1, IO_WORKS_AS_SPI0_MOSI & IO_ ...


谢谢你的反馈,代码生成器会比ICC的好很多,应该说基本目标就不同。正式版出来前,肯定会先公测的。

对于SPI的接口,你有什么建议呢?比如修改成什么样的形式比较好呢?你看一楼的spi.h,里面其实还提供了另外两个接口
用于数据传输,分别是SPIn.Write() 和 SPIn.Read() (n这里代表是第几个SPI)

出0入0汤圆

发表于 2013-10-14 17:09:48 | 显示全部楼层
Gorgon_Meducer 发表于 2013-10-14 09:56
谢谢你的反馈,代码生成器会比ICC的好很多,应该说基本目标就不同。正式版出来前,肯定会先公测的。

对 ...

static bool spi_write(__spi_t *ptSPI,uint16_t hwOut)
{
    CLASS(__spi_t) *ptThis = (CLASS(__spi_t) *)ptSPI;
   
    //! validate input parameter
    if(ptThis == NULL) {
        return false;
    }
    //! if tx fifo is not full, write data
    if(this.ptREG->SR.Value & SPI_SR_TNF_MASK) {            //!< tx fifo is not full
        this.ptREG->DR.Value = hwOut;
        return true;
    }

    return false;
}
——————————————————————————————————————————
这段代码看着好像C++啊!!太像了! 代码看不太懂,不知道 第一个形参是干啥用的?而且看着不像是往spi的发送缓冲区写数,倒像是往自己建的一个fifo里写数,不知道这样的好处,对于初学者来说有些困难

出0入296汤圆

 楼主| 发表于 2013-10-14 17:11:46 | 显示全部楼层
sbk100 发表于 2013-10-14 17:09
static bool spi_write(__spi_t *ptSPI,uint16_t hwOut)
{
    CLASS(__spi_t) *ptThis = (CLASS(__spi_t ...

第一个参数就是SPI对象阿

下面这句话就是向SPI的硬件FIFO写数据阿
this.ptREG->DR.Value = hwOut;

出0入0汤圆

发表于 2013-10-14 19:00:16 | 显示全部楼层
Gorgon_Meducer 发表于 2013-10-14 17:11
第一个参数就是SPI对象阿

下面这句话就是向SPI的硬件FIFO写数据阿

他的问题估计是那个“this”把人唬住了,还好这是内部实现的东西,用户要是都保持对内部实现“眼不见心为净”,驱动就不那么众口难调了

出0入296汤圆

 楼主| 发表于 2013-10-15 00:53:52 | 显示全部楼层
yiming988 发表于 2013-10-14 19:00
他的问题估计是那个“this”把人唬住了,还好这是内部实现的东西,用户要是都保持对内部实现“眼不见心为 ...

驱动的内部实现要么固化在芯片的专用ROM里,要么是.a形式发布的,没的看。

出0入0汤圆

发表于 2013-10-15 09:10:41 | 显示全部楼层
对抗这一点,我很有心得:
1、绝对不推广——好东西要别人自己来用
2、保持宏一定要好用,能偷懒,傻瓜才不用
3、保持规则一致且简单,既然为了偷懒,当然简单好记,规则统一才行
4、终极解决目标——代码生成器——如果代码都能替你生成了,鬼才管你用了多少宏呢
______________________________________________________________________________
我觉得傻孩子大侠说的很对!可能有很多人评论之前都没有仔细的研究过代码,就在此发泄情绪,这是不对的啦!

我是个菜鸟,所以我说话会更谨慎一下,因为我知道自己懂的有限!希望广大菜鸟同志,先跟我一起学习宏定义。。。c语言,然后再来写一些客观实在的评论!

虽说楼主要大家吐槽,但是大家在吐完畅快之后能不能顺便也应该发现点优点啊。

最后想起一句话:
为什么大家对对陌生人有那么客气,自己熟知的人这么苛刻呢?


出0入0汤圆

发表于 2013-10-15 09:12:47 | 显示全部楼层
1、绝对不推广——好东西要别人自己来用
2、保持宏一定要好用,能偷懒,傻瓜才不用
3、保持规则一致且简单,既然为了偷懒,当然简单好记,规则统一才行
4、终极解决目标——代码生成器——如果代码都能替你生成了,鬼才管你用了多少宏呢
______________________________________________________________________________
我觉得傻孩子大侠说的很对!可能有很多人评论之前都没有仔细的研究过代码,就在此发泄情绪,这是不对的啦!

我是个菜鸟,所以我说话会更谨慎一下,因为我知道自己懂的有限!希望广大菜鸟同志,先跟我一起学习宏定义。。。c语言,然后再来写一些客观实在的评论!

虽说楼主要大家吐槽,但是大家在吐完畅快之后能不能顺便也应该发现点优点啊。

最后想起一句话:
为什么大家对对陌生人有那么客气,自己熟知的人这么苛刻呢?


出0入0汤圆

发表于 2013-10-15 09:24:32 | 显示全部楼层
YuWan 发表于 2013-10-13 16:47
菜鸟一枚,看见很多宏技巧都要用到 do{...}while(0); 这个结构,但我一直都不明白这个的用意。
大神,能否 ...

你要回去好好看c语言书了

do {} 后面花括号里面必须执行一次

然后检测 while(0);  是否循环

出0入0汤圆

发表于 2013-10-15 09:31:38 | 显示全部楼层
我,今天,就及其不负责任的发泄一下情绪:
“一,愿天下所有不爱用宏的人,天天遇到大型项目”
“二,愿天下所有爱展开宏的人,天天遇到高度封装的Framework”
“三,愿天下所有不放心使用黑盒子的人,写的代码天天被别人怀疑”

最后:
“愿天下所有 不看到宏展开会死星人,一辈子被以上三条困惑”
_____________________________________________________________________
楼主不淡定啊!

其实用宏有很多好处的,现在虽然只是用到了初级的宏定义,但是对于程序的修改、移植而言,方便性很大啊!还有大家看国外的一些优秀代码也用到了很多宏,总之我觉得这个需要学习和理解的过程。
就像大家当初都学51,后来都去学STM32去了,是个不断进化的过程吧!
借用那位高人说的一句话,谁用谁知道!






出0入0汤圆

发表于 2013-10-15 09:36:25 | 显示全部楼层
呼呼。。。看完评论了,全是高手过招,我等菜鸟赶快闪,以免误伤

出0入0汤圆

发表于 2013-10-15 09:43:38 | 显示全部楼层
只要是系统性的,什么风格都无所谓……
厂家或编译器提供的就是系统性的,像ST,TI,芯唐的M3/M0系列驱动库,风格迥异,尤其是芯唐,一个芯片一种库……但是第一次接触都感觉很容易上手。需要做个什么项目,拷贝个模板或者例程,改改就能直接编译、下载调试了……

楼主这个,说实在的不看好……首先个人维护一个驱动库难度是极大的,技术上可能好说,但是工作量、测试这些都是个人极难完成的。

出0入0汤圆

发表于 2013-10-15 09:56:34 | 显示全部楼层
Gorgon_Meducer 发表于 2013-10-13 15:01
你说的很对,但我就是芯片提供商……我不提供这个……谁提供……?
芯片是Cortex M系列的芯片,所以估计 ...

刚才还没看到这一贴……
原来LZ就是做ST、TI、芯唐同样的工作。那建议LZ还是把库分为两层好了……底层跟别人完成同样的功能,中间层组件其实可有可无的,像我们这样的公司,串口、SPI、I2C……常用的接口都有自己的中间层组件,在新的IC上,只需厂家提供个xxx_init()以及读写收发寄存器的例程就OK了。
如果LZ的IC也跟STM32类似(外设很多、管脚有限、各种排斥……),搞一个跟C8051图形配置工具可能更实用

出0入296汤圆

 楼主| 发表于 2013-10-15 12:08:16 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-10-15 12:24 编辑
mhw 发表于 2013-10-15 09:43
只要是系统性的,什么风格都无所谓……
厂家或编译器提供的就是系统性的,像ST,TI,芯唐的M3/M0系列驱动库, ...


库不是一个人在维护,是一个团队在维护,我只负责管理风格,质量审核和核心构架。所以维护难度不是问题。
你的意见很好,能不能说的具体一点呢?不好看是不好看在什么地方呢?易用性如何呢?可读性如何呢?

你觉得1楼提供的两个风格中,C的经典风格怎么样呢?非常期待你的反馈。

出0入296汤圆

 楼主| 发表于 2013-10-15 12:08:31 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-10-15 12:18 编辑
mhw 发表于 2013-10-15 09:56
刚才还没看到这一贴……
原来LZ就是做ST、TI、芯唐同样的工作。那建议LZ还是把库分为两层好了……底层跟 ...


图形配置工具是一定会有的。其实库是有三个层次,LV0固化在ROM里面,是最基础的构件,LV1和LV2分别是对基础构件的
二次封装和功能扩展,会不断以.a的形式发布更新,更新后的库会尽力保持接口不变。 未来LV1主要专注于提供更便捷的驱动
级服务,比如用定时器封装出直接的舵机控制器模块,无刷电机驱动模块,列波发生模块,多路司服电机同步运动控制模块……
SMBus的驱动模块,SD卡读写模块等等……LV2专注于协议栈及协议栈与LV1的集成,比如提供USB Mass storage的中间件,可以与
SD卡读写模块直接对接,与各类FLASH模块(比如SPI Flash)对接,实现存储器功能,U盘,读卡器等等;比如提供FAT32
中间件,与底层的存储器模块对接,或者SD卡读写模块对接,实现方便的SD卡文件存取,等等……

所有这些模块,最后都会提供图形化控件式的配置模型,方便用户托方式的开发,当然在后面的版本中,用户将可以
通过图形工具利用已有的模块组合出新的模块,或者完全从0开始开发自己的模块控件——这里所提到的技术都是成熟
的技术,目前都只存在开发的劳动力问题,不存在技术上的实现难度。

出0入0汤圆

发表于 2013-10-15 14:58:29 | 显示全部楼层
Gorgon_Meducer 发表于 2013-10-15 12:08
库不是一个人在维护,是一个团队在维护,我只负责管理风格,质量审核和核心构架。所以维护难度不是问题。 ...

是公司行为就没问题了。
至于风格,我是觉得两种都无所谓,移植过的代码多了适应能力比较强
风格能保持一致才是比较重要的,不要学芯唐,同一个芯片的不同版本的库都大相径庭(咨询得到的答复是人员变动)

出0入296汤圆

 楼主| 发表于 2013-10-15 15:37:53 | 显示全部楼层
mhw 发表于 2013-10-15 14:58
是公司行为就没问题了。
至于风格,我是觉得两种都无所谓,移植过的代码多了适应能力比较强
风格 ...

明白了,我们会努力保持接口的一致性的,团队以及后续的成员都会经过我的培训才能上岗,
所以风格上会师承我的思想,芯片名字的三个字母上还有我的“G”,这些都不会改变。

出0入0汤圆

发表于 2013-10-15 15:47:55 来自手机 | 显示全部楼层
个人觉得posix标准就很好,要想简单的话,arduino不知可否成为标准

出0入296汤圆

 楼主| 发表于 2013-10-15 16:11:55 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-10-15 16:34 编辑
avr-arm 发表于 2013-10-15 15:47
个人觉得posix标准就很好,要想简单的话,arduino不知可否成为标准


会独立推出一个arduino的库。个人觉得posix的标准对MCU稍微有点“过”了,不过我会认真考虑使用posix的可能性。

出0入296汤圆

 楼主| 发表于 2013-10-24 10:22:35 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-10-24 10:29 编辑

根据各位调查的意见,更新了编码风格。
使用

  1. IO_CFG (
  2.     ...
  3. );

  4. SPI_CFG (
  5.     ...
  6. );
复制代码
取代原先的

  1. IO_CFG {
  2.     ...
  3. } END_IO_CFG;

  4. SPI_CFG(...) {
  5.    ...
  6. } END_SPI_CFG(...)
复制代码
使其更符合C语言的风格和习惯,并在IO配置中尝试增加表格式的配置风格。
详情请参考楼主位和1楼。

出0入296汤圆

 楼主| 发表于 2013-11-6 18:37:51 | 显示全部楼层
解决了原本让人很看不懂的系统分频参数问题。
现在用 SPI_PCLK_DIVn 来替代

出0入0汤圆

发表于 2013-11-15 15:22:54 | 显示全部楼层
嗯,回去把高焕堂老师的那本书再翻一遍。。。

出0入0汤圆

发表于 2013-12-18 10:49:07 | 显示全部楼层
Gorgon_Meducer 发表于 2013-10-12 12:29
这其实也说明一个问题,为了减小这个 ”首次接触“ 的门槛,我需要在文档或者其他方面加入必要的辅助,
...

这个出来了吗?在那里可以看我想看看

出0入296汤圆

 楼主| 发表于 2013-12-18 12:14:19 | 显示全部楼层
wazhiyi 发表于 2013-12-18 10:49
这个出来了吗?在那里可以看我想看看

具体哪个?能说的明确一些么?

出0入0汤圆

发表于 2013-12-18 12:54:59 | 显示全部楼层
"我计划在网站上加入Wizard形式的图文教程"
你的网站在那里?
图文教程有吗?

出0入296汤圆

 楼主| 发表于 2013-12-18 15:04:55 | 显示全部楼层
wazhiyi 发表于 2013-12-18 12:54
"我计划在网站上加入Wizard形式的图文教程"
你的网站在那里?
图文教程有吗? ...

网站还没上线呢。到时候我会高调宣传的。就现有的接口,吐吐槽吧。

出0入0汤圆

发表于 2013-12-18 20:17:26 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-18 15:04
网站还没上线呢。到时候我会高调宣传的。就现有的接口,吐吐槽吧。

你好,今天看了一天你的帖子。
晚上的时候,我想谢谢代码测试一下。
发现你的代码中

//! \name class: spi_t
//! @{
DEF_INTERFACE(spi_t)

中的“DEF_INTERFACE”的定义是什么?

#include ".\app_cfg.h"
#include ".\i_io_spi.h"

还有这几个头文件有吗?可以提供共享一下吗?

出0入0汤圆

发表于 2013-12-19 09:10:17 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-18 15:04
网站还没上线呢。到时候我会高调宣传的。就现有的接口,吐吐槽吧。

兄台,我在把你的设计思想移植到STM32上面。
其中问题如下:
1、SPI.c
文件中的ROOT的宏定义是什么?

出0入0汤圆

发表于 2013-12-19 09:16:03 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-18 15:04
网站还没上线呢。到时候我会高调宣传的。就现有的接口,吐吐槽吧。

还有
2、SPI.c
中用到的spi_reg_t
的定义时候如下

//! \name SPI Register
//! @{
typedef struct {
    volatile uint32_t CR0;
    volatile uint32_t CR1;
    volatile uint32_t SR;
    volatile uint32_t DR;
    volatile uint32_t CPSR;
    volatile uint32_t RXCRCR;
    volatile uint32_t TXCRCR;
    volatile uint32_t I2SCFGR;
    volatile uint32_t I2SPR;
}spi_reg_t;

出0入0汤圆

发表于 2013-12-19 15:37:03 | 显示全部楼层
有谁知道 文件中的ROOT的宏定义是什么?

出0入296汤圆

 楼主| 发表于 2013-12-19 19:13:39 | 显示全部楼层
wazhiyi 发表于 2013-12-19 09:10
兄台,我在把你的设计思想移植到STM32上面。
其中问题如下:
1、SPI.c

IAR环境下,ROOT是__root,用来强制编译器产生对应的函数和变量。

出0入0汤圆

发表于 2013-12-19 19:15:24 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 19:13
IAR环境下,ROOT是__root,用来强制编译器产生对应的函数和变量。

避免被优化掉是吧,MDK有没有类似的语法?

出0入296汤圆

 楼主| 发表于 2013-12-19 19:15:47 | 显示全部楼层
wazhiyi 发表于 2013-12-19 09:16
还有
2、SPI.c
中用到的spi_reg_t

你具体的问题是什么呢?

出0入296汤圆

 楼主| 发表于 2013-12-19 19:16:31 | 显示全部楼层
wazhiyi 发表于 2013-12-19 19:15
避免被优化掉是吧,MDK有没有类似的语法?

这个其实可以去掉,我加入ROOT是为了做.a文件的时候保证没有用到的接口也能生成。你普通的Library不需要ROOT

出0入0汤圆

发表于 2013-12-19 19:20:25 | 显示全部楼层
基于STM32的IO配置

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-12-19 19:21:24 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 19:16
这个其实可以去掉,我加入ROOT是为了做.a文件的时候保证没有用到的接口也能生成。你普通的Library不需要R ...

理解了,非常感谢。
上面是我基于STM32写的IO配置程序,可以帮我看一下,是否理解到位?

出0入296汤圆

 楼主| 发表于 2013-12-19 19:22:21 | 显示全部楼层
wazhiyi 发表于 2013-12-19 19:21
理解了,非常感谢。
上面是我基于STM32写的IO配置程序,可以帮我看一下,是否理解到位? ...

求clean以后再发……8M太大了……

出0入0汤圆

发表于 2013-12-19 19:24:36 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 19:22
求clean以后再发……8M太大了……

呵呵,不好意思啊

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-12-19 19:25:48 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 19:22
求clean以后再发……8M太大了……

核心部分代码

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入296汤圆

 楼主| 发表于 2013-12-19 19:33:57 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2013-12-19 19:39 编辑


对于返回值是fsm_rt_t的函数,说明该函数是状态机,因此不能存在阻塞代码,你在idle和close里面使用了while死等
这是不符合要求的。对于非阻塞代码,比如SPI0.Close,只要调用的时候加一个while就可以将其转化成阻塞代码,但
是反过来就不行了,所以尽可能编写非阻塞代码。

另外,你在spi_cfg_t里面,使用了大量的配置变量,这是不必要的,一般一个uint32_t类型的wMode就可以了,这个
wMode会把一些位常数组合在一起,配置寄存器的时候方便使用。使用wMode的好处是,你可以简化要配置的内容
有时候某些选项不需要出现,就不用专门去配置,这就是用"|"操作的好处,你分开了,作为结构体成员了,那么就是
每次都要配置了,不适合简化应用。当然结构体在初始化的时候也可以省略后续的内容,系统会自动补0,我有时候
也用这个技巧,但这就存在重要性的问题,如果某个重要的参数出现在初始化列表的最后,那么中间部分就必须要
初始化了。

其它内容基本符合。也真佩服你找到我以前的代码模板,幸好我修正不是太多。这里说一下,一般driver是要放在
hal里面的……你放在外面估计也就是为了简单验证下,还没有处理framework的层次架构问题吧。

出0入0汤圆

发表于 2013-12-19 19:37:03 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 19:33
对于返回值是fsm_rt_t的函数,说明该函数是状态机,因此不能存在阻塞代码,你在idle和close里面使用了whi ...

1、关于“非阻塞代码”的问题。
我感觉你说的非常有道理,是的,阻塞代码的等待标志位的事情应该交给在上一层的代码解决。
2、

出0入0汤圆

发表于 2013-12-19 19:48:21 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 19:33
对于返回值是fsm_rt_t的函数,说明该函数是状态机,因此不能存在阻塞代码,你在idle和close里面使用了whi ...

对于第二点,从内存占用上来说,是比较笨的方法,但是和与开关相比,我感觉可能还是这样子的好。
1、如果让上层代码来进行与或开关配置的话,可能会出现误差,毕竟不是很直观,另外你还要把底层驱动层的很多MASK标志位开放给上层。
上层应用者拿到的代码信息量比较大,甚至还是要去看DS手册。
2、配置信息,分化的好处就是用户很直观的看到这些信息,直接赋值。
另外你说的“简化应用”的问题,我感觉如果把不需要的配置项直接赋予初值,就可以了,也就是默认选项。

“也真佩服你找到我以前的代码模板,幸好我修正不是太多。这里说一下,一般driver是要放在
hal里面的……你放在外面估计也就是为了简单验证下,还没有处理framework的层次架构问题吧。”

呵呵,找了两天,从网上查的资料,有一些定义来自ASF是吧,我专门把ASF下载下来看了一下。

是的这个是简单的验证,是要放在硬件抽象层里面。
framework的层次架构,打算接下来在弄。。。。

把你的帖子都看了一遍,信息量太大了,要慢慢消化。。。。

你的新书进行的怎么样了,很希望能接收你的进一步熏陶了。。。。

出0入0汤圆

发表于 2013-12-19 19:49:32 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 19:33
对于返回值是fsm_rt_t的函数,说明该函数是状态机,因此不能存在阻塞代码,你在idle和close里面使用了whi ...

关于framework,有没有帖子专门讨论呢?

出0入0汤圆

发表于 2013-12-19 19:53:10 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 19:33
对于返回值是fsm_rt_t的函数,说明该函数是状态机,因此不能存在阻塞代码,你在idle和close里面使用了whi ...

IAR倒是支持
struct spi_cfg_t tgSPI =
{
        .hwMode = 0x0400;
};
的语法,但是MDK目前不支持,不知道以后会不会支持

出0入0汤圆

发表于 2013-12-19 19:54:58 | 显示全部楼层
本帖最后由 wazhiyi 于 2013-12-19 19:57 编辑
Gorgon_Meducer 发表于 2013-12-19 19:33
对于返回值是fsm_rt_t的函数,说明该函数是状态机,因此不能存在阻塞代码,你在idle和close里面使用了whi ...


关于UART通讯协议类的构架,你有没有什么想法呢?

----- MCU硬件中断

----- 协议封装层 “协议头--字节数量--数据---校验和---协议尾”

----- 协议数据层  分析数据,把数据缓存在链表中


----- 主任务里面检测到数据链表中有数据的时候,处理数据


感觉不是很系统

出0入0汤圆

发表于 2013-12-19 20:28:10 | 显示全部楼层
我喜欢黑盒子模式,我顶多会去看几个自己关心的函数实现

Interface的清晰是最重要的,至于Implement是否最优相对次要得多,库的风格应尽量小对用于App的影响
因为Lib的团队一直在maintain的是Implement,肯定能每个版本都比上个版本改进一截
Interface基本应该是雷打不动的,即使加强也要向后兼容,不到万不得已不可另起炉灶

出0入296汤圆

 楼主| 发表于 2013-12-19 21:53:19 | 显示全部楼层
wazhiyi 发表于 2013-12-19 19:54
关于UART通讯协议类的构架,你有没有什么想法呢?

----- MCU硬件中断

我有一个Component叫SimpleFrame,专门负责进行帧解析——当然是我自己定义的帧结构。
帧的前端接口是PIPE,任何可以封装成PIPE的串行数据接口,包括USART,SPI,I2C, USB都可以
将数据通过PIPE与帧解析对接,帧解析算是前端。
根据需要,我有一些中间件,不同中间件有自己的协议以及消息地图接口,这里就不多说了。
我的整个处理都是状态机架构的,所以不存在阻塞的问题,同时也是放在主循环里面的。PIPE
是一个线程安全的结构,因为,对于串行通信底层是不是硬件中断实现的,不敏感。

出0入296汤圆

 楼主| 发表于 2013-12-19 21:58:16 | 显示全部楼层
wazhiyi 发表于 2013-12-19 19:48
对于第二点,从内存占用上来说,是比较笨的方法,但是和与开关相比,我感觉可能还是这样子的好。
1、如果 ...

MSK标志其实是可以通过枚举或者宏的方式封装的,对上层来说看到的只是其代表的意义而不是数字值
本身,同时借助宏的帮助,可以把一些MSk联合起来,赋予更为直观的意义,这就形成了Template。
所以你担忧的问题其实不是那个样子。我从来不支持将寄存器的位定义直接公开,我提倡配置信息要更
贴近和符合接口的功能本身,为了达到对应的配置,我们要进行必要的封装。
用枚举或者宏封装起来的不是MSK本身,而是一个逻辑意义,这就允许当底层硬件发生变化时,仍能使
用相同的宏和枚举来传递信息,对驱动来说,只要遵守的是与应用相同的接口,那么实现对应的枚举和
宏所代表的的意义也没有什么太大的问题。

出0入296汤圆

 楼主| 发表于 2013-12-19 21:58:47 | 显示全部楼层
McuPlayer 发表于 2013-12-19 20:28
我喜欢黑盒子模式,我顶多会去看几个自己关心的函数实现

Interface的清晰是最重要的,至于Implement是否最 ...

对现在的接口,你有什么看法呢?很想听听你的意见。

出0入296汤圆

 楼主| 发表于 2013-12-19 21:59:33 | 显示全部楼层
wazhiyi 发表于 2013-12-19 19:53
IAR倒是支持
struct spi_cfg_t tgSPI =
{

避免使用ANSI-C99不支持的语法。不然会影响到代码的可移植性。

出0入0汤圆

发表于 2013-12-19 22:19:31 | 显示全部楼层
Gorgon_Meducer 发表于 2013-12-19 21:53
我有一个Component叫SimpleFrame,专门负责进行帧解析——当然是我自己定义的帧结构。
帧的前端接口是PIP ...

MCU中,什么是“线程安全的结构”?
怎么样来保证“线程安全”呢?

出0入0汤圆

发表于 2015-8-9 23:10:52 | 显示全部楼层
mark一下。IO配置

出0入296汤圆

 楼主| 发表于 2015-8-10 13:44:40 | 显示全部楼层
本帖最后由 Gorgon_Meducer 于 2015-8-10 13:46 编辑
wazhiyi 发表于 2013-12-19 22:19
MCU中,什么是“线程安全的结构”?
怎么样来保证“线程安全”呢?


这要从线程抢占式上下文切换的基本原理入手了,一般ARM的OS会用SysTick、PendSV来实现抢占式的上下文切换。
那基本上屏蔽全局中断,或者说PRIMASK就可以确保线程安全了。当然,如果你想减小这种大杀器对实时性的影响
可以在允许的情况下,将SysTick和PendSV配置为比其它中断的优先级都低,其中,PendSV要做到优先级最低。这
种情况下,当你想确保线程安全时修改BASEPRI的级别就可以做到只屏蔽系统强占式调度,但是确保其它中断不被
影响,当然别忘记在出了临界区以后要将BASEPRI恢复。

希望这些信息对你有所帮助。

出0入0汤圆

发表于 2016-12-9 10:17:35 | 显示全部楼层
特别有借鉴意义的帖子,换个周末继续研读~
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 21:08

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表