Other Parts Discussed in Thread: CC1310
CC1310在调试过程中,NVS_write 和 Clock会有冲突.比如先调用NVS_write ,然后调用启动Clock,Clock不能启动.或者Clock启动了,调用NVS_write 后,Clock中止了.
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
CC1310在调试过程中,NVS_write 和 Clock会有冲突.比如先调用NVS_write ,然后调用启动Clock,Clock不能启动.或者Clock启动了,调用NVS_write 后,Clock中止了.
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
这个是其中一个文件
#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; /************************辅助函数部分*****************************************/ /*! * @def fix4 * @brief 字节补齐函数,使用此函数要让自己的buffer扩大3个字节 * @para 要补齐的长度 * @return NULL */ 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_t input_adjust(uint8_t adjust) { if(adjust >= '0' && adjust <= '9' || (adjust >= 'A' && adjust <= 'F')) return true; return false; } /********************************************************************* * @fn Change_ASCII_HEX * * @brief 将ASCII码转换成16进制数 * * @param p转换后存储的位置,q要转换的字符串,ss要转换的长度 * * @return none */ /********************************************************************* *********************************************************************/ 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++; } } /********************************************************************* * @fn toadd * * @brief 将相邻的两个16进制数相加 * * @param p转换后存储的位置,q要转换的16进制数组,ss要转换的长度 * * @return none */ /********************************************************************* *********************************************************************/ 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); // } } /************************看门狗函数部分*****************************************/ /*! * @def my_watchdog_start * @brief 启动看门狗,设置看门狗时间 * @para 看门狗时间 此时间不准 * @return NULL */ void my_watchdog_start(uint32_t time_milliseconds) { Watchdog_close(watchdog); Watchdog_setReload(watchdog,Watchdog_convertMsToTicks(watchdog,time_milliseconds)); } /************************flash存储部分*****************************************/ /*! * @def init_my_nvs * @brief 初始化nvs * @para 无 * @return NULL */ void init_my_nvs(void) { NVS_init(); nvsHandle = NVS_open(CC1310DK_5XD_NVS1F000, NULL); } /*! * @def my_nvs_read * @brief 读取nvs中相应位置的数据 * @para 读取数据后存储的位置 * @para 读取flash的位置相对初始位置的偏移量 * @para 要读取的数据的长度,若无四字节对齐,自动对齐,最大补齐长度3。最好设置存储的buff长度增加3 * @return NULL */ void my_nvs_read(uint8_t * buff,uint16_t offset,uint16_t len) { //保证四字节对齐 如果无对齐自动补齐 len = fix4(len); NVS_read(nvsHandle, offset, buff, len); } /*! * @def my_nvs_write * @brief 向nvs中读取数据 * @para 要存储的数据源 * @para 写入flash的位置相对初始位置的偏移量 * @para 要写入的数据的长度,若无四字节对齐,自动对齐,最大补齐长度3。最好设置写入的buff长度增加3 * @return NULL */ 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) { // 记录为1 char 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); // 记录为1 my_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); // 记录为1 my_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); // 记录为0 my_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中无数据,默认115200 if(para[0] == 0xff && para[1] == 0xff) { uatr_init(115200); waitTime = 1; } // 00波特率2400 else if(para[0] == '0' && para[1] == '0') { uatr_init(2400); waitTime = 16; } // 01波特率4800 else if(para[0] == '0' && para[1] == '1') { uatr_init(4800); waitTime = 8; } // 02波特率9600 else if(para[0] == '0' && para[1] == '2') { uatr_init(9600); waitTime = 4; } // 03波特率19200 else if(para[0] == '0' && para[1] == '3') { uatr_init(19200); waitTime = 2; } // 04波特率38400 else if(para[0] == '0' && para[1] == '4') { uatr_init(38400); waitTime = 2; } // 05波特率57600 else if(para[0] == '0' && para[1] == '5') { uatr_init(57600); waitTime = 2; } // 06波特率115200 else { uatr_init(115200); waitTime = 1; } }
您好,
不好意思由于一些原因回复晚了。这边是我们工程师的一些问题:
原文如下:
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?