我这里主要是记录一下我所使用的方法,调试也花了两天时间。
我所用的型号是STM32F103C8T6,这个IC有64KFlash和20K的RAM,也有小道说有后置隐藏的64K,也就是说其实是有128K,我一直也没有测试,有空测测,有大神这样说,估计是可以的。
这里重点记录一下我写的IAP思路和代码以及细节和遇到坑的地方。先大体的概述一下,最后贴上我认为重点的代码。
在概述之前先要解决一个问题,那就是sram空间和flash空间的问题,sram只有20K,flash有64k。
解决的办法有很多:
1)最常见的就是自己写上位机软件,通过分包发送,期间还可以加入加密算法,校验等等。
2)使用环形队列,简单点说就是个环形数组,一边接收上位机数据,一边往flash里面写。
这里条件限制就采用第二种方法。所以即使是分给A和B的25K空间的flash空间,sram只有20K也是不能一次接收完所有的bin数据的,这里我只开辟了一个1K的BUF,使用尾插法写入,我的测试应用程序都在5-6K,用这样的方法可以在9600波特率下测试稳定,也试过57600的勉强可以的,115200就不行了。
环形队列代码如下:
C文件:
- #include "fy_looplist.h"
-
- #include "fy_includes.h"
-
-
- #ifndef NULL
- #define NULL 0
- #endif
-
- #ifndef min
- #define min(a, b) (a)<(b)?(a):(b) //< 获取最小值
- #endif
-
- #define DEBUG_LOOP 1
-
- static int Create(_loopList_s* p,unsigned char *buf,unsigned int len);
- static void Delete(_loopList_s* p);
- static int Get_Capacity(_loopList_s *p);
- static int Get_CanRead(_loopList_s *p);
- static int Get_CanWrite(_loopList_s *p);
- static int Read(_loopList_s *p, void *buf, unsigned int len);
- static int Write(_loopList_s *p, const void *buf, unsigned int len);
-
- struct _typdef_LoopList _list=
- {
- Create,
- Delete,
- Get_Capacity,
- Get_CanRead,
- Get_CanWrite,
- Read,
- Write
- };
-
-
- //初始化环形缓冲区
- static int Create(_loopList_s* p,unsigned char *buf,unsigned int len)
- {
- if(NULL == p)
- {
- #if DEBUG_LOOP
- printf("ERROR: input list is NULL\n");
- #endif
- return 0;
- }
- p->capacity = len;
- p->buf = buf;
- p->head = p->buf;//头指向数组首地址
- p->tail = p->buf;//尾指向数组首地址
-
- return 1;
- }
-
- //删除一个环形缓冲区
- static void Delete(_loopList_s* p)
- {
- if(NULL == p)
- {
- #if DEBUG_LOOP
- printf("ERROR: input list is NULL\n");
- #endif
- return;
- }
-
- p->buf = NULL;//地址赋值为空
- p->head = NULL;//头地址为空
- p->tail = NULL;//尾地址尾空
- p->capacity = 0;//长度为空
- }
-
- //获取链表的长度
- static int Get_Capacity(_loopList_s *p)
- {
- if(NULL == p)
- {
- #if DEBUG_LOOP
- printf("ERROR: input list is NULL\n");
- #endif
- return -1;
- }
- return p->capacity;
- }
-
- //返回能读的空间
- static int Get_CanRead(_loopList_s *p)
- {
- if(NULL == p)
- {
- #if DEBUG_LOOP
- printf("ERROR: input list is NULL\n");
- #endif
- return -1;
- }
-
- if(p->head == p->tail)//头与尾相遇
- {
- return 0;
- }
-
- if(p->head < p->tail)//尾大于头
- {
- return p->tail - p->head;
- }
-
- return Get_Capacity(p) - (p->head - p->tail);//头大于尾
- }
-
- //返回能写入的空间
- static int Get_CanWrite(_loopList_s *p)
- {
- if(NULL == p)
- {
- #if DEBUG_LOOP
- printf("ERROR: input list is NULL\n");
- #endif
- return -1;
- }
-
- return Get_Capacity(p) - Get_CanRead(p);//总的减去已经写入的空间
- }
-
-
- // p--要读的环形链表
- // buf--读出的数据
- // count--读的个数
- static int Read(_loopList_s *p, void *buf, unsigned int len)
- {
- int copySz = 0;
-
- if(NULL == p)
- {
- #if DEBUG_LOOP
- printf("ERROR: input list is NULL\n");
- #endif
- return -1;
- }
-
- if(NULL == buf)
- {
- #if DEBUG_LOOP
- printf("ERROR: input buf is NULL\n");
- #endif
- return -2;
- }
-
- if(p->head < p->tail)//尾大于头
- {
- copySz = min(len, Get_CanRead(p)); //比较能读的个数
- memcpy(buf, p->head, copySz); //读出数据
- p->head += copySz; //头指针加上读取的个数
- return copySz; //返回读取的个数
- }
- else //头大于等于了尾
- {
- if (len < Get_Capacity(p)-(p->head - p->buf))//读的个数小于头上面的数据量
- {
- copySz = len;//读出的个数
- memcpy(buf, p->head, copySz);
- p->head += copySz;
- return copySz;
- }
- else//读的个数大于头上面的数据量
- {
- copySz = Get_Capacity(p) - (p->head - p->buf);//先读出来头上面的数据
- memcpy(buf, p->head, copySz);
- p->head = p->buf;//头指针指向数组的首地址
- //还要读的个数
- copySz += Read(p,(char*)buf+copySz, len-copySz);//接着读剩余要读的个数
- return copySz;
- }
- }
- }
- // p--要写的环形链表
- // buf--写出的数据
- // len--写的个数
- static int Write(_loopList_s *p, const void *buf, unsigned int len)
- {
- int tailAvailSz = 0;//尾部剩余空间
-
- if(NULL == p)
- {
- #if DEBUG_LOOP
- printf("ERROR: list is empty \n");
- #endif
- return -1;
- }
-
- if(NULL == buf)
- {
- #if DEBUG_LOOP
- printf("ERROR: buf is empty \n");
- #endif
- return -2;
- }
-
- if (len >= Get_CanWrite(p))//如果剩余的空间不够
- {
- #if DEBUG_LOOP
- printf("ERROR: no memory \n");
- #endif
- return -3;
- }
-
- if (p->head <= p->tail)//头小于等于尾
- {
- tailAvailSz = Get_Capacity(p) - (p->tail - p->buf); //查看尾上面剩余的空间
- if (len <= tailAvailSz)//个数小于等于尾上面剩余的空间
- {
- memcpy(p->tail, buf, len);//拷贝数据到环形数组
- p->tail += len;//尾指针加上数据个数
- if (p->tail == p->buf+Get_Capacity(p))//正好写到最后
- {
- p->tail = p->buf;//尾指向数组的首地址
- }
- return len;//返回写入的数据个数
- }
- else
- {
- memcpy(p->tail, buf, tailAvailSz); //填入尾上面剩余的空间
- p->tail = p->buf; //尾指针指向数组首地址
- //剩余空间 剩余数据的首地址 剩余数据的个数
- return tailAvailSz + Write(p, (char*)buf+tailAvailSz, len-tailAvailSz);//接着写剩余的数据
- }
- }
- else //头大于尾
- {
- memcpy(p->tail, buf, len);
- p->tail += len;
- return len;
- }
- }
-
-
- /*********************************************END OF FILE********************************************/
|