Part Number:LAUNCHXL-CC1310Other Parts Discussed in Thread:CC1310
CC1310在调试过程中,NVS_write 和 Clock会有冲突.比如先调用NVS_write ,然后调用启动Clock,Clock不能启动.或者Clock启动了,调用NVS_write 后,Clock中止了.
Nick Sun:
您好,
感谢您的对TI产品的关注!为更加有效地解决您的问题,我需要多一些时间查看这个问题,稍后会为您解答。
,
Nick Sun:
您好,
您有使用什么sdk的示例吗?可以把相关程序部分贴上来。
,
zijun li:
Nick您好,
我使用的是Easylink TX的示例.
这是调用NVS_write的代码void my_nvs_write(uint8_t * buff,uint16_t offset,uint16_t len){ //保证四字节对齐 如果无对齐自动补齐 len = fix4(len); NVS_write(nvsHandle, offset, buff, len, NVS_WRITE_ERASE | NVS_WRITE_VALIDATE); }在调用NVS_write 后,调用定时器或者调用串口打印,都不能成功,如果不调用NVS_write,调用定时器或者调用串口打印都正常.
被这个问题困扰很久了,现在项目就卡在这个问题上面,请帮忙分析下原因和解决办法,谢谢.
Jacky
,
Nick Sun:
您好,
我们需要一些时间解决这个问题,有结论后联系您。
感谢您的支持。
,
zijun li:
请帮忙分析一下,谢谢!
,
Nick Sun:
您好,
能否直接将您有修改部分的程序文件发上来?
,
zijun li:
这个是其中一个文件at.c
#include <stdint.h> #include <stdbool.h> #include <ti/drivers/Watchdog.h> #include <ti/drivers/power/PowerCC26XX.h>#include <ti/drivers/NVS.h> #include <driverlib/flash.h> #include "CC1310DK_5XD.h" #include "string.h" #include <ti/drivers/UART.h> #include "Board.h" #include "string.h" #include "task/UartTask.h" #include "interrupt_function/at.h" #include "EasyLink.h" //#include <ti/sysbios/knl/Semaphore.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/knl/Clock.h>#include <ti/drivers/Power.h> #include <ti/drivers/power/PowerCC26XX.h> #include <driverlib/trng.h>NVS_Handle nvsHandle;uint32_t waitTime = 2; int button_count1 = 0; extern UART_Handle uart0; /************************辅助函数部分*****************************************/ /*!*@deffix4*@brief字节补齐函数,使用此函数要让自己的buffer扩大3个字节*@para要补齐的长度*@returnNULL*/ uint16_t fix4(uint16_t length) {uint8_t remainder = 0;if(length == 1){length += 3;}else if(length == 2){length += 2;}else if(length == 3){length += 1;}else{remainder = length % 4;if(remainder == 1){length += 3;}else if(remainder == 2){length += 2;}else if(remainder == 3){length += 1;}}return length; }uint8_t my_memcmp(const void*src1, const void*src2, unsigned int len ) {const uint8_t*pSrc1;const uint8_t*pSrc2;pSrc1 = src1;pSrc2 = src2;while ( len-- ){if( *pSrc1++ != *pSrc2++ )return FALSE;}return TRUE; }uint8_tinput_adjust(uint8_t adjust) {if(adjust >= '0' && adjust <= '9' || (adjust >= 'A' && adjust <= 'F'))return true;return false; }/********************************************************************** @fnChange_ASCII_HEX** @brief将ASCII码转换成16进制数** @paramp转换后存储的位置,q要转换的字符串,ss要转换的长度** @returnnone*//********************************************************************* *********************************************************************/ void Change_ASCII_HEX(uint8_t *p,uint8_t *q,int ss) {int i = 0;while(i < ss){if(q[i]>='0' && q[i]<='9'){p[i]=q[i]-'0' + 0x00;}else if(q[i]>='a' && q[i]<='f'){p[i]=q[i]-'a'+0x0a;}else if(q[i]>='A' && q[0]<='F'){p[i]=q[i]-'A'+0x0a;}i++;} }/********************************************************************** @fntoadd** @brief将相邻的两个16进制数相加** @paramp转换后存储的位置,q要转换的16进制数组,ss要转换的长度** @returnnone*//********************************************************************* *********************************************************************/ void toadd(uint8_t * p,uint8_t *q,int ss) {int i = 0;int j = 0;while(j < ss){p[j] = q[i] * 0x10 + q[i + 1];j++;i += 2;} }// 5分钟定时器回调函数 Clock_Handle pairHandle; int pair_clock_count = 0; uint8_t attention_buff11[20] = {0}; Void pairClockCallBack(UArg arg) {memcpy(attention_buff11,"ERR:1\r\n",7);UART_write(uart0, attention_buff11, 7);PIN_setOutputValue(pinHandle, Board_LED2, 0);pair_clock_count++;if(pair_clock_count == 1)// 按钮触发就马上回调了{}else if(pair_clock_count == 2)// 这才是真正的回调{// 如果还处于配对模式, 退出配对模式if(read_flag() == 0){set_flag(2);PIN_setOutputValue(pinHandle, Board_LED1, 1);PIN_setOutputValue(pinHandle, Board_LED2, 1);}Clock_stop(pairHandle); // 停止定时器pair_clock_count = 0;} }static void pairClockInit() {Clock_Struct period_ClockStruct1;Clock_Params clkParams1;Clock_Params_init(&clkParams1);//clkParams.period = 5 * 60 * 1000 * 1000 / Clock_tickPeriod;// 5分钟clkParams1.period = 1* 30 * 1000 * 1000 / Clock_tickPeriod;// 测试1分钟clkParams1.startFlag = FALSE;pairHandle = Clock_create(pairClockCallBack,1,&clkParams1,NULL); }Clock_Handle clkHandle; int clock_count = 0;// 定时器回调函数,发送配对数据包 //Void periodClockCallBack(UArg arg) //{ //clock_count ++; //if(clock_count == 1)// 按钮触发就马上回调了 //{ ////memcpy(attention_buff11,"ERR:1\r\n",7); ////UART_write(uart0, attention_buff11, 7); //} //else if(clock_count == 2)// 这才是真正的回调 //{ //if(button_count1 >= 3) // 15秒触发3次按钮,开始进入配对,开启5分钟定时器 //{ //// 1,开始配对 //set_flag(0); ////PIN_setOutputValue(pinHandle, Board_LED2, 0); //Clock_stop(clkHandle); // 停止定时器 ////my_watchdog_start(1); //CPUdelay(8000*50); ////// 2,开启5分钟定时器 //Clock_start(pairHandle);//} //else //{ //Clock_stop(clkHandle); // 停止定时器 //} ////button_count1 = 0; //clock_count = 0; //}//}int clock_index = 0; Void periodClockCallBack(UArg arg) {clock_index++;attention_buff11[0] = clock_index; //memcpy(attention_buff11,"ERR:1\r\n",7);UART_write(uart0, attention_buff11, 1);if(clock_index == 30) // 超时未配对成功,结束配对{Clock_stop(clkHandle); // 停止定时器attention_buff11[0] = 0xA1;attention_buff11[1] = 0x03;UART_write(uart0, attention_buff11, 2);} //else if(clock_index == 3) //{ //set_flag(0); //} //if(clock_index <=15) //{ //if(button_count1 >= 3) //{ //// 1,开始配对 //set_flag(0); //clock_count++; //} //} //else if(clock_index == 16) //{ //if(clock_count == 0) //{ //memcpy(attention_buff11,"ERR:1\r\n",7); //UART_write(uart0, attention_buff11, 7); //Clock_stop(clkHandle); // 停止定时器 //clock_index = 0; //} //} //else if(clock_index >= 30) //{ //if(read_flag() == 0)// 没有配对成功 //{ //set_flag(2); //PIN_setOutputValue(pinHandle, Board_LED1, 1); //PIN_setOutputValue(pinHandle, Board_LED2, 1); //} //Clock_stop(clkHandle); // 停止定时器 //clock_index = 0; //}}static void btnClockInit() {Clock_Struct period_ClockStruct;Clock_Params clkParams;Clock_Params_init(&clkParams);clkParams.period = 1 * 1000 * 1000 / Clock_tickPeriod;// 15秒clkParams.startFlag = FALSE;//Clock_construct(&period_ClockStruct, periodClockCallBack, 1, &clkParams);// Error_Block *eb;clkHandle = Clock_create(periodClockCallBack,1,&clkParams,NULL); }static Watchdog_Handle watchdog;void watchdogInit() {Watchdog_init();Watchdog_Params params;Watchdog_Params_init(¶ms);params.debugStallMode = Watchdog_DEBUG_STALL_ON;params.resetMode = Watchdog_RESET_ON;watchdog = Watchdog_open(0, ¶ms); // 打开看门狗// 定时器初始化btnClockInit();pairClockInit();//Clock_start(clkHandle);// 2秒 }// 按钮中断触发事件 void set_btnClock_start() { //button_count1++; //if(button_count1 == 1) // 第一次触发开始计时 //{Clock_start(clkHandle);//Clock_start(pairHandle);//}}/************************看门狗函数部分*****************************************/ /*!*@defmy_watchdog_start*@brief启动看门狗,设置看门狗时间*@para看门狗时间此时间不准*@returnNULL*/void my_watchdog_start(uint32_t time_milliseconds) {Watchdog_close(watchdog);Watchdog_setReload(watchdog,Watchdog_convertMsToTicks(watchdog,time_milliseconds));} /************************flash存储部分*****************************************//*!*@definit_my_nvs*@brief初始化nvs*@para无*@returnNULL*/ void init_my_nvs(void) {NVS_init();nvsHandle = NVS_open(CC1310DK_5XD_NVS1F000, NULL); }/*!*@defmy_nvs_read*@brief读取nvs中相应位置的数据*@para读取数据后存储的位置*@para读取flash的位置相对初始位置的偏移量*@para要读取的数据的长度,若无四字节对齐,自动对齐,最大补齐长度3。最好设置存储的buff长度增加3*@returnNULL*/ void my_nvs_read(uint8_t * buff,uint16_t offset,uint16_t len) {//保证四字节对齐 如果无对齐自动补齐len = fix4(len);NVS_read(nvsHandle, offset, buff, len); }/*!*@defmy_nvs_write*@brief向nvs中读取数据*@para要存储的数据源*@para写入flash的位置相对初始位置的偏移量*@para要写入的数据的长度,若无四字节对齐,自动对齐,最大补齐长度3。最好设置写入的buff长度增加3*@returnNULL*/ void my_nvs_write(uint8_t * buff,uint16_t offset,uint16_t len) {//保证四字节对齐 如果无对齐自动补齐len = fix4(len);NVS_write(nvsHandle, offset, buff, len, NVS_WRITE_ERASE | NVS_WRITE_VALIDATE);}int Create_configString(char* buf) {int len = 0;char buf1[] = {"Baud rate |"},buf2[6] = {0},buf3[] = {"\r\nAddress|"},buf4[4] = {0},\buf5[] = {"\r\nPower|"},buf6[2] = {0},buf7[] = {"dBm\r\nFrequency |"},buf8[10] = {0};int buf2len = 0;if (NVS_Buff[0] == '0'){switch(NVS_Buff[1]){case '0':memcpy(buf2,"2400",4);buf2len = 4;break;case '1':memcpy(buf2,"4800",4);buf2len = 4;break;case '2':memcpy(buf2,"9600",4);buf2len = 4;break;case '3':memcpy(buf2,"19200",5);buf2len = 5;break;case '4':memcpy(buf2,"38400",5);buf2len = 5;break;case '5':memcpy(buf2,"57600",5);buf2len = 5;break;case '6':memcpy(buf2,"115200",6);buf2len = 6;break;default:memcpy(buf2,"115200",6);buf2len = 6;break;}}else{memcpy(buf2,"115200",6);buf2len = 6;}// 地址if (input_adjust(NVS_Buff[2]) && input_adjust(NVS_Buff[3]) &&input_adjust(NVS_Buff[4]) && input_adjust(NVS_Buff[5])){memcpy(buf4,NVS_Buff + 2,4);}else{memcpy(buf4,"0000",4);}if( ((NVS_Buff[6] - '0')*10 + (NVS_Buff[7] - '0')) <=14){memcpy(buf6,NVS_Buff + 6,2);}else{memcpy(buf6,"15",2);}int range_value = ((NVS_Buff[8] - '0') * 1000) + ((NVS_Buff[9] - '0') * 100) + ((NVS_Buff[10] - '0') * 10) + (NVS_Buff[11] - '0');if (range_value < 27 && range_value >= 0){range_value = range_value * 5 + 8630;memcpy(buf8,"868.0MHz\r\n",10);buf8[4] = (range_value % 10) + '0';buf8[2] = (range_value % 100 / 10) + '0';buf8[1] = (range_value % 1000 / 100) + '0';}else{memcpy(buf8,"868.0MHz\r\n",10);}memcpy(buf,buf1,sizeof(buf1)-1);len += (sizeof(buf1)-1);memcpy(buf + len,buf2,buf2len);len += buf2len;memcpy(buf + len,buf3,sizeof(buf3)-1);len += (sizeof(buf3)-1);memcpy(buf + len,buf4,sizeof(buf4));len += sizeof(buf4);memcpy(buf + len,buf5,sizeof(buf5)-1);len += (sizeof(buf5)-1);memcpy(buf + len,buf6,sizeof(buf6));len += sizeof(buf6);memcpy(buf + len,buf7,sizeof(buf7)-1);len += (sizeof(buf7)-1);memcpy(buf + len,buf8,sizeof(buf8));len += sizeof(buf8);return len; }/************************串口命令部分*****************************************/volatile static uint8_t sn_respondflag;uint8_t attention_buff[20] = {0};void write_address(uint8_t *command) {my_nvs_read(attention_buff, 0, 12);memcpy(attention_buff+2,command,4);my_nvs_write(attention_buff, 0, 12);}// 设置配对模式 void set_flag(int a) {// 记录为1char bb[2] ={0};if(a==1){bb[0] = 0x01;}else if(a == 0){bb[0] = 0;}else if(a == 2){bb[0] = 0x02;}my_nvs_read(attention_buff, 0, 18); //memcpy(attention_buff+16,(uint8_t*)bb,1);attention_buff[16] = bb[0];my_nvs_write(attention_buff, 0, 18);my_watchdog_start(1);CPUdelay(8000*50);}// 读取配对模式 int read_flag(void) {my_nvs_read(attention_buff, 0, 18);//my_memcmp(attention_buff[16],"BPS",1)if(attention_buff[16] == 0xFF || attention_buff[16] == 2){return 2;}else if(attention_buff[16] == 0){return 0;} //if(attention_buff[16] == 2) //{ //return 2; //} //else if(attention_buff[16] == 0xFF || attention_buff[16] == 0) //{ //return 0; //}else if(attention_buff[16] == 1){return 1;}return 0; }static uint8_t Get_Random() {uint32_t ln_random;Power_setDependency(PowerCC26XX_PERIPH_TRNG);TRNGEnable();while (!(TRNGStatusGet() & TRNG_NUMBER_READY)){}ln_random = TRNGNumberGet(TRNG_LOW_WORD);TRNGDisable();Power_releaseDependency(PowerCC26XX_PERIPH_TRNG);return ln_random; }uint8_t adjust_atcommand(uint8_t *command,uint8_t len) {uint8_t * P = command;int32_t range_value = 0;if(my_memcmp(P,"AT+",3) == FALSE){return STATUS_CMD_ERR;}else{P += 3;//修改波特率,注意修改后要切換波特率if(my_memcmp(P,"BPS",3)){P += 4;range_value = ((P[0] - 48) * 10) + (P[1] - 48);//输入参数不正确,打印错误信息if((len - 3 - 4) != 2 || range_value < 0 || range_value > 6){memcpy(attention_buff,"ERR:1\r\n",7);UART_write(uart0, attention_buff, 7);memset(attention_buff,0,20);return STATUS_CMD_PARAMENT_ERR;}//输入参数正确,保存,打印成功信息else{my_nvs_read(attention_buff, 0, 12);memcpy(attention_buff,P,2);my_nvs_write(attention_buff, 0, 12);memset(attention_buff,0,20);memcpy(attention_buff,"BPS:",4);memcpy(attention_buff+4,P,2);memcpy(attention_buff+4+2,"\r\n",2);UART_write(uart0, attention_buff, 8);memset(attention_buff,0,20);my_watchdog_start(1);CPUdelay(8000*50);return STATUS_CMD_BPS;}}if(my_memcmp(P,"ADDR",4)){P += 5;//输入参数不正确,打印错误信息if((len - 3 - 5) != 4){memcpy(attention_buff,"LEN:1\r\n",7);UART_write(uart0, attention_buff, 7);}else if(input_adjust(P[0]) ==false){memcpy(attention_buff,"P0:1\r\n",6);UART_write(uart0, attention_buff, 6);}if((len - 3 - 5) != 4 || input_adjust(P[0]) ==false|| input_adjust(P[1]) == false ||input_adjust(P[2]) == false || input_adjust(P[3]) == false){memcpy(attention_buff,"ARR:1\r\n",7);UART_write(uart0, attention_buff, 7);memset(attention_buff,0,20);return STATUS_CMD_PARAMENT_ERR;}else{my_nvs_read(attention_buff, 0, 12);memcpy(attention_buff+2,P,4);my_nvs_write(attention_buff, 0, 12);memcpy(attention_buff,"ADDR:",5);memcpy(attention_buff+5,P,4);memcpy(attention_buff+5+4,"\r\n",2);UART_write(uart0, attention_buff, 11);memset(attention_buff,0,20);my_watchdog_start(1);CPUdelay(8000*50);return STATUS_CMD_ADDR;}}if(my_memcmp(P,"START",5)){//sn_respondflag = 1;//Clock_start(clkHandle);//my_nvs_read(attention_buff, 0, 18);memcpy(attention_buff,"START\r\n",7);UART_write(uart0, attention_buff+16, 1);// 记录为1my_nvs_read(attention_buff, 0, 18); //memcpy(attention_buff+2,P,4);char bb[2] ={0};bb[0] = 1;memcpy(attention_buff+16,(uint8_t*)bb,1);my_nvs_write(attention_buff, 0, 18);my_watchdog_start(1);CPUdelay(8000*50);return STATUS_CMD_POW;}if(my_memcmp(P,"PAIRNO",6)){//sn_respondflag = 1;//Clock_start(clkHandle);//my_nvs_read(attention_buff, 0, 18);memcpy(attention_buff,"START\r\n",7);UART_write(uart0, attention_buff+16, 1);// 记录为1my_nvs_read(attention_buff, 0, 18); //memcpy(attention_buff+2,P,4);char bb[2] ={0};bb[0] = 0xFF;memcpy(attention_buff+16,(uint8_t*)bb,1);my_nvs_write(attention_buff, 0, 18);my_watchdog_start(1);CPUdelay(8000*50);return STATUS_CMD_POW;}if(my_memcmp(P,"STOP",4)){//sn_respondflag = 0;//Clock_stop(clkHandle);// 记录为0my_nvs_read(attention_buff, 0, 18); //memcpy(attention_buff+2,P,4);char bb[2] ={0};bb[0] = 0;memcpy(attention_buff+16,(uint8_t*)bb,1);my_nvs_write(attention_buff, 0, 18);set_btnClock_start();memcpy(attention_buff,"STOP\r\n",6);UART_write(uart0, attention_buff, 6);my_watchdog_start(1);CPUdelay(8000*50);return STATUS_CMD_POW;}if(my_memcmp(P,"READ",4)){// 读取my_nvs_read(attention_buff, 0, 18);UART_write(uart0, attention_buff+16, 1);return STATUS_CMD_POW;}if(my_memcmp(P,"RANDOM",6)){// 随机值uint8_t address_buff[20] = {0};my_nvs_read(attention_buff, 0, 12); //address_buff[2] = Get_Random1(); //address_buff[3] = Get_Random1();address_buff[0] = attention_buff[2];address_buff[1] = attention_buff[3];//attention_buff[0] = (uint8_t)Get_Random();UART_write(uart0, address_buff, 2);return STATUS_CMD_POW;}if(my_memcmp(P,"DADDR",5)){//network();memcpy(attention_buff,"DADDR\r\n",7);UART_write(uart0, attention_buff, 7);return STATUS_CMD_POW;}//if(my_memcmp(P,"START",5)) //{ ////sn_respondflag = 1; //Clock_start(clkHandle); //memcpy(attention_buff,"START\r\n",7); //UART_write(uart0, attention_buff, 7); //return STATUS_CMD_POW; //} ////if(my_memcmp(P,"STOP",4)) //{ ////sn_respondflag = 0; //Clock_stop(clkHandle); //memcpy(attention_buff,"STOP\r\n",6); //UART_write(uart0, attention_buff, 6); //return STATUS_CMD_POW; //}if(my_memcmp(P,"POW",3)){P += 4;range_value = ((P[0] - 48) * 10) + (P[1] - 48);//输入参数不正确,打印错误信息if((len - 3 - 4) != 2 || (range_value != 6 && range_value != 10 &&\range_value != 13 && range_value != 14 && range_value != 15)){memcpy(attention_buff,"ERR:1\r\n",7);UART_write(uart0, attention_buff, 7);memset(attention_buff,0,20);return STATUS_CMD_PARAMENT_ERR;}//输入参数正确,保存,打印成功信息,重启else{my_nvs_read(attention_buff, 0, 12);memcpy(attention_buff+6,P,2);my_nvs_write(attention_buff, 0, 12);memcpy(attention_buff,"POW:",4);memcpy(attention_buff+4,P,2);memcpy(attention_buff+4+2,"\r\n",2);UART_write(uart0, attention_buff, 8);memset(attention_buff,0,20);my_watchdog_start(1);CPUdelay(8000*50);return STATUS_CMD_POW;}}if(my_memcmp(P,"CGCN",4)){P += 5;range_value = ((P[0] - 48) * 1000) + ((P[1] - 48)*100) + ((P[2] - 48)*10) + (P[3] - 48);//输入参数不正确,打印错误信息if((len - 3 - 5) != 4 || range_value < 0 || range_value > 26 ){memcpy(attention_buff,"ERR:1\r\n",7);UART_write(uart0, attention_buff, 7);memset(attention_buff,0,20);return STATUS_CMD_PARAMENT_ERR;}else{my_nvs_read(attention_buff, 0, 12);memcpy(attention_buff+8,P,4);my_nvs_write(attention_buff, 0, 12);memcpy(attention_buff,"CGCN:",5);memcpy(attention_buff+5,P,4);memcpy(attention_buff+5+4,"\r\n",2);UART_write(uart0, attention_buff, 11);memset(attention_buff,0,20);my_watchdog_start(1);CPUdelay(8000*50);return STATUS_CMD_CGCN;}}if (my_memcmp(P,"CONFIG",6)){char i[80];int slen =Create_configString(i);UART_write(uart0, i, slen);return STATUS_CMD_CONFIG;}}return STATUS_CMD_ERR;}void update_bps(uint8_t * para) {//flash中无数据,默认115200if(para[0] == 0xff && para[1] == 0xff){uatr_init(115200);waitTime = 1;}// 00波特率2400else if(para[0] == '0' && para[1] == '0'){uatr_init(2400);waitTime = 16;}// 01波特率4800else if(para[0] == '0' && para[1] == '1'){uatr_init(4800);waitTime = 8;}// 02波特率9600else if(para[0] == '0' && para[1] == '2'){uatr_init(9600);waitTime = 4;}// 03波特率19200else if(para[0] == '0' && para[1] == '3'){uatr_init(19200);waitTime = 2;}// 04波特率38400else if(para[0] == '0' && para[1] == '4'){uatr_init(38400);waitTime = 2;}// 05波特率57600else if(para[0] == '0' && para[1] == '5'){uatr_init(57600);waitTime = 2;}// 06波特率115200else{uatr_init(115200);waitTime = 1;} }
,
Nick Sun:
您好,
收到您的跟进消息,有结论答复您。
感谢您的支持。
,
zijun li:
Hi Nick,
一周了都没有收到您的消息,请问有解决方法了吗?
,
Nick Sun:
您好,
不好意思由于一些原因回复晚了。这边是我们工程师的一些问题:
您这边是用的SDK是什么版本的?
你的两个失败案例的现象是什么,能具体描述一下吗?clock启动 API 是否返回失败状态?你能发布失败状态吗?
NVS_write 可能需要一些时间才能完成,这取决于你写了多少以及写是否触发了压缩。您是否在等待 NVS_write 在启动时钟之前返回?或者你在不同的线程中启动时钟?原文如下:
1) Which version of the SDK are they using?
2) What is the symptom in your two fail cases? Does the clock start API return a fail status? Can you post the fail status?
3) NVS_write can take some time to complete, depending on how much you're writing and whether the write trigger a compaction. Are you waiting for NVS_write to return before starting the clock? Or are you starting the clock in a different thread?