Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
互斥锁mutex互斥量
idle空闲线程
线程上下文调度切换_context
10
关于线程切入空闲线程的问题
发布于 2022-04-19 18:46:41 浏览:1079
订阅该版
问题描述:我在做一个高速采集的实验: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
被浏览
1.1k
关于作者
八音盒子
这家伙很懒,什么也没写!
提问
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】【ci】【scons】将ci.attachconfig.yml和scons结合使用
2
Rt-thread中OTA下载后,bootloader不搬程序
3
ulog 日志 LOG_HEX 输出时间改为本地日期时间
4
在RT-Thread Studio中构建前执行python命令
5
研究一了一段时间RTT,直接标准版上手太难,想用nano,但又舍不得组件
热门标签
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
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
出出啊
1518
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
5
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部