Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[drv_spi] 将等待spi传输完成的方式从死等变为阻塞线程的形式 #5582

Closed
wants to merge 4 commits into from

Conversation

qingehao
Copy link
Contributor

拉取/合并请求描述:(PR description)

[
原来等待spi传输完成的方式为死等,在spi速度慢且传输大量数据时,会一直占用CPU,导致其他任务无法运行。
现改为通过等待事件的方式,阻塞掉当前调用spi传输的线程,使得其他任务得以运行。

在STM32F411CEU6上使用LVGL SPI1-DMA方式刷屏,并通过SPI2读取FLASH的应用上测试通过。
]

以下的内容不应该在提交PR时的message修改,修改下述message,PR会被直接关闭。请在提交PR后,浏览器查看PR并对以下检查项逐项check,没问题后逐条在页面上打钩。
The following content must not be changed in the submitted PR message. Otherwise, the PR will be closed immediately. After submitted PR, please use a web browser to visit PR, and check items one by one, and ticked them if no problem.

当前拉取/合并请求的状态 Intent for your PR

必须选择一项 Choose one (Mandatory):

  • 本拉取/合并请求是一个草稿版本 This PR is for a code-review and is intended to get feedback
  • 本拉取/合并请求是一个成熟版本 This PR is mature, and ready to be integrated into the repo

代码质量 Code Quality:

我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:

  • 已经仔细查看过代码改动的对比 Already check the difference between PR and old code
  • 代码风格正确,包括缩进空格,命名及其他风格 Style guide is adhered to, including spacing, naming and other styles
  • 没有垃圾代码,代码尽量精简,不包含#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up
  • 所有变更均有原因及合理的,并且不会影响到其他软件组件代码或BSP All modifications are justified and not affect other components or BSP
  • 对难懂代码均提供对应的注释 I've commented appropriately where code is tricky
  • 本拉取/合并请求代码是高质量的 Code in this PR is of high quality
  • 本拉取/合并使用formatting等源码格式化工具确保格式符合RT-Thread代码规范 This PR complies with RT-Thread code specification

@Guozhanxin
Copy link
Member

很棒👍

static struct stm32_spi spi_bus_obj[sizeof(spi_config) / sizeof(spi_config[0])] = {0};

static void rthw_spi_wait_completed(struct stm32_spi *spi);
static void set_wait_event(struct stm32_spi *spi,enum T_R_TYPE tx_rx_type);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

, 后面都需要有空格的,后面的代码也是

static void set_wait_event(struct stm32_spi *spi, enum T_R_TYPE tx_rx_type);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

switch((int)(hspi->Instance))
{
#ifdef BSP_USING_SPI1
case (int)SPI1:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case这里的代码,也和规范不太一样,可以参考编码规范里的格式化说明
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

好的

1.调整格式.
2.在不使用DMA情况.仍然采用死等的方式,避免在未开启DMA情况下,event无法发送.
@thewon86
Copy link
Contributor

每个 spi 总线都有一个 struct stm32_spi 结构体变量的吧,因此,各个 wait_event 变量是独立的。
XXX_TxRxCplt_EVENT
XXX_TxCplt_EVENT
XXX_RxCplt_EVENT
这几个宏定义一个就够了吧。
set_wait_event 函数也不用区分是哪个总线。

@qingehao
Copy link
Contributor Author

每个 spi 总线都有一个 struct stm32_spi 结构体变量的吧,因此,各个 wait_event 变量是独立的。 XXX_TxRxCplt_EVENT XXX_TxCplt_EVENT XXX_RxCplt_EVENT 这几个宏定义一个就够了吧。 set_wait_event 函数也不用区分是哪个总线。

spi_event的事件控制块是所有总线共用的,假设宏定义使用统一的SPI_XXXXCplt_Event,当SPI1总线等待传输完成事件(SPI_XXXXCplt_Event)的时候,别的线程调用SPI2总线传输数据,SPI2数据量很小,很快完成了,SPI2会调用spi_event发送SPI_XXXXCplt_Event事件。此时,如果使用SPI1总线的优先级较高,则SPI1总线收到了该事件,会认为是它完成了传输,造成了冲突。

@qingehao qingehao closed this Feb 10, 2022
@qingehao qingehao reopened this Feb 10, 2022
@mysterywolf
Copy link
Member

666666666

@thewon86
Copy link
Contributor

struct stm32_spi

spi1总线有个 struct stm32_spi 结构体变量对应 spi1 总线控制。spi2总线也有个 struct stm32_spi 结构体变量对应 spi2 总线控制。
struct stm32_spi 里第一个元素 handle 肯定不会是所有 spi 总线共用的吧。wait_event 元素变量也肯定不会是所有 spi 总线共用了。

@qingehao
Copy link
Contributor Author

qingehao commented Mar 9, 2022

抱歉,最近忙没看到。我明白你的意思的,现在我的event控制块不是定义在stm32_spi结构体中,意味着系统中所有总线共用这个event控制块,所以等待的事件需要区分开哪一个总线。你说的可以将event控制块定义在总线结构体中,这样子每个总线拥有一个事件控制块,这样子也可以,两种方式。

#endif
#ifdef BSP_USING_SPI3
case (int)SPI3:
event = SPI3_RxCplt_EVENT;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

今天又看了一遍这个pr,感觉添加了好多代码。这些针对不同SPI的适配可以再抽象一下吗?目前这种模式,如果再添加一路SPI,感觉要修改好多地方。很有可能遗漏掉。可维护性感觉有些下降了。

#ifdef BSP_USING_SPI6
#define SPI5_TxRxCplt_EVENT (1 << 16)
#define SPI5_TxCplt_EVENT (1 << 17)
#define SPI5_RxCplt_EVENT (1 << 18)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stm32系列有没有可能超过10路啊,目前这种模式,如果超过10路,这边的值好像就不够用了

@Guozhanxin Guozhanxin added the discussion This PR/issue needs to be discussed later label Mar 21, 2022
@BreederBai
Copy link
Contributor

能否把在bus中添加一个完成量,做高层次的抽象,是否使用阻塞线程方式由底层驱动自己去实现
image

@mysterywolf mysterywolf marked this pull request as draft September 29, 2022 05:32
@mysterywolf mysterywolf marked this pull request as ready for review October 12, 2022 22:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion This PR/issue needs to be discussed later
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants