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?
|