1619 views|2 replies

53

Posts

0

Resources
The OP
 

aos multithreading and mutex lock [Copy link]

 This post was last edited by Chengjian on 2022-6-14 12:52

First, let’s look at a piece of code:

#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include <drv/timer.h>

#define TAG "app"

volatile int n=0;
csi_timer_t g1_timer;//定义变量
static void g1_handler(csi_timer_t *timer_handle, void *arg)
{
	printf("%d\r\n",n);
	n=0;//为什么这句会时不时不执行呢?
	//printf("%d\r\n",n);
}

void my_test(void)
{
	csi_timer_init(&g1_timer, 0);//初始化定时器
	csi_timer_attach_callback(&g1_timer, g1_handler, NULL);//绑定回调函数
	csi_timer_start(&g1_timer, 1000000);//1000000每秒定时,单位为us,时间到自动执行回调函数
	while(1){
		n++;
	}
	csi_timer_stop(&g1_timer);
	csi_timer_detach_callback(&g1_timer);
	csi_timer_uninit(&g1_timer);
}

int main(void)
{
    board_yoc_init();
    LOGD(TAG, "%s\n", aos_get_app_version());
	my_test();
    return 0;
}

That is, the cumulative number of outputs n per second is executed as:

32767548
65535098
32767548
65535098
32767548
65535098
32767548
65535098
32767548
65535098
32767548
65535098
32767548
65535098

From the execution results, it seems that n=0; in the timer callback function is occasionally not executed. In fact, the reason is that the sentence n++; in the main function cannot be executed by one instruction, but requires three instructions.

1) Take the value of n and put it into the register,

2) Add 1 to the register.

3) Store the value after adding 1 into n,

Then these three instructions may be interrupted by the timer, and then unexpected problems may occur. . .

The correct approach is to look at the following code

/*
 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
 */


#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include <drv/timer.h>

#define TAG "app"

static aos_mutex_t test_mutex;

volatile int n=0;
csi_timer_t g1_timer;//定义变量
static void g1_handler(csi_timer_t *timer_handle, void *arg)
{
	printf("%d\r\n",n);
	aos_mutex_lock(&test_mutex, AOS_WAIT_FOREVER);
	n=0;
	aos_mutex_unlock(&test_mutex);
}

void my_test(void)
{
	csi_timer_init(&g1_timer, 0);//初始化定时器
	csi_timer_attach_callback(&g1_timer, g1_handler, NULL);//绑定回调函数
	csi_timer_start(&g1_timer, 1000000);//1000000每秒定时,单位为us,时间到自动执行回调函数
	while(1){
		aos_mutex_lock(&test_mutex, AOS_WAIT_FOREVER);
		n++;
		aos_mutex_unlock(&test_mutex);
	}
	csi_timer_stop(&g1_timer);
	csi_timer_detach_callback(&g1_timer);
	csi_timer_uninit(&g1_timer);
}

int main(void)
{
    board_yoc_init();
    LOGD(TAG, "%s\n", aos_get_app_version());
	aos_mutex_new(&test_mutex);
	my_test();
    return 0;
}

Execution Result:

668735
668682
668711
668711
668711
668711
668710
668711
668712
668711
668711
668711
668711
668711

Although the program execution is slow, I can get the correct result. Thanks to the technical staff of Pingtou Ge's work order system for patiently answering my questions. . .

The following article is a good understanding of multithreading and resource preemption

Multiple threads are "fighting" for the same resource. How can we keep them in check?

Latest reply

Thank you for sharing May I ask the original poster, under what circumstances will this aos multithreading and mutex phenomenon occur? Are there other ways to deal with it?   Details Published on 2022-6-15 07:08
 
 

6555

Posts

0

Resources
2
 

Thank you for sharing

May I ask the original poster, under what circumstances will this aos multithreading and mutex phenomenon occur? Are there other ways to deal with it?

Comments

In fact, there are definitely methods, such as:   Details Published on 2022-6-15 14:44
 
 
 

53

Posts

0

Resources
3
 
This post was last edited by Chengjian on 2022-6-15 14:45
Jacktang posted on 2022-6-15 07:08 Thank you for sharing. May I ask the OP, under what circumstances will this aos multithreading and mutex phenomenon occur? Are there other ways to deal with it?

In fact, there are definitely methods, such as:

/*
 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
 */


#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include "aos/cli.h"
#include "main.h"
#include "app_init.h"
#include <drv/timer.h>

#define TAG "app"

volatile int n=0,s=0;
csi_timer_t g1_timer;//定义变量
static void g1_handler(csi_timer_t *timer_handle, void *arg)
{
	printf("%d\r\n",n);
	s=1;
}

void my_test(void)
{
	csi_timer_init(&g1_timer, 0);//初始化定时器
	csi_timer_attach_callback(&g1_timer, g1_handler, NULL);//绑定回调函数
	csi_timer_start(&g1_timer, 1000000);//1000000每秒定时,单位为us,时间到自动执行回调函数
	while(1){
		if(s){
			s=0;
			n=1;
		}
		else n++;
	}
	csi_timer_stop(&g1_timer);
	csi_timer_detach_callback(&g1_timer);
	csi_timer_uninit(&g1_timer);
}

int main(void)
{
    board_yoc_init();
    LOGD(TAG, "%s\n", aos_get_app_version());
    my_test();
    return 0;
}

 
 
 

Guess Your Favourite
Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list