TCPIP and MAC thread task priorities

http://lwip.100.n7.nabble.com/TCPIP-and-MAC-thread-task-priorities-td28800.html


I was looking through my codebase recently (a mix of code from LPC Open, and also a project I inherited) and I saw a comment which I want to fact check:

/* TCPIP thread must run at higher priority than MAC threads! */

My software is using FreeRTOS. The Ethernet interrupt only signals a semaphore which wakes up the "MAC" thread. This thread handles incoming and outgoing packets on the ethernet hardware.

The comment implies that this MAC thread must run at a lower priority than the TCPIP thread. I don't know who wrote the comment, or if it is correct.

This posting 


indicates that there may not be such a stringent requirement, and it might even be advantageous to have the Ethernet task run at a higher priority than the TCPIP thread, but I'm not sure if the same applies to a MAC thread.

Thanks
- Wayne

 

_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Sylvain Rochet
497 posts
Hi Wayne, 

On Mon, Feb 27, 2017 at 01:56:24PM +1000, Wayne Uroda wrote:

> I was looking through my codebase recently (a mix of code from LPC Open, 
> and also a project I inherited) and I saw a comment which I want to fact 
> check: 

> /* TCPIP thread must run at higher priority than MAC threads! */ 

> My software is using FreeRTOS. The Ethernet interrupt only signals a 
> semaphore which wakes up the "MAC" thread. This thread handles incoming and 
> outgoing packets on the ethernet hardware. 

> The comment implies that this MAC thread must run at a lower priority than 
> the TCPIP thread. I don't know who wrote the comment, or if it is correct. 
> This posting
"must" is wrong, there is no such requirement. 


http://lists.nongnu.org/archive/html/lwip-users/2010-03/msg00148.html

> indicates that there may not be such a stringent requirement, and it might 
> even be advantageous to have the Ethernet task run at a higher priority 
> than the TCPIP thread, but I'm not sure if the same applies to a MAC thread. 

At first sight, if your TCPIP thread is busy handling packets from the 
message box there is little value of pushing more packets into it. But 
(there is always a but), if you do otherwise, if the TCPIP message box 
is full, you will enter a priority inversion condition and your RX 
thread will wait for a little while to queue the message or drop the 
packet. 

It means having your RX thread with a higher priority helps your system 
to fill the TCPIP thread message box, this is not the case if your RX 
thread have a lower priority than the TCPIP thread. 

So, I'm with Simon on that, your RX thread *should* have a higher 
priority than the TCPIP thread. Anyway, this is always the case for RX 
interrupt based systems. 


Sylvain 

_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users

  signature.asc (188 bytes)  Download Attachment
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Noam weissman
300 posts
Hi All, 

This comes from my own experience with STM micro that has Cortex-M core 
Running with FreeRTOS. It does apply to STM9 etc... 

TCP main task priority should be high priority. It should not be the highest priority but it should 
not be lower than other tasks that consume lots of time share. 

The most misunderstood issue is interrupt priority levels in Cortext-M and FreeRTOS. 

First of all: 
A lower number in Coretex means a higher priority while in FreeRTOS a higher number 
Means a higher priority. 

Secondly Cortex use a nesting interrupt and a smart level... Assume you set an interrupt to 
level 2 and try to run some critical section code from RS232 but that RS232 has an interrupt 
level set at 5. 

What happens is that the interrupt 2 (higher) will never be masked because the issuer of the 
Critical section runs at a lower interrupt level. 

FreeRTOS has lots of sections like this one: 

  portENTER_CRITICAL(); 
  {
     // some code 
  }
  portEXIT_CRITICAL(); 


If you set your interrupt level to be higher priority than the FreeRTOS timer tick that part will never 
Be masked and your critical section will not work as expected. 

I had strange problems and only after understanding the above I stabilized my software. 

I hope this is clear now. 

BR, 
Noam. 


-----Original Message----- 
From: lwip-users [mailto:lwip-users-bounces+noam= [hidden email]] On Behalf Of Sylvain Rochet 
Sent: Monday, February 27, 2017 1:02 PM 
To: Mailing list for lwIP users 
Subject: Re: [lwip-users] TCPIP and MAC thread task priorities 

Hi Wayne, 

On Mon, Feb 27, 2017 at 01:56:24PM +1000, Wayne Uroda wrote:

> I was looking through my codebase recently (a mix of code from LPC 
> Open, and also a project I inherited) and I saw a comment which I want 
> to fact 
> check: 

> /* TCPIP thread must run at higher priority than MAC threads! */ 

> My software is using FreeRTOS. The Ethernet interrupt only signals a 
> semaphore which wakes up the "MAC" thread. This thread handles 
> incoming and outgoing packets on the ethernet hardware. 

> The comment implies that this MAC thread must run at a lower priority 
> than the TCPIP thread. I don't know who wrote the comment, or if it is correct. 
> This posting

"must" is wrong, there is no such requirement. 


http://lists.nongnu.org/archive/html/lwip-users/2010-03/msg00148.html

> indicates that there may not be such a stringent requirement, and it 
> might even be advantageous to have the Ethernet task run at a higher 
> priority than the TCPIP thread, but I'm not sure if the same applies to a MAC thread. 

At first sight, if your TCPIP thread is busy handling packets from the message box there is little value of pushing more packets into it. But (there is always a but), if you do otherwise, if the TCPIP message box is full, you will enter a priority inversion condition and your RX thread will wait for a little while to queue the message or drop the packet. 

It means having your RX thread with a higher priority helps your system to fill the TCPIP thread message box, this is not the case if your RX thread have a lower priority than the TCPIP thread. 

So, I'm with Simon on that, your RX thread *should* have a higher priority than the TCPIP thread. Anyway, this is always the case for RX interrupt based systems. 


Sylvain 
_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Sylvain Rochet
497 posts
Hi, 

On Mon, Feb 27, 2017 at 11:50:26AM +0000, Noam Weissman wrote:

> Hi All, 

> This comes from my own experience with STM micro that has Cortex-M core 
> Running with FreeRTOS. It does apply to STM9 etc... 

> TCP main task priority should be high priority. It should not be the 
> highest priority but it should not be lower than other tasks that 
> consume lots of time share. 

> The most misunderstood issue is interrupt priority levels in Cortext-M 
> and FreeRTOS. 

> First of all: A lower number in Coretex means a higher priority while 
> in FreeRTOS a higher number Means a higher priority. 

> Secondly Cortex use a nesting interrupt and a smart level... Assume 
> you set an interrupt to level 2 and try to run some critical section 
> code from RS232 but that RS232 has an interrupt level set at 5. 

> What happens is that the interrupt 2 (higher) will never be masked 
> because the issuer of the Critical section runs at a lower interrupt 
> level. 

> FreeRTOS has lots of sections like this one: 

>   portENTER_CRITICAL(); 
>   {
>      // some code 
>   }
>   portEXIT_CRITICAL(); 


> If you set your interrupt level to be higher priority than the 
> FreeRTOS timer tick that part will never Be masked and your critical 
> section will not work as expected.
I don't understand any of this, portENTER_CRITICAL/portEXIT_CRITICAL 
proper implementation is to disable *ALL* interrupts, therefore having a 
critical section which is not enforced for whatever reason can't happen 
at all. 

By the way, FreeRTOS is not supposed to run with nested interrupts, you 
have to put all OS calls from interrupts (i.e. *FromISR() functions) in 
a critical section. 

Sylvain 

_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users

  signature.asc (188 bytes)  Download Attachment
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Sylvain Rochet
497 posts
Hi, 

On Mon, Feb 27, 2017 at 01:24:39PM +0100, Sylvain Rochet wrote:

> On Mon, Feb 27, 2017 at 11:50:26AM +0000, Noam Weissman wrote: 
> > 
> > If you set your interrupt level to be higher priority than the 
> > FreeRTOS timer tick that part will never Be masked and your critical 
> > section will not work as expected. 

> I don't understand any of this, portENTER_CRITICAL/portEXIT_CRITICAL 
> proper implementation is to disable *ALL* interrupts, therefore having a 
> critical section which is not enforced for whatever reason can't happen 
> at all.
To be more precise here, *ALL* interrupts which might call the FreeRTOS 
API, you indeed don't care for interrupts that are outside the FreeRTOS 
scope, which don't even need to be naked at all, and therefore can't 
wake up tasks. 


> By the way, FreeRTOS is not supposed to run with nested interrupts, you 
> have to put all OS calls from interrupts (i.e. *FromISR() functions) in 
> a critical section. 

Except if your FreeRTOS port support it, looks like some of them do :-) 


