用IAR  jlink调试的时候,总是出错,告诉寄存器15读不到,当cpu运行的时候,后来把jlink附近的跳帽拔掉了,(k2的reset和jlink短接),引到上面之后,问题就解决了
一个设备如果想要通过IAP升级的话,就一定要自己编写bootloader。
nankai的k2和转换器都是ST的, k2的bootloader起始地址是0x08000000  开始  应用程序是从0x08002000开始的
                                   转换器的bootloader起始地址是0x08000000  开始  应用程序是从0x08005000开始的
一般情况下,bootloader和app程序都是分别编译的,所有就会产生两个bin文件,我们不能分别下载到目标板上,所有要进行bin文件合并,有两种方式,1是通过软件合并,简单,但是不能保存一些编译的配置信息。每次都要重新配置,调试麻烦。  2,通过编写批处理文件实现,详情见我的博文收藏里面
转换器的的bootloader和app程序都有,k2之后app的有   bootloader是没有的。这两个产品都能通过IAP更新程序。  把bin文件合并后,可以通过jlink的工具,下载到目标板上(此时用到的是st自带的bootloader引导的),以后就可以用串口直接更新应用程序了。。
 
1,我曾试过改k2的应用程序的地址地址为0x08002100开始,之后改了下iar中断icf文件,把向量中断起始位置和rom的起始位置都变成0x08002100
之后把NVIC_SetVectorTable(0x08000000, 0x2100); 
编译后,下载 程序就跑飞,又试着改了几个值,都有问题,原因是STM32如果要更改中断向量的起始地址,偏移地址一定要是0x200的整数倍,原因stm就是这么规定的,如果不是整数倍,可能会出现问题。
 
 
关于锁的理解
同步时间里面有个锁,锁的作用是防止调用同一个函数而造成冲突(多任务的情况,或者中断调用),
inline void AppProcSyncTime(uint8 *MsgBuff,uint16 MsgLen)
{
static  uint8stc_LockFlag = 0;
static  SFtuDspClock stc_CurClock;
 
if(stc_LockFlag) return;
stc_LockFlag = 1; // 锁
 
stc_CurClock.year = MsgBuff[0] + 2000;
stc_CurClock.month = MsgBuff[1];
stc_CurClock.day = MsgBuff[2];
stc_CurClock.hour = MsgBuff[3];
stc_CurClock.minute = MsgBuff[4];
stc_CurClock.second = MsgBuff[5];
stc_CurClock.msecond = (uint16)MsgBuff[6] + ((uint16)MsgBuff[7] << 8);
 
SetDspClock(&stc_CurClock);
 
stc_LockFlag = 0; // 解锁
}
 
怎么样保证任务的实时性,
1,有操作系统的比无操作系统的实时性要高,裸机的情况下,操作是按照逻辑循序下来的,其中如果必然有的要求实时性高,实时性低,要求高的只能用“中断”来进行处理,
且中间如出去问题的话,直接会影响其他的功能处理过程。但是带操作系统的,如果功能简单的话,相反会更加耗费cpu。如果功能简单,不需要文件系统,GUI,和tcp ip协议栈之类的话,就没有必要用操作系统了。
2.有操作系统的,有优先级的感念,要求实时性高的任务,可以优先级高些,或者中断触发。 有操作系统的怎么保证实时性呢,主要就是任务的优先级划分和中断触发的合理使用。
 
我一直想知道cpu运行一个程序,多长时间能跑一个循环,今天拿K2测试了一下,k2的主频是72MHz的,stm32F103ret6   程序里跑的是通讯的,南凯的内部规约,我用超级终端不停的和k2进行通讯,在这种有简单负载的情况下,大约可以15微秒跑一个循环,如果没有负载的话,大约7微秒左右,我想如果要是跑协议的话,怎么也能达到,1ms一次,也就是1s跑1000次循环。cpu太tm强大了。
 
2013 12 19  
移植k2中的程序问总结,
一,我从IAR中一直到keil当中,遇到一些问题,for(int i=0;i<8;i++) 这么写IAR就没有问题,而keil就不行,必须再前面先定义好i,不能再for循环里
直接定义,必须先int i;  for(i=0;i<8;i++)  。不知道是不是设置的问题。
二,IAR在一个函数体内,的局部变量在哪里定义都行,我可以先不定义,之后写执行语句,之后需要局部变量了,再定义。但是keil就不行,必须函数体内的所有变量必须定义在执行语句的前面,也就是一开就要把全部用到的局部变量都定义完,不容许在函数中间定义。这个很操蛋。
三,关于头文件的问题,以后写头文件记住了,必须都按照#ifndef __hello_h
                                                                                        #define __hello_h
                                                                                             .........
                                                                                           #endif
否则的话到后来头文件越来越多,你应用的时候如果重新应用了,错误一大堆,相当麻烦
四,以后养成好的习惯,在别的文件用到外部变量int a的时候,要先找到他自身的所在文件,之后在他的头文件里面添加extern int a;   之后在所用的文件中的想匹配的头文件中添加那个变量的头文件,切记不要直接在文件头部,添加extern int a; 养成习惯,要不以后也是麻烦。慢慢你会知道的。
五,关于数据通讯 的数据结构的创建,看单位写的那个小本,都记载上面了,那是以移植k2的modbus为例写的。
 
2013  12 23
一直纠结can中断是怎么回事,接受中断无疑是硬件中断,只有硬件检测存放接受数据的寄存器有数据了,自然触发中断,但是发送中断是怎么触发的呢。今天弄明白了,发送中断是靠人为去触发的,只要你开启can的发送中断使能,他就会一直中断,所以要求你没发送一帧报文之后,就要自己关闭发送中断,否则就会死在那里,stm32的自带can有三个发送邮箱,CAN_Transmit(CAN1, &TxMessage);当你调用这个库函数发送消息的时候,他返回的是发送邮箱的编号,之后你要进行判断,。。详细看k2的程序吧,说也说不明白,有点复杂,
can每次发送最多能发送8个字节,所有假设如果一帧报文(以帧为单位)如果有250个字节的话,如果用循环无疑会很麻烦,这种情况下,只要你先用循环发送一次,之后判断发没发完,如果发送了,就不用打开发送中断了,如果没发送,直接打开can的发送中断,让中断发送剩下的帧报文,也就是242个,在can发送的中断中,判断发没发完,如果发完,就关闭can的发送中断使能,否则就一直发,直到发完为止,这就是can中断发送的用法,和uart发送一样,发送中断的触发都是人为使能,消能控制的,k2中的设计是,没发送一帧报文的,前八个字节是循环发送的,剩下的都是can中断发送的,明白了吗》》》
 
2013 12 24 
今天做keil能否支持c++实验,keil的arm版本也叫MDK,发现是可以支持的,在工程的配置里面,【Project】->【Options for Target 'xxx'】->【C/C++】->【Misc Controls】后的编辑框中,填入"--cpp",Keil MDK就可以支持C++,这么配置就支持c++了,但是在编译的时候可能会出错误,因为bool类型,keil和c++可能是重复定义了,直接屏蔽错误代码即可。但是在选择库的时候,最好还是把micro lib选上,不选的话容易出错,原因未知
 
 
2014 12 11
今天装了ccsv5版本的程序,之后要安装仿真器的驱动,但是都安装完之后,在ccs中的newtargetconfiguration中找不到相应的合众达仿真器的选项,百度后,解决
首先安装ccsv5安装到哪里都可以,不分盘符,只要是不含中文目录就可以,之后仿真器要想在ccsv5中找到相应的选项,就一定要把仿真器的驱动安装在ccs安装目录下的
。。\ccsv5\ccs_base目录下,之后重启就可以,找到相应的选项了,之后还要装个Bios,叫做 control suite    这个东西,否则编译程序的时候可能会出现问题,因为没有安装这个,导致This project was created using a version of DSP/BIOS tools that is not currently installed: 5.42.1.09. Please install the DSP/BIOS tools of this version, or migrate(移植的意思) the project to one of the supported versions这个错误