Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
互斥锁mutex互斥量
idle空闲线程
线程上下文调度切换_context
10
关于线程切入空闲线程的问题
发布于 2022-04-19 18:46:41 浏览:949
订阅该版
问题描述:我在做一个高速采集的实验:can数据和串口数据帧周期都是10ms,问题描述有点多,我怕我说不清,可以直接看加粗的地方。 1、目前无法实现两个同时采集。 ![image.png](https://oss-club.rt-thread.org/uploads/20220419/506ce7253d8d3f13d37c44b9abf30503.png) 2、就拿一个来说,can。我的思路是,建立两个线程(1)CAN读取线程,(2)SD写入线程。线程运行简图如上 顺序是这样的,CAN读取线程优先级高于SD写入线程。 系统启动,CAN线程运行,1.互斥上锁、2.信号量未来临,被挂起。执行SD写入线程,由于CAN线程互斥量已经上锁,被挂起。 CAN中断来临,CAN线程被释放,1.把数据写入环形缓冲区,释放互斥信号,2.进入SD线程,**我疑惑的地方就在SD线程,它不是运行完然后切换其他程序,它是一直在和空闲线程切换,切换好几次才会执行完,但是我检查代码发现,SD线程中没有引起线程切换的函数,这里疑惑,SD写入函数每次只写入环形缓冲区读取出来的8字节,希望大佬有空指点一下,感谢** **下面是我调用钩子函数的情况:SD写入线程执行过程中会和空闲线程切换几次,我想知道为什么会切换。数据采集乱码概率是万分之1.** ![image.png](https://oss-club.rt-thread.org/uploads/20220419/8b27d99dc64612249478b015e86fcfa7.png) SD写入线程代码: ```c void Sd_WriteCan_Data(void* parameter) { //SD卡的写入,测试的时候先按照一帧数据,8字节写入,先打印出来。 uint8_t data[8] = {0}; char SDformat[100] = {0}; char buffer[20]; buffer[0] = '\0'; time_t now; while(1) { // rt_kprintf("CAN SD startup\r\n"); rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);//获取信号互斥信号量。 // rt_kprintf("CAN SD dynamic_mutex\r\n"); rt_size_t recv =rt_ringbuffer_get(RWSd, (rt_uint8_t *)data, sizeof(uint8_t)*8);//一直报错环形缓冲区的指针为空 RT_ASSERT(recv == sizeof(data)); //数据不再打印出来 // for (uint8_t i = 0; i < 8; i++) // { // rt_kprintf("0x%2x ", data[i]); // } for(uint8_t i = 0;i<8;i++) { sprintf(buffer,"%x,",data[i]); strcat(SDformat,buffer); } now = time(RT_NULL);//获取实时时间, strcat(SDformat,ctime(&now));//加了时间之后不需要空格换行了。 Write2SD(SDformat); //rt_thread_mdelay(100); memset(SDformat,'\0',strlen(SDformat));//把缓存清零了。 // rt_kprintf("CAN SD ending\r\n"); rt_mutex_release(dynamic_mutex);//释放信号量。 } } ``` SD写入函数: ```c int Write2SD(char *C_data) { static int can_filecount = 00000001;//定义一个静态变量用来新建存储can数据的文件。 static int can_datacount = 0;//用来记录一个文件里面的帧数 static uint8_t Creatfile= 1;//用来表示是否需要创建文件 static uint8_t Creatdir = 1;//用来表示是否需要创建文件夹 static int fd = 0; static DIR *dirp; int res_sync; int res_write; int res_close; //这个函数只负责新建文件夹和新建文件存储数据。 //创建文件夹 if(Creatdir == 1) { int res_mk; res_mk = mkdir("/can_data01",0x777);//创建了can_data01文件夹 if (res_mk < 0) { /* 创建目录失败 */ rt_kprintf("dir error!\n"); } else { //创建成功,下次进来之后就不再创建; Creatdir = 0; } } if(Creatfile == 1) { char name[50] = "/can_data01/can"; char file_type[] = ".csv"; char count2char[10]; count2char[0] = '\0'; sprintf(count2char,"%d",can_filecount); strcat(name,count2char); strcat(name,file_type); dirp = opendir("/can_data01"); fd = open(name, O_CREAT|O_WRONLY);//如果文件不存在则创建一个文件 if(fd>0) { Creatfile = 0;//创建成功以后,再次进入函数不再创建文件。 } else { rt_kprintf("create file failed\r\n"); } } if(fd>0) { // rt_kprintf("C_data:%s\r\n",C_data); res_write = write(fd, C_data, strlen(C_data)); if(res_write >0) { ; //rt_kprintf("res_write = %d\r\n",res_write); } else { rt_kprintf("write error%d \r\n",strlen(C_data)); rt_kprintf("write error \r\n"); } lseek(fd,0, SEEK_CUR); res_sync = fsync(fd);//同步,将缓存写到SD卡里面。 can_datacount++; if(can_datacount>19999) { can_datacount = 0;//清零计数器 Creatfile = 1;//下次进入函数要创建新文件 can_filecount++;//新建文件的编号 // close(fd); res_close = close(fd);//写完一个文件一定要关闭; if(res_close == 0) { rt_kprintf("close successed:%d\r\n",res_close); } else { rt_kprintf("close failed:%d\r\n",res_close); } closedir(dirp);//因为打开了目录,所以把目录也关闭一下。 rt_kprintf("file count:%d,fd = %d\r\n",can_filecount-1,fd); } if(res_sync == 0) { ; } else { rt_kprintf("res_sync failed:%d",res_sync); } } } ```
查看更多
aozima
2022-04-19
调网络不抓包,调I2C等时序不上逻辑分析仪,就像电工不用万用表!多用整理的好的文字,比截图更省流量,还能在整理过程中思考。
有图好评 写SD卡时,主要的时间主要是在等SD卡内部写入完成,此时CPU都是可以让出的。
1
个回答
默认排序
按发布时间排序
撰写答案
登录
注册新账号
关注者
0
被浏览
949
关于作者
八音盒子
这家伙很懒,什么也没写!
提问
15
回答
4
被采纳
0
关注TA
发私信
相关问题
1
modbusRTU如何避免因为被高优先级任务切走而导致本次通讯失败
2
RT-Thread 4.0.2初次上下文切换失败
3
pendSV中bx lr指令,lr指向哪里?psp中剩余的寄存器啥时候弹出的?
4
Cortex-M0在bootloader环境下的上下文切换问题?
5
arc内核移植线程切换
6
rt_thread_yield 无法在同级别中释放cpu
7
线程执行完后退出 是如何通知cpu切换任务的
8
RTT-NANO 3.1.3 线程切换问题
9
线程切换,打印出来的时间不对
10
软件定时器的回调函数里可以挂起或解挂另一个线程吗?
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
开源共生 商业共赢 | RT-Thread 2024开发者大会议程正式发布!
2
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
3
RT-Thread EtherKit开源以太网硬件正式发布
4
如何在master上的BSP中添加配置yml文件
5
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
a1012112796
20
个答案
3
次被采纳
张世争
11
个答案
3
次被采纳
踩姑娘的小蘑菇
7
个答案
3
次被采纳
rv666
9
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部