您尚未登录。

楼主 # 2022-08-14 03:30:21

游乐场
会员
注册时间: 2022-07-29
已发帖子: 42
积分: 160

【代码分享】hal库现在提供互斥锁

MC3172使用全局变量做线程间通信,如何解决线程对全局资源的访问冲突问题是肯定绕不开的,自从上次给出了一种全局资源管理方法以来已经五天了,当时的两个问题属实有点把我难住了。

基于以上方法,我参照LiteOS的互斥锁做了一个MC3172的锁,刚好解决了之前遗留的两个问题,代码在此:https://gitee.com/ylc0919/mc3172/.

各种小bug困扰了我很久,刚刚测试通过,还没有来得及整理测试示例,有空我会做一个如GPIO一样的互斥锁demo分支,先来看看锁的效果:

1.png
2.png

互斥锁模块向外提供5个函数,其中常用的只有两个。
.png

顺便提一下,现在本工程中的printf()函数已经可以安全的使用了。

最近编辑记录 游乐场 (2022-08-14 03:46:18)

离线

#1 2022-08-14 10:02:04

海石生风
会员
注册时间: 2019-07-02
已发帖子: 163
积分: 263

Re: 【代码分享】hal库现在提供互斥锁

其实应该是官方在SDK内实现这种线程安全的共享内存访问方案,不然就需要用户自己造轮子来实现一套,就等于要用户自己实现RTOS的基础组件,那还不如直接用通用MCU的RTOS方案。

其实最好是芯片硬件上有类似多核心CPU那种核间通信的邮箱或管道,这样线程间通信就简单好多。

PS @游乐场 这个互斥锁的初始化搞复杂了,虽然名为 HAL_MUX_Create 其实没有在堆里malloc内存,但还是复杂了容易出BUG,简洁的方式应该是声明互斥锁结构体、所有互斥锁变量都静态分配即是全局变量、将互斥锁结构体变量指针传入初始化函数进行初始化、然后拿这个结构体来使用。API应该是这样:

typedef struct Mutex
{
    int lock;
}Mutex_t;

int Mutex_Init(Mutex_t *mutex);
int Mutex_Lock(Mutex_t *mutex);
int Mutex_Unlock(Mutex_t *mutex);

最近编辑记录 海石生风 (2022-08-14 10:27:05)

离线

楼主 #2 2022-08-14 11:54:36

游乐场
会员
注册时间: 2022-07-29
已发帖子: 42
积分: 160

Re: 【代码分享】hal库现在提供互斥锁

@海石生风
第一,官方实现的问题,如果官方有能力,我建议他实现一切东西,我做产品直接cv多好。驱动任何传感器都是在造轮子,而mc3172明显是新车,官方为什么没有提供,谁都清楚。

第二,关于rtos,群里已经讨论很多了,真正玩这个芯片就能感受到区别,我一时半会也讲不清楚。

第三,如果核间通信比全局变量方便...

第四,我拒绝在单片机使用malloc,关于hal库的互斥锁,如果遇到bug了来这里说一下哦,谢谢。

离线

#3 2022-08-14 19:23:40

海石生风
会员
注册时间: 2019-07-02
已发帖子: 163
积分: 263

Re: 【代码分享】hal库现在提供互斥锁

一般来说,create接口是基于malloc的动态内存分配,init接口对应的则是静态内存分配即静态变量,我说的是你的命名容易误导、初始化过程太复杂。

最近编辑记录 海石生风 (2022-08-14 19:28:22)

离线

#4 2022-08-14 22:41:27

support_gxchip
Moderator
注册时间: 2022-07-26
已发帖子: 48
积分: 103

Re: 【代码分享】hal库现在提供互斥锁

游总这速度真是太快了

离线

楼主 #5 2022-08-14 22:52:50

游乐场
会员
注册时间: 2022-07-29
已发帖子: 42
积分: 160

Re: 【代码分享】hal库现在提供互斥锁

海石生风 说:

一般来说,create接口是基于malloc的动态内存分配,init接口对应的则是静态内存分配即静态变量,我说的是你的命名容易误导、初始化过程太复杂。

那好像确实有点,不过我的创建锁就是从全局所有空闲锁链表取一个,标记成已使用的,并不复杂,叫create应该没啥问题,或许叫get也可以,不过又怕和pend混淆了。

离线

楼主 #6 2022-08-14 22:54:17

游乐场
会员
注册时间: 2022-07-29
已发帖子: 42
积分: 160

Re: 【代码分享】hal库现在提供互斥锁

support_gxchip 说:

游总这速度真是太快了

之前有俩bug卡住了,真是吃不香睡不香啊,只能打打牌勉强度日的样子。

离线

楼主 #7 2022-08-14 23:23:02

游乐场
会员
注册时间: 2022-07-29
已发帖子: 42
积分: 160

Re: 【代码分享】hal库现在提供互斥锁

添加了基于官方开发板的测试程序,程序在仓库的hal_mux分支,master分支我会尝试一些奇奇怪怪的功能,不适合大家参考。
https://gitee.com/ylc0919/mc3172/tree/hal_mux/
工程基于梦程的cmake,用visual studio 和vs code打开均可,原开源地址在https://github.com/dreamcmi/MC3172-CMake.

离线

#8 2022-08-17 17:31:28

lignin
会员
注册时间: 2020-03-21
已发帖子: 69
积分: 87.5

Re: 【代码分享】hal库现在提供互斥锁

大佬来搞个重入锁,可以多次锁,linux里面有提供这个,最近用rtos用用到这个功能

离线

楼主 #10 2022-08-18 09:06:32

游乐场
会员
注册时间: 2022-07-29
已发帖子: 42
积分: 160

Re: 【代码分享】hal库现在提供互斥锁

lignin 说:

大佬来搞个重入锁,可以多次锁,linux里面有提供这个,最近用rtos用用到这个功能

我这个锁也可以递归,锁多次

最近编辑记录 游乐场 (2022-08-18 09:07:24)

离线

#11 2022-08-24 17:12:40

jokerlai
会员
注册时间: 2022-08-08
已发帖子: 1
积分: 31

Re: 【代码分享】hal库现在提供互斥锁

在楼主的互斥锁的基础上稍作修改实现了计数型信号量。
1.在结构“typedef struct MuxCB_S;”中增加一项uint16_t limit;用于限制信号量计数值。
2.增加了一项宏定义“#define HAL_ERRNO_SEM_EXCEED 7”用于信号量计数超过限制时的返回值。
3.增加5个函数,源文件见附件mc31xx_hal_sem.zip
uint32_t HAL_SEM_Create(uint32_t* puwMuxHandle, uint16_t limit, uint16_t init);
uint32_t HAL_SEM_Delete(uint32_t uwMuxHandle);
uint32_t HAL_SEM_Pend(u32 uwMuxHandle, u32 uwTimeout);
uint32_t HAL_SEM_Post(uint32_t uwMuxHandle);
uint32_t HAL_SEM_Query(uint32_t uwMuxHandle, uint16_t*count);

信号量可以通过一个简单的生产者-消费者模型进行测试。
1.首先初始化两个信号量Full和Empty,假设缓冲区大小为8,Full的初值设为0,Empty的初值设为8
    HAL_SEM_Create(&g_uwFullSemHandle, 8, 0);
    HAL_SEM_Create(&g_uwEmptySemHandle, 8, 8);

2.生产者线程:
     Pend(Empty);
     写入数据;
     Post(Full)

3.消费者线程:
     Pend(Full)
     读取数据;
     Post(Empty)

最近编辑记录 jokerlai (2022-08-24 17:23:38)

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn