硬汉嵌入式论坛

 找回密码
 立即注册
查看: 1205|回复: 13
收起左侧

[STM32H7] 在FreeRTOS中使用24C02的疑惑

[复制链接]

8

主题

33

回帖

57

积分

初级会员

积分
57
发表于 2024-7-30 10:52:16 | 显示全部楼层 |阅读模式
在FreeRTOS中使用24C02,使用HAL库提供的硬件IIC接口,当要写入的字节大于8(分页数)时,需要延时5ms
疑问1:优先使用HAL_Delay还是osDelay?这两个遇到高优先级中断会不会影响写入时序?


疑问2:有个方案是挂起调度器,这个时候还应该停止所有中断?



回复

使用道具 举报

12

主题

218

回帖

254

积分

高级会员

积分
254
发表于 2024-7-30 14:26:40 | 显示全部楼层
疑问1: osDelay,
疑问2: 挂起调度器? 不要这么做,比如有紧急的中断,这时候无法响应该中断。5ms太长了。
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
115490
QQ
发表于 2024-7-30 15:22:44 | 显示全部楼层
此贴方案

第9期ThreadX视频教程:自制个微秒分辨率任务调度实现方案(2023-10-11)
https://www.armbbs.cn/forum.php? ... 1371&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

14

主题

243

回帖

285

积分

高级会员

积分
285
发表于 2024-7-30 15:55:50 | 显示全部楼层
个人对1使用osDelay有一定的疑问,因为osDelay会引发任务切换,如果另一个任务也正好需要写入24c02,会不会跟这个任务产生冲突?
回复

使用道具 举报

12

主题

218

回帖

254

积分

高级会员

积分
254
发表于 2024-7-30 16:03:52 | 显示全部楼层
zhang0352505 发表于 2024-7-30 15:55
个人对1使用osDelay有一定的疑问,因为osDelay会引发任务切换,如果另一个任务也正好需要写入24c02,会不会 ...

会。
如果想要当前任务独占读、写EEPROM操作,就要加入互斥。

举个例子,A、B、C三个任务都可以进行EEPROM读写操作。为了防止不同任务操作EEPORM地址时读写冲突,必须加入互斥这种原子操作。

可以这样实现。 EEPROM接口增加一个互斥变量,读写EEPROM时检查该互斥变量是否释放,如果释放则进入下一步操作,如果没有释放,就根据传入的超时时间等在那里。

回复

使用道具 举报

14

主题

243

回帖

285

积分

高级会员

积分
285
发表于 2024-7-30 16:07:33 | 显示全部楼层
本帖最后由 zhang0352505 于 2024-7-30 16:08 编辑
yunqi 发表于 2024-7-30 16:03
会。
如果想要当前任务独占读、写EEPROM操作,就要加入互斥。

引入互斥会增加程序的复杂性,我感觉不容易把握,会出现其他的问题。
所以,我更倾向与直接用HAL_Delay(),死等。
回复

使用道具 举报

3

主题

295

回帖

304

积分

高级会员

积分
304
发表于 2024-7-30 16:23:37 | 显示全部楼层
如果读写eeprom任务是最高优先级,osdelay是直接让出cpu给低优先级任务,时间到了再切回来;HAL_Delay是死等,最高优先级不会被其他任务抢占。这两个都是会被高优先级中断打断的。
hal库里很多函数都是用HAL_GetTick来计时,操作超时了就进错误处理,这时候要注意如果在用hal库的时候被切到其他任务而且长时间没切回来,等切回来可能就会进错误处理,所以像你这样需要等5ms以上的情况停止中断或者挂起调度器都不太好
回复

使用道具 举报

3

主题

295

回帖

304

积分

高级会员

积分
304
发表于 2024-7-30 16:26:15 | 显示全部楼层
处理办法就是楼上说的,用osdelay,并且在比较关键的地方加入互斥
回复

使用道具 举报

3

主题

295

回帖

304

积分

高级会员

积分
304
发表于 2024-7-30 16:42:36 | 显示全部楼层
zhang0352505 发表于 2024-7-30 15:55
个人对1使用osDelay有一定的疑问,因为osDelay会引发任务切换,如果另一个任务也正好需要写入24c02,会不会 ...

hal库对同一个i2c或者其他外设提供简单的互斥处理,hal库里的state变量就用来处理这个的
回复

使用道具 举报

9

主题

156

回帖

183

积分

初级会员

积分
183
发表于 2024-7-30 20:31:02 | 显示全部楼层
24C02本来就不能连续写入的, 最大写入长度位Page。 如果要做互斥,最好在EEPROM_Write内部实现, 还不是外部实现。这样就有统一的接口
回复

使用道具 举报

14

主题

243

回帖

285

积分

高级会员

积分
285
发表于 2024-7-31 08:53:12 | 显示全部楼层
tcs_stm32 发表于 2024-7-30 20:31
24C02本来就不能连续写入的, 最大写入长度位Page。 如果要做互斥,最好在EEPROM_Write内部实现, 还不是外 ...

哎,要想有统一接口,就要把24C02封装成一整个模块,既然它不能同时写入,就把它变成串行模块,
这个模块接收所有写入数据的要求,然后按照先来后到,把所有要写的数据列个队,挨个写入,优先级
也不用太高,由于是模块自动整合写入了,所以也不用mutex锁了,直接用osDelay就可以,切换就切换
呗,但是有一个问题,就是要有处理结果回调,调用写入的操作需要知道结果。
回复

使用道具 举报

12

主题

53

回帖

89

积分

初级会员

面霸

积分
89
发表于 2024-8-1 00:32:31 来自手机 | 显示全部楼层
zhang0352505 发表于 2024-7-31 08:53
哎,要想有统一接口,就要把24C02封装成一整个模块,既然它不能同时写入,就把它变成串行模块,
这个模 ...

这位大佬说的太好了
回复

使用道具 举报

14

主题

243

回帖

285

积分

高级会员

积分
285
发表于 2024-8-1 09:06:56 | 显示全部楼层
1350280419 发表于 2024-8-1 00:32
这位大佬说的太好了

其实任何方法都是有代价的,这种方法的代价就是,实时性降低了,因为本来可以快速执行的,变成排队了,很可能要阻塞很久才能存上,第二个代价就是增加了业务层的代码量,因为以前调用驱动就一句话就就行了,我看返回结果是什么,如果没存上,我再执行3次存,如果还是存不上,就放弃了,代码一直就是顺序逻辑的。但是有了回调,你得考虑回调怎么写,还有如果没存上,这个时候怎么处理?回调里面再去保存吗?那不成了嵌套了?我们也在探索代码究竟该如何写,只是楼主的提问,跟大家伙一起探讨一下罢了,没有绝对的好与坏
回复

使用道具 举报

8

主题

33

回帖

57

积分

初级会员

积分
57
 楼主| 发表于 2024-8-1 11:04:45 | 显示全部楼层
zhang0352505 发表于 2024-8-1 09:06
其实任何方法都是有代价的,这种方法的代价就是,实时性降低了,因为本来可以快速执行的,变成排队了,很 ...

是的,在讨论中我们可以进步,总能找到适合自己项目需求的方法
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-4-29 06:53 , Processed in 0.416282 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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