Akik Conscience still lives

Welcome to add a wechat account: Conscious Remains

An overview

Used to develop and then encountered such a situation, our equipment is the on-board equipment, need to report the real-time vehicle data in the process of vehicle, but due to the use of the network side is 2 g network, in the process of driving, will have bad signal leads to the situation of the network interruption, the earliest time for configuration networking state machine soon, heavy Internet time is very small, I just chose to reconnect and then report. However, in the actual use process, it is found that the switch of base station and bad network signal will lead to network interruption, and the reconnection mechanism is not always very fast. Therefore, I began to consider saving the data locally and make up the report again after the success of networking. I will introduce the specific ideas below.

The development experience of a blind spot supplement for embedded Network devices (A) This is the last article.

Second, the introduction of the program

After yesterday’s presentation of the data structure from receiving the project to finally selecting the implementation, LET me take a look at the actual code.

First of all, we need to be clear about the data reported in blind spot supplement. The data cannot be uploaded in real time due to network interruption due to various reasons in the process of vehicle running. At this time, some information of the vehicle needs to be saved locally and reported to the server after successfully reconnected.

Start with a structure that supports data storage: UTC time and latitude and longitude, as well as some basic vehicle information

Copy the code
__packed typedef struct { u32 year :12; // year u32 month :4; // month u32 day :5; // u32 hour :5; // u32 min :6; // min u8 SEC :6; // SEC u8 res :2; }utcTypeDef; */ __packed typedef struct {utcTypeDef UTC; /*nmea_utc_time; u32 Longitude; u32 Latitude; u16 Speed; u16 RPM; }Message;Copy the code

Start defining the size of memory that we need to save and allocate, and there’s a hint that when allocating, because it’s malloc, we allocate memory for the data heap on the chip, so the first thing to allocate is to set the size of the heap.

First, we use a two-level pointer (the address of the first-level pointer points to the stored data, the address of the second-level pointer points to the address of the first-level pointer), a one-time allocation method for stack sorting storage, using all the first step to initialize the stack space and header address.

​​​​​​​

/* global */ const int MaxCachesLen = 22 * 1024; const int MaxCachesCount = MaxCachesLen / sizeof(Message); u32 g_CachesCount = 0; // cache count Message** g_Caches =NULL; // malloc(sizeof(char*) * MaxCachesCount); void GpsCacheInit(void) { g_Caches = (Message**)malloc(sizeof(Message*) * MaxCachesCount); //MaxCachesCount); MaxCachesCount Specifies the first address of the cache spaceif(NULL == g_Caches)
  {
    LOG("malloc g_cahce error\r\n"); //DEBUG
  }else{
    LOG("malloc g_cahce suc\r\n"); //DEBUG
  }
}
int GetCachesTotalSize(void){
 return sizeof(Message) * g_CachesCount;
}Copy the code

Functions to write to and out of the stack:Copy the code

​​​​​​​

// u32 Push(Message item) {/* If it is full, empty the address of the last data address on the stack, discard the old data and rearrange the address above the stack */if(GetCachesTotalSize() >= MaxCachesLen || g_CachesCount >= MaxCachesCount) { free((g_Caches[g_CachesCount - 1])); // free memmove(g_Caches + 1, g_Caches, sizeof(Message*) * (g_CachesCount-1)); }else{ memmove(g_Caches + 1, g_Caches, sizeof(Message*) * g_CachesCount); g_CachesCount++; } /* Allocate new address pointer space to stack */ Message* newItem = (Message*)malloc(sizeof(Message));if(NULL == newItem)
 {
   LOG("newItem NULL\r\n");
   return 0;
 }
 else{
   *newItem = item;
   g_Caches[0] = newItem;
   LOG("newItem success\r\n");
   return1; }}Copy the code

Copy the code

Pack and push the vehicle information in the running state into the stack (there are two ways to save it: one is to convert the UTC into the count of seconds and store it in the memory; the other is to use the data structure and store it in the memory. Finally, I choose the first way)

​​​​​​​

U8 InCache(void)/* Cache package */ {u8 ret; /* Get the UTC of the current GPS */ Message pIn; pIn.utc.year = gpsx.utc.year; pIn.utc.month = gpsx.utc.month; pIn.utc.day = gpsx.utc.date; pIn.utc.hour = gpsx.utc.hour; pIn.utc.min = gpsx.utc.min; pIn.utc.sec = gpsx.utc.sec;; // pIn.utc = UTC2Sec(gpsUtc); // Convert to second storage pIn.Latitude = gpsx.latitude; pIn.Longitude = gpsx.longitude; pIn.RPM = carPulse.EngRpm ; pIn.Speed = carPulse.carSpeed; ret = Push(pIn); LOG("Incache Message Count:%d.TotalSize:%d\r\n",g_CachesCount,GetCachesTotalSize());
  return ret;
}Copy the code

 Copy the code

Take the data out of the stack and package it to the server

u8 OutCache(void)
{
  u8 ret=0;
  Message pOut;
  ret = Pop(&pOut);
  if(ret)
  {
    LOG("outcache Message Count:%d.TotalSize:%d\r\n",g_CachesCount,GetCachesTotalSize()); char *p,*p1,*p2,length; p2= malloc(30); p=malloc(300); p1=p; Memset (p, 0 x00, 300); Memset (p2, 0 x00, 30);if(p1 == NULL )
    {
      LOG("%s:malloc p1 fault! \n", __FILE__);
      return 0;
    }


    sprintf(p2,"%04d-%02d-%02d %02d:%02d:%02d,",pOut.utc.year,pOut.utc.month,pOut.utc.day,pOut.utc.hour,pOut.utc.min,pOut.utc.sec); strcat(p1,p2); / / 1, 2, 3 / * * / memset (p2, 0 x00, 20); /* sprintf(p2,"%03d.%05d,%02d.%05d, ,",(pOut.Longitude/100000),(pOut.Longitude%100000),(pOut.Latitude/100000),(pOut.Latitude%100000)); strcat(p1,p2); / / 4 memset (p2, 0 x00, 20); sprintf(p2,"%d,",pOut.Speed); / / speed strcat (p1, p2); p1=p; length = strlen(p); p[length] = MsgOrCRC((u8*)&p[2],length-2); SendBuf(USART1, p, length+1); free(p); free(p2); }return ret;
}Copy the code


This is the second blind spot supplement article I share, the code is practiced, if you have a better idea, welcome to share and exchange ha.