准确的说,其实也不能算是硬件设计的问题,而是rust在倒逼一切,逼到硬件设计上也得遵循它的生命周期管理的规范...
我这个问题其实很简单,比如我有几个同构的模块需要驱动,在固件里肯定是把它们封装起来的。
但这些模块有一个enable pin,因为虽然你也不能排除单独启动其中一个关闭另一个的需求,但一般是所有模块都要启动的。刚好这块板子gpio口很紧张,我就把几个模块的enable pin合并到一块去了。
然后在固件里封装自然就遇到问题了...因为rust不让我很轻松的share这个pin...
其实我本来是想的挺好的,我就写个sharedpin,在里面做了个引用计数,减到0才会disable这个pin。这样share 1个en的时候跟直接使用一模一样,而多次share也不会产生恶性问题,一切都挺合理。然后首先这样搞肯定是mutable了,多重mutable引用肯定是不可以的。那么规范的做法就是arc/rc + mutex。但嵌入式环境是no_std会有很多限制。虽然这些不依赖std但也会依赖alloc,我也不太想在嵌入式系统中动态分配内存所以否决。然后我用refcell封装了一下把sharedpin对外变成immutable。然而虽然消除了多重可变引用问题,但毕竟还是需要引用的,那封装的时候就必须要声明生命周期...然后因为这个pin相当的底层,这个生命周期声明就被传播的到处都是...其实本来我也是想捏着鼻子就这么算了,反正standalone版本编译也过了。但后面还有个用rtic框架的版本,这个时候rtic又不允许我这么搞了,因为它有它自己的资源管理机制,不允许我声明生命周期...所以如果要在rtic下用,我就得迭代设计,把这个sharedpin做成一个独立的task拎出来单独管理...想了想为了share一个pin这尼玛实在是太杀鸡用牛刀了。我抄起板子改了下线,每个模块一人一个enable这样就消停了....
讲真,用c写会觉得共享个pin多大事,虽然有点小问题,也就是留个心眼的事嘛。谁想到rust下会引出这么多的麻烦...但你想怪rust吧,它也没任何问题,恰恰相反它正确的很,实在是太tm正确了... standalone版本虽然丑,但人家把生命周期管理的好好的,没任何毛病啊。然后换rtic框架之后就不再是简单的standalone了,自然得按照rtic的设计把它分离成一个task重新设计架构,也非常的合理...
所以搞了一天我有点脱力...要么en一人一个,要么不要封en...
但en一人一个如果来10个模块那岂不是要浪费10个pin;反过来不封en,哪有调用一个库还需要在外面单独使能下的...这叫啥鸡毛封装嘛...
所以我一直想找个各方面都完美的方法。结果折腾了一天还是回到了起点...
【 在 jyw 的大作中提到: 】
: Rust 前景非常看好,相信以后会有越来越多项目从 c++ 甚至 c 转向 Rust,系统编程语言这块最有前景,除此之外系统工具领域也不输 Go,需要高性能的其他业务场景应该也能也能有一席之地。
: 通过他还能发现硬件设计的问题,这个一般还真想不到,意外的惊喜……
:
--
修改:lvsoft FROM 117.89.220.*
FROM 117.89.220.*