【DWM1000】 code 解密1一 去掉Main 函数多余内容
蓝点DWM1000 模块已经打样测试完毕,有兴趣的可以申请购买了,更多信息参见 蓝点论坛
正文:
室内定位兴起,DWM1000 作为超宽带UWB的代表,在国内用的越来越多,但是可见资料非常少。 一方面是官方代码写的实在有点太差,另一方面是现在国内普及者将自己的代码当作是商业机密,当作是卖点,很少出来分享解析的。
我计划花一段时间来梳理DWM1000 代码,之前稍微接触过一点,感觉还能理解DWM1000 一点思路。 放在这里供大家参考。
作为穷人,目前我淘到一块DWM1000 模块,与我老旧的STM32 还没有互连,也就是说,还没有调试。这里的代码主要是分析思路,难免有误,请大家甄别参考。
拿到DWM1000 定位代码后发现需要CoCox编译,其实这个编译环境我试了试还是挺好的,免费的东西做成这样已经非常棒了,没有必要换成Keil 了。 另外我分析代码使用了source insight,我本人更偏向用vim 。 推荐大家用SI,有兴趣用vim。
好了,第一节,我想主要是清理一下Main 函数,因为太多LCD相关的,我们分析code,假定没有液晶,也不考虑LED以及USB把相关代码先全部注释掉。
int main(void)
{
int i = 0;
int toggle = 1;
double range_result = 0;
double avg_result = 0; led_off(LED_ALL); //turn off all the LEDs peripherals_init(); spi_peripheral_init(); /* Sleep(1000); //wait for LCD to power on initLCD(); memset(dataseq, 0, LCD_BUFF_LEN);
memcpy(dataseq, (const uint8 *) "DECAWAVE ", 16);
writetoLCD( 40, 1, dataseq); //send some data
memcpy(dataseq, (const uint8 *) SOFTWARE_VER_STRING, 16); // Also set at line #26 (Should make this from single value !!!)
writetoLCD( 16, 1, dataseq); //send some data Sleep(1000);*/
/*
#ifdef USB_SUPPORT
// enable the USB functionality
usb_init();
Sleep(1000);
#endif*/ s1switch = is_button_low(0) << 1 // is_switch_on(TA_SW1_2) << 2
| is_switch_on(TA_SW1_3) << 2
| is_switch_on(TA_SW1_4) << 3
| is_switch_on(TA_SW1_5) << 4
| is_switch_on(TA_SW1_6) << 5
| is_switch_on(TA_SW1_7) << 6
| is_switch_on(TA_SW1_8) << 7; port_DisableEXT_IRQ(); //disable ScenSor IRQ until we configure the device //test EVB1000 - used in EVK1000 production
if((is_button_low(0) == S1_SWITCH_ON) && (is_switch_on(TA_SW1_8) == S1_SWITCH_ON)) //using BOOT1 switch for test
{
test_application_run(); //does not return....
}
else
if(is_switch_on(TA_SW1_3) == S1_SWITCH_OFF)
{
/* int j = 1000000;
uint8 command; memset(dataseq, 0, LCD_BUFF_LEN); while(j--);
//command = 0x1 ; //clear screen
//writetoLCD( 1, 0, &command);
command = 0x2 ; //return cursor home
writetoLCD( 1, 0, &command); memcpy(dataseq, (const uint8 *) "DECAWAVE ", 12);
writetoLCD( 40, 1, dataseq); //send some data
#ifdef USB_SUPPORT //this is set in the port.h file
memcpy(dataseq, (const uint8 *) "USB to SPI ", 12);
#else
#endif
writetoLCD( 16, 1, dataseq); //send some data j = 1000000; while(j--); command = 0x2 ; //return cursor home
writetoLCD( 1, 0, &command);*/
/*
#ifdef USB_SUPPORT //this is set in the port.h file
// enable the USB functionality
//usb_init(); NVIC_DisableDECAIRQ(); // Do nothing in foreground -- allow USB application to run, I guess on the basis of USB interrupts?
while (1) // loop forever
{
usb_run();
}
#endif*/
return 1;
}
else //run DecaRanging application
{
/* uint8 dataseq[LCD_BUFF_LEN];
uint8 command = 0x0; command = 0x2 ; //return cursor home
writetoLCD( 1, 0, &command);
memset(dataseq, ' ', LCD_BUFF_LEN);
memcpy(dataseq, (const uint8 *) "DECAWAVE RANGE", 15);
writetoLCD( 15, 1, dataseq); //send some data led_off(LED_ALL); #ifdef USB_SUPPORT //this is set in the port.h file
usb_printconfig(16, (uint8 *)SOFTWARE_VER_STRING, s1switch);
#endif*/ if(inittestapplication(s1switch) == (uint32)-1)
{
/* led_on(LED_ALL); //to display error....
dataseq[0] = 0x2 ; //return cursor home
writetoLCD( 1, 0, &dataseq[0]);
memset(dataseq, ' ', LCD_BUFF_LEN);
memcpy(dataseq, (const uint8 *) "ERROR ", 12);
writetoLCD( 40, 1, dataseq); //send some data
memcpy(dataseq, (const uint8 *) " INIT FAIL ", 12);
writetoLCD( 40, 1, dataseq); //send some data*/
return 0; //error
} //sleep for 5 seconds displaying "Decawave"
/* i=30;
while(i--)
{
if (i & 1) led_off(LED_ALL);
else led_on(LED_ALL); Sleep(200);
}
i = 0;
led_off(LED_ALL);
command = 0x2 ; //return cursor home
writetoLCD( 1, 0, &command); memset(dataseq, ' ', LCD_BUFF_LEN);*/ if(s1switch & SWS1_ANC_MODE)
{
instance_mode = ANCHOR; /led_on(LED_PC6);
}/
else
{
instance_mode = TAG;
// led_on(LED_PC7);
} /*if(instance_mode == TAG)
{
//if TA_SW1_2 is on use fast ranging (fast 2wr)
if(is_button_low(0) == S1_SWITCH_ON)
{
memcpy(&dataseq[2], (const uint8 *) " Fast Tag ", 12);
writetoLCD( 40, 1, dataseq); //send some data
memcpy(&dataseq[2], (const uint8 *) " Ranging ", 12);
writetoLCD( 16, 1, dataseq); //send some data
}
else
{
memcpy(&dataseq[2], (const uint8 *) " TAG BLINK ", 12); writetoLCD( 40, 1, dataseq); //send some data
sprintf((char*)&dataseq[0], "%llX", instance_get_addr());
writetoLCD( 16, 1, dataseq); //send some data
}
}
else
{
memcpy(&dataseq[2], (const uint8 *) " AWAITING ", 12);
writetoLCD( 40, 1, dataseq); //send some data
memcpy(&dataseq[2], (const uint8 *) " POLL ", 12);
writetoLCD( 16, 1, dataseq); //send some data
} command = 0x2 ; //return cursor home
writetoLCD( 1, 0, &command);*/
}
#if (DWINTERRUPT_EN == 1)//CN:define1
port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
#endif /* memset(dataseq, ' ', LCD_BUFF_LEN);
memset(dataseq1, ' ', LCD_BUFF_LEN); #ifdef USART_SUPPORT
printf2(" %s\n", SOFTWARE_VER_STRING);
#endif*/ // main loop
while(1)
{
/*
#if (DWINTERRUPT_EN == 0)
process_deca_irq(); //poll DW1000 IRQ line when using polling of interrupt line
#endif*/
instance_run(); //if delayed TX scheduled but did not happen after expected time then it has failed... (has to be < slot period)
//if anchor just go into RX and wait for next message from tags/anchors
//if tag handle as a timeout
if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0].timeofTx) > instance_data[0].finalReplyDelay_ms))
{
instance_data[0].wait4ack = 0; if(instance_mode == TAG)
{
inst_processrxtimeout(&instance_data[0]);
}
else //if(instance_mode == ANCHOR)
{
dwt_forcetrxoff(); //this will clear all events
//enable the RX
instance_data[0].testAppState = TA_RXE_WAIT ;
}
instance_data[0].monitor = 0;
} if(instancenewrange())
{
int n, l = 0, /*txl = 0, rxl = 0,*/ aaddr, taddr, txa, rxa, rng, rng_raw;
ranging = 1;
//send the new range information to LCD and/or USB
range_result = instance_get_idist();
avg_result = instance_get_adist();
//set_rangeresult(range_result);
/* dataseq[0] = 0x2 ; //return cursor home
writetoLCD( 1, 0, dataseq); memset(dataseq, ' ', LCD_BUFF_LEN);
memset(dataseq1, ' ', LCD_BUFF_LEN);
sprintf((char*)&dataseq[1], "LAST: %4.2f m", range_result);
writetoLCD( 40, 1, dataseq); //send some data sprintf((char*)&dataseq1[1], "AVG8: %4.2f m", avg_result); writetoLCD( 16, 1, dataseq1); //send some data*/ l = instance_get_lcount();
//txl = instance_get_txl();
//rxl = instance_get_rxl();
aaddr = instancenewrangeancadd();
taddr = instancenewrangetagadd();
txa = instancetxantdly();
rxa = instancerxantdly();
rng = (int) (range_result*1000);
rng_raw = (int) (instance_get_idistraw()*1000); /* if(instance_mode == TAG)
{
//n = sprintf((char*)&dataseq[0], "ia%04x t%04x %04x %04x %04x %04x %04x %02x %02x t", aaddr, taddr, rng, rng_raw, l, txa, rxa, txl, rxl);
n = sprintf((char*)&dataseq[0], "ia%04x t%04x %08x %08x %04x %04x %04x t", aaddr, taddr, rng, rng_raw, l, txa, rxa);
}
else
{
//n = sprintf((char*)&dataseq[0], "ia%04x t%04x %04x %04x %04x %04x %04x %02x %02x a", aaddr, taddr, rng, rng_raw, l, txa, rxa, txl, rxl);
//n = sprintf((char*)&dataseq[0], "ia%04x t%04x %08x %08x %04x %04x %04x %2.2f a", aaddr, taddr, rng, rng_raw, l, txa, rxa, instance_data[0].clockOffset);
n = sprintf((char*)&dataseq[0], "ia%04x t%04x %08x %08x %04x %04x %04x a", aaddr, taddr, rng, rng_raw, l, txa, rxa);
}
#ifdef USB_SUPPORT //this is set in the port.h file
send_usbmessage(&dataseq[0], n);
#endif*/
/*
#ifdef USART_SUPPORT
{ //printf2("R= %i mm\r\n",rng);
printf2("R= %-3.2f m\r\n",range_result);
}
#endif*/
}
/*
#ifdef USART_SUPPORT
{
int nrm = 0;
if(nrm = instancenorange())
{
if(nrm == 1)
{
printf2("I= No Response\r\n");
}
else if(nrm == 2)
{
printf2("I= No Report\r\n");
}
else if(nrm == 3)
{
printf2("I= No Final\r\n");
}
}
}
#endif*/ if(ranging == 0)
{
if(instance_mode != ANCHOR)
{
if(instancesleeping())
{
//dataseq[0] = 0x2 ; //return cursor home
// writetoLCD( 1, 0, dataseq);
if(toggle)
{
/* toggle = 0;
memcpy(&dataseq[0], (const uint8 *) " AWAITING ", 16);
writetoLCD( 40, 1, dataseq); //send some data
memcpy(&dataseq[0], (const uint8 *) " RESPONSE ", 16);
writetoLCD( 16, 1, dataseq); //send some data*/
}
else
{
/* toggle = 1;
memcpy(&dataseq[2], (const uint8 *) " TAG BLINK ", 16); writetoLCD( 40, 1, dataseq); //send some data
sprintf((char*)&dataseq[0], "%llX", instance_get_addr());
writetoLCD( 16, 1, dataseq); //send some data*/
}
} if(instanceanchorwaiting() == 2)
{
ranging = 1;
/* dataseq[0] = 0x2 ; //return cursor home
writetoLCD( 1, 0, dataseq);
memcpy(&dataseq[0], (const uint8 *) " RANGING WITH", 16);
writetoLCD( 40, 1, dataseq); //send some data
sprintf((char*)&dataseq[0], "%016llX", instance_get_anchaddr());
writetoLCD( 16, 1, dataseq); //send some data*/
}
}
else //if(instance_mode == ANCHOR)
{
if(instanceanchorwaiting())
{
/* toggle+=2; if(toggle > 300000)
{
dataseq[0] = 0x2 ; //return cursor home
writetoLCD( 1, 0, dataseq);
if(toggle & 0x1)
{
toggle = 0;
memcpy(&dataseq[0], (const uint8 *) " AWAITING ", 16);
writetoLCD( 40, 1, dataseq); //send some data
memcpy(&dataseq[0], (const uint8 *) " POLL ", 16);
writetoLCD( 16, 1, dataseq); //send some data
}
else
{
toggle = 1;
memcpy(&dataseq[0], (const uint8 *) " DISCOVERY MODE ", 16);
writetoLCD( 40, 1, dataseq); //send some data
sprintf((char*)&dataseq[0], "%llX", instance_get_addr());
writetoLCD( 16, 1, dataseq); //send some data
}
}*/ }
else if(instanceanchorwaiting() == 2)
{
/* dataseq[0] = 0x2 ; //return cursor home
writetoLCD( 1, 0, dataseq);
memcpy(&dataseq[0], (const uint8 *) " RANGING WITH", 16);
writetoLCD( 40, 1, dataseq); //send some data
sprintf((char*)&dataseq[0], "%llX", instance_get_tagaddr());
writetoLCD( 16, 1, dataseq); //send some data*/
}
}
} /*
#ifdef USB_SUPPORT //this is set in the port.h file
usb_run();
#endif*/
} return 0;
}
上面代码不用看,如果你看了,恭喜你,帮我找一下看我注释掉的代码是否有问题, 我把注释掉的直接先删掉吧,虽然不是处女座,但是我看code 非常有洁癖的。
int main(void)
{
int i = 0;
int toggle = 1;
double range_result = 0;
double avg_result = 0; led_off(LED_ALL); //turn off all the LEDs
peripherals_init();
spi_peripheral_init(); s1switch = is_button_low(0) << 1 // is_switch_on(TA_SW1_2) << 2
| is_switch_on(TA_SW1_3) << 2
| is_switch_on(TA_SW1_4) << 3
| is_switch_on(TA_SW1_5) << 4
| is_switch_on(TA_SW1_6) << 5
| is_switch_on(TA_SW1_7) << 6
| is_switch_on(TA_SW1_8) << 7; port_DisableEXT_IRQ(); //disable ScenSor IRQ until we configure the device
//test EVB1000 - used in EVK1000 production
if((is_button_low(0) == S1_SWITCH_ON) && (is_switch_on(TA_SW1_8) == S1_SWITCH_ON)) //using BOOT1 switch for test
{
test_application_run(); //does not return....
}
else
if(is_switch_on(TA_SW1_3) == S1_SWITCH_OFF)
{
return 1;
}
else //run DecaRanging application
{
if(inittestapplication(s1switch) == (uint32)-1)
{
return 0; //error
} if(s1switch & SWS1_ANC_MODE)
{
instance_mode = ANCHOR; /led_on(LED_PC6);
}/
else
{
instance_mode = TAG; }
}
#if (DWINTERRUPT_EN == 1)//CN:define1
port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
#endif
// main loop
while(1)
{
instance_run();
if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0].timeofTx) > instance_data[0].finalReplyDelay_ms))
{
instance_data[0].wait4ack = 0; if(instance_mode == TAG)
{
inst_processrxtimeout(&instance_data[0]);
}
else //if(instance_mode == ANCHOR)
{
dwt_forcetrxoff(); //this will clear all events
//enable the RX
instance_data[0].testAppState = TA_RXE_WAIT ;
}
instance_data[0].monitor = 0;
}
if(instancenewrange())
{
int n, l = 0, /*txl = 0, rxl = 0,*/ aaddr, taddr, txa, rxa, rng, rng_raw;
ranging = 1;
//send the new range information to LCD and/or USB
range_result = instance_get_idist();
avg_result = instance_get_adist();
l = instance_get_lcount();
//txl = instance_get_txl();
//rxl = instance_get_rxl();
aaddr = instancenewrangeancadd();
taddr = instancenewrangetagadd();
txa = instancetxantdly();
rxa = instancerxantdly();
rng = (int) (range_result*1000);
rng_raw = (int) (instance_get_idistraw()*1000);
if(ranging == 0)
{
if(instance_mode != ANCHOR)
{
if(instancesleeping())
{
if(toggle)
{
}
else
{
}
}
if(instanceanchorwaiting() == 2)
{
ranging = 1; }
}
else //if(instance_mode == ANCHOR)
{
if(instanceanchorwaiting())
{ }
else if(instanceanchorwaiting() == 2)
{
}
}
} }
return 0;
}
删除注释,一下清爽很多,可能删除了一些有用的code,如果后面分析不同,我们再补回来。
下面再删除一个关于test的东西, Main 函数开始通过按键选择执行,有个test函数还不返回,我们定位不执行这部分,再次删除。
删除函数: test_application_run(); //does not return....
int main(void)
{
int i = 0;
int toggle = 1;
double range_result = 0;
double avg_result = 0; led_off(LED_ALL); //turn off all the LEDs
peripherals_init();
spi_peripheral_init(); s1switch = is_button_low(0) << 1 // is_switch_on(TA_SW1_2) << 2
| is_switch_on(TA_SW1_3) << 2
| is_switch_on(TA_SW1_4) << 3
| is_switch_on(TA_SW1_5) << 4
| is_switch_on(TA_SW1_6) << 5
| is_switch_on(TA_SW1_7) << 6
| is_switch_on(TA_SW1_8) << 7; port_DisableEXT_IRQ(); //disable ScenSor IRQ until we configure the device
else //run DecaRanging application
{
if(inittestapplication(s1switch) == (uint32)-1)
{
return 0; //error
} if(s1switch & SWS1_ANC_MODE)
{
instance_mode = ANCHOR; /led_on(LED_PC6);
}/
else
{
instance_mode = TAG; }
}
#if (DWINTERRUPT_EN == 1)//CN:define1
port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
#endif
// main loop
while(1)
{
instance_run();
if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0].timeofTx) > instance_data[0].finalReplyDelay_ms))
{
instance_data[0].wait4ack = 0; if(instance_mode == TAG)
{
inst_processrxtimeout(&instance_data[0]);
}
else //if(instance_mode == ANCHOR)
{
dwt_forcetrxoff(); //this will clear all events
//enable the RX
instance_data[0].testAppState = TA_RXE_WAIT ;
}
instance_data[0].monitor = 0;
}
if(instancenewrange())
{
int n, l = 0, /*txl = 0, rxl = 0,*/ aaddr, taddr, txa, rxa, rng, rng_raw;
ranging = 1;
//send the new range information to LCD and/or USB
range_result = instance_get_idist();
avg_result = instance_get_adist();
l = instance_get_lcount();
//txl = instance_get_txl();
//rxl = instance_get_rxl();
aaddr = instancenewrangeancadd();
taddr = instancenewrangetagadd();
txa = instancetxantdly();
rxa = instancerxantdly();
rng = (int) (range_result*1000);
rng_raw = (int) (instance_get_idistraw()*1000);
if(ranging == 0)
{
if(instance_mode != ANCHOR)
{
if(instancesleeping())
{
if(toggle)
{
}
else
{
}
}
if(instanceanchorwaiting() == 2)
{
ranging = 1; }
}
else //if(instance_mode == ANCHOR)
{
if(instanceanchorwaiting())
{ }
else if(instanceanchorwaiting() == 2)
{
}
}
} }
return 0;
}
再来看现在代码,直接从else 开始了,直奔主题。
if(inittestapplication(s1switch) == (uint32)-1)
{
return 0; //error
} if(s1switch & SWS1_ANC_MODE)
{
instance_mode = ANCHOR; /led_on(LED_PC6);
}/
else
{
instance_mode = TAG; }
}
#if (DWINTERRUPT_EN == 1)//CN:define1
port_EnableEXT_IRQ(); //enable ScenSor IRQ before starting
#endif
// main loop
while(1)
{
instance_run();
上面代码中,红色字体的两个函数是整个定位中非常重要的两个函数。
第一节,就分析到这里,主要是删除多余代码
【DWM1000】 code 解密1一 去掉Main 函数多余内容的更多相关文章
- 【DWM1000】 code 解密5一ACHOR 第一次回家Main 函数
instance_run(); if((instance_data[0].monitor == 1) && ((portGetTickCnt() - instance_data[0]. ...
- 【DWM1000】 code 解密6一TAG 状态机第一步
我们前面分析过,不论ANCHOR 还是TAG,前面变量的初始化基本都是一样的,只是状态机必须明确区分不同的设备类型.我们从开始看TAG.由于初始化TAG的 testAppState一样初始化为TA_I ...
- 【Go入门教程3】流程(if、goto、for、switch)和函数(多个返回值、变参、传值与传指针、defer、函数作为值/类型、Panic和Recover、main函数和init函数、import)
这小节我们要介绍Go里面的流程控制以及函数操作. 流程控制 流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑.Go中流程控制分三大类:条件判断,循环控制和 ...
- Atitit dsl对于数组的处理以及main函数的参数赋值
Atitit dsl对于数组的处理以及main函数的参数赋值 1.1. 词法解析..添加了[] 方括号的解析支持1 1.2. Ast建立.添加了数组参数的支持..使用了递归下降法..getparam ...
- SequoiaDB 系列之五 :源码分析之main函数
好久好久没有写博客了,因为一直要做各种事,工作上的,生活上的,这一下就是半年. 时光如梭. 这两天回头看了看写的博客,感觉都是贻笑大方. 但是还是想坚持把SequoiaDB系列写完. 初步的打算已经确 ...
- 为什么需要main函数,及其参数的用法
首先,需要明确main函数是什么? 答:main函数是C语言约定的入口函数 C99标准里面是这样描述的: Program startup The function called at program ...
- C++向main函数传递参数的方法(实例已上传至github)
通常情况下,我们定义的main函数都只有空形参列表: int main(){...} 然而,有时我们确实需要给mian传递实参,一种常见的情况是用户设置一组选项来确定函数所要执行的操作.例如,假定ma ...
- 转:iOS程序main函数之前发生了什么
原文地址:http://blog.sunnyxx.com/2014/08/30/objc-pre-main/ 我是前言 一个iOS app的main()函数位于main.m中,这是我们熟知的程序入口. ...
- C语言编程漫谈——main函数
写在前面 促使我写这篇文章是因为我这几天找了几个一样是大三的同学,与我相同专业相同方向(物联网)的人,除了@小胡同的诗,基本没有什么其他人会现在看起来很简单的编程题目了.问了一下其他同学,他们大部分都 ...
随机推荐
- JS onclick跳转
onclick="javascript:window.location.href='URL'" onclick="location='URL'" onclick ...
- BZOJ4675
题解: 考虑这么一件事情,n个人买彩票,在不断抽走卡片的时候,他们的中奖概率是不变的 所以在这道题中,由于每个人的操作次数是确定的,所以选每k个点的概率是相同的(因为如果我们逐一考虑每一次操作这个问题 ...
- admin密码对应的MD5值
admin密码对应的MD5值,16位和32位 admin密码对应的MD5值,16位和32位 admin的md5值是多少,常用密码加密md5值,123456,admin,admin888 如果遇到MD5 ...
- flink--DateSet开发--简单入门
开发流程 1. 获得一个execution environment, 2. 加载/创建初始数据, 3. 指定这些数据的转换, 4. 指定将计算结果放在哪里, 5. 触发程序执行 例子: object ...
- Mysql 锁库与锁表
一.全局锁表 1.FLUSH TABLES WITH READ LOCK 这个命令是全局读锁定,执行了命令之后所有库所有表都被锁定只读.一般都是用在数据库联机备份,这个时候数据库的写操作将被阻塞,读操 ...
- AtCoder Grand Contest 002 (AGC002) F - Leftmost Ball 动态规划 排列组合
原文链接https://www.cnblogs.com/zhouzhendong/p/AGC002F.html 题目传送门 - AGC002F 题意 给定 $n,k$ ,表示有 $n\times k$ ...
- web项目部署以及放到ROOT目录下
最近度过了一个国庆长假,好几天都没有写博客了! 发布这篇案例也是希望能帮助到像我一样的菜鸟o(* ̄︶ ̄*)o,百度上面的资料都不怎么全.也没有人说明注意事项.总是这篇说一点.那个人也说补一点,最后自己 ...
- P1057 传球游戏 dp
题目描述 上体育课的时候,小蛮的老师经常带着同学们一起做游戏.这次,老师带着同学们一起做传球游戏. 游戏规则是这样的:nn个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个 ...
- mySql版本的相关问题:com.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver
Mysql版本的相关问题:com.mysql.cj.jdbc.Driver和com.mysql.jdbc.Driver 1. 在使用mysql时,控制台日志报错如下: Loading class `c ...
- pageHelper多个sql分页
之前有个需求,在一个页面中需要有多个sql分页查询然后放到一个list中,展示,但是会出现一个bug,就是每次分页都会展示第一条查出的所有的数据: 第一页 第二页 因为是截的生产环境,第一条数据被处理 ...