Anyway, this is a bit outside the initial subject. The RX thread (if 
any) should have a higher priority than the TCPIP thread, both 
priorities should obviously be within the allowed priorities window 
which only depend on your FreeRTOS port. 


Sylvain 

_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users

  signature.asc (188 bytes)  Download Attachment
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Noam weissman
300 posts
In reply to  this post by Sylvain Rochet
Dear Sylvain, 

If you issue portDISABLE_INTERRUPTS() it will mask all interrupts 

If you issue portENTER_CRITICAL() it will only mask interrupts that have a priority 
Lower than the FreeRTOS one interrupt. 

See these: 
    http://www.freertos.org/RTOS-Cortex-M3-M4.html

In this link check the paragraph that starts with Attention please!: 
    http://www.freertos.org/portcortexiar.html


    https://mcuoneclipse.com/2016/08/14/arm-cortex-m-interrupts-and-freertos-part-1/


BR, 
Noam. 




-----Original Message----- 
From: lwip-users [mailto:lwip-users-bounces+noam= [hidden email]] On Behalf Of Sylvain Rochet 
Sent: Monday, February 27, 2017 2:25 PM 
To: Mailing list for lwIP users 
Subject: Re: [lwip-users] TCPIP and MAC thread task priorities 

Hi, 

On Mon, Feb 27, 2017 at 11:50:26AM +0000, Noam Weissman wrote:

> Hi All, 

> This comes from my own experience with STM micro that has Cortex-M 
> core Running with FreeRTOS. It does apply to STM9 etc... 

> TCP main task priority should be high priority. It should not be the 
> highest priority but it should not be lower than other tasks that 
> consume lots of time share. 

> The most misunderstood issue is interrupt priority levels in Cortext-M 
> and FreeRTOS. 

> First of all: A lower number in Coretex means a higher priority while 
> in FreeRTOS a higher number Means a higher priority. 

> Secondly Cortex use a nesting interrupt and a smart level... Assume 
> you set an interrupt to level 2 and try to run some critical section 
> code from RS232 but that RS232 has an interrupt level set at 5. 

> What happens is that the interrupt 2 (higher) will never be masked 
> because the issuer of the Critical section runs at a lower interrupt 
> level. 

> FreeRTOS has lots of sections like this one: 

>   portENTER_CRITICAL(); 
>   {
>      // some code 
>   }
>   portEXIT_CRITICAL(); 


> If you set your interrupt level to be higher priority than the 
> FreeRTOS timer tick that part will never Be masked and your critical 
> section will not work as expected.

I don't understand any of this, portENTER_CRITICAL/portEXIT_CRITICAL 
proper implementation is to disable *ALL* interrupts, therefore having a critical section which is not enforced for whatever reason can't happen at all. 

By the way, FreeRTOS is not supposed to run with nested interrupts, you have to put all OS calls from interrupts (i.e. *FromISR() functions) in a critical section. 

Sylvain 
_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Simon Goldschmidt
2733 posts
In reply to  this post by Sylvain Rochet
Sylvain Rochet wrote: 
>> If you set your interrupt level to be higher priority than the 
>> FreeRTOS timer tick that part will never Be masked and your critical 
>> section will not work as expected. 

> I don't understand any of this, portENTER_CRITICAL/portEXIT_CRITICAL 
> proper implementation is to disable *ALL* interrupts 


To add some confusion: that's not entirely true: at least on the Cortex-M ARMs, 
you can have "fast-interrupts" that are NOT masked by ENTER/EXIT_CRICITAL. 
If I remember correctly, all (Cortex-M) ports I used have been setting up the 
lowest/highest interrupt priority in a way that at least some interrupts were 
such fast-interrupts, so there's definitively a possibility that this happens 
if you configure things wrong! 


Keeping that aside and answering to the OP: 
There is *no* limitation in lwIP itself that imposes the requirement of specific 
task priorities. The lwIP port to your OS/system can however impose this, so 
there's no way for us knowing if the comment you saw is true or not. 

In the end, you'll have to know which thread is more important than others. 
Given the tcpip_thread/eth_thread combination, you probably have to weight TX 
against RX, but that can largely depend on your application and/or driver. 


Simon 

_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Simon Goldschmidt
2733 posts
In reply to  this post by Sylvain Rochet
Oops, didn't see that before pushing the 'send' button :-) 

Sylvain Rochet wrote: 
> The RX thread (if any) should have a higher priority than the TCPIP thread, 

That's probably true. Having it the other way round doesn't actually 
break it I guess, but you should have a strong cause to do so (e.g. RX 
throttling, giving priority to TX). 


Simon 

_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Sylvain Rochet
497 posts
Hi, 

On Mon, Feb 27, 2017 at 08:03:09PM +0100,  [hidden email] wrote: 
> Oops, didn't see that before pushing the 'send' button :-) 

> Sylvain Rochet wrote: 
> >The RX thread (if any) should have a higher priority than the TCPIP thread, 

> That's probably true. Having it the other way round doesn't actually 
> break it I guess, but you should have a strong cause to do so (e.g. RX 
> throttling, giving priority to TX). 

It doesn't matter much anyway, we all know that with mutexes, 
semaphores, critical sections, and queues, priority inversion is the 
norm rather than the exception. 

If the system can't process RX fast enough, whichever task have 
precedence, incoming packets will be lost, either if DMA rx ring is full 
or if tcpip message box is full, then it won't work properly. 

Sylvain 

_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users

  signature.asc (188 bytes)  Download Attachment
Reply |  Threaded |  More 

Re: TCPIP and MAC thread task priorities

Wayne Uroda
3 posts
In reply to  this post by Simon Goldschmidt
Thank you Simon, and everyone else who contributed to the discussion.

I have had both tasks set at the same priority (RTOS task priority, nothing to do with the Cortex interrupt priority). I have not noticed any issues with this so I will leave it as is for now.
I don't think that the comment is accurate in my source code so I will remove it (perhaps replacing it with a link to this conversation).

Thanks again for the great work on supporting lwip.

- Wayne


On 28 February 2017 at 00:09, Simon Goldschmidt  <[hidden email]> wrote:
Sylvain Rochet wrote:
>> If you set your interrupt level to be higher priority than the
>> FreeRTOS timer tick that part will never Be masked and your critical
>> section will not work as expected.
>
> I don't understand any of this, portENTER_CRITICAL/portEXIT_CRITICAL
> proper implementation is to disable *ALL* interrupts


To add some confusion: that's not entirely true: at least on the Cortex-M ARMs,
you can have "fast-interrupts" that are NOT masked by ENTER/EXIT_CRICITAL.
If I remember correctly, all (Cortex-M) ports I used have been setting up the
lowest/highest interrupt priority in a way that at least some interrupts were
such fast-interrupts, so there's definitively a possibility that this happens
if you configure things wrong!


Keeping that aside and answering to the OP:
There is *no* limitation in lwIP itself that imposes the requirement of specific
task priorities. The lwIP port to your OS/system can however impose this, so
there's no way for us knowing if the comment you saw is true or not.

In the end, you'll have to know which thread is more important than others.
Given the tcpip_thread/eth_thread combination, you probably have to weight TX
against RX, but that can largely depend on your application and/or driver.


Simon

_______________________________________________
lwip-users mailing list
[hidden email]
https://lists.nongnu.org/mailman/listinfo/lwip-users


_______________________________________________ 
lwip-users mailing list 
[hidden email] 
https://lists.nongnu.org/mailman/listinfo/lwip-users
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
大学生在线租房平台管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、报修评价管理、字典管理、房东管理、房屋管理、房屋收藏管理、房屋留言管理、房屋租赁管理、租房论坛管理、公告信息管理、留言板管理、用户管理、管理员管理。用户的功能等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 大学生在线租房平台管理系统可以提高大学生在线租房平台信息管理问题的解决效率,优化大学生在线租房平台信息处理流程,保证大学生在线租房平台信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理大学生在线租房平台信息,包括房屋管理,培训管理,报修管理,薪资管理等,可以管理公告。 房屋管理界面,管理员在房屋管理界面中可以对界面中显示,可以对房屋信息的房屋状态进行查看,可以添加新的房屋信息等。报修管理界面,管理员在报修管理界面中查看报修种类信息,报修描述信息,新增报修信息等。公告管理界面,管理员在公告管理界面中新增公告,可以删除公告。公告类型管理界面,管理员在公告类型管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
基于hal库的OLED显示屏驱动C语言实现源码.zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip基于hal库的OLED显示屏驱动C语言实现源码.zip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值