MC3172使用全局变量做线程间通信,如何解决线程对全局资源的访问冲突问题是肯定绕不开的,自从上次给出了一种全局资源管理方法以来已经五天了,当时的两个问题属实有点把我难住了。
基于以上方法,我参照LiteOS的互斥锁做了一个MC3172的锁,刚好解决了之前遗留的两个问题,代码在此:https://gitee.com/ylc0919/mc3172/.
各种小bug困扰了我很久,刚刚测试通过,还没有来得及整理测试示例,有空我会做一个如GPIO一样的互斥锁demo分支,先来看看锁的效果:
互斥锁模块向外提供5个函数,其中常用的只有两个。
顺便提一下,现在本工程中的printf()函数已经可以安全的使用了。
最近编辑记录 游乐场 (2022-08-14 03:46:18)
离线
其实应该是官方在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)
离线
@海石生风
第一,官方实现的问题,如果官方有能力,我建议他实现一切东西,我做产品直接cv多好。驱动任何传感器都是在造轮子,而mc3172明显是新车,官方为什么没有提供,谁都清楚。
第二,关于rtos,群里已经讨论很多了,真正玩这个芯片就能感受到区别,我一时半会也讲不清楚。
第三,如果核间通信比全局变量方便...
第四,我拒绝在单片机使用malloc,关于hal库的互斥锁,如果遇到bug了来这里说一下哦,谢谢。
离线
游总这速度真是太快了
离线
一般来说,create接口是基于malloc的动态内存分配,init接口对应的则是静态内存分配即静态变量,我说的是你的命名容易误导、初始化过程太复杂。
那好像确实有点,不过我的创建锁就是从全局所有空闲锁链表取一个,标记成已使用的,并不复杂,叫create应该没啥问题,或许叫get也可以,不过又怕和pend混淆了。
离线
游总这速度真是太快了
之前有俩bug卡住了,真是吃不香睡不香啊,只能打打牌勉强度日的样子。
离线
添加了基于官方开发板的测试程序,程序在仓库的hal_mux分支,master分支我会尝试一些奇奇怪怪的功能,不适合大家参考。
https://gitee.com/ylc0919/mc3172/tree/hal_mux/
工程基于梦程的cmake,用visual studio 和vs code打开均可,原开源地址在https://github.com/dreamcmi/MC3172-CMake.
离线
大佬来搞个重入锁,可以多次锁,linux里面有提供这个,最近用rtos用用到这个功能
离线
大佬来搞个重入锁,可以多次锁,linux里面有提供这个,最近用rtos用用到这个功能
我这个锁也可以递归,锁多次
最近编辑记录 游乐场 (2022-08-18 09:07:24)
离线
在楼主的互斥锁的基础上稍作修改实现了计数型信号量。
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)
离线
;我测试了下,为啥打印不了中文,另外申请锁为啥总是超时
离线
波特率我也修改测试了115200和256000都是这样
离线
hal库v1.2.2编译提示mc31xx_hal_spi.h文件里面#define SPI_POLARITY_HIGH SPI_CR1_CPOL 和#define SPI_PHASE_2EDGE SPI_CR1_CPHA 提示错误找不到SPI_CR1_CPOL和SPI_CR1_CPHA 的定义,想问下这个的定义在哪里能找到
离线
锁要用到管理线程,对比一下当前线程分配,有没有配置管理线程,我代码里是用线程3
离线
hal库v1.2.2编译提示mc31xx_hal_spi.h文件里面#define SPI_POLARITY_HIGH SPI_CR1_CPOL 和#define SPI_PHASE_2EDGE SPI_CR1_CPHA 提示错误找不到SPI_CR1_CPOL和SPI_CR1_CPHA 的定义,想问下这个的定义在哪里能找到
spi部分并没有适配完成,可以直接删除
离线
hal库v1.2.2在两个线程里面同时每隔2s用printf进行周期打印,发现有冲突导致打印死机;对printf进行加锁也无法解决;最后间隔时间不一致即可打印;这个有没有办法解决
离线