/** ****************************************************************************** * File Name : can_comm.c * Description : This file provides code for the configuration * of the CAN communication instances. ****************************************************************************** * @attention * *

© Copyright (c) 2019 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under Ultimate Liberty license * SLA0044, the "License"; You may not use this file except in compliance with * the License. You may obtain a copy of the License at: * www.st.com/SLA0044 * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "malloc.h" //Memory pool (4-byte alignment) __align(4) uint8_t membase[MEM_MAX_SIZE]; // __attribute__((at(0x10000000))); //CMM within the memory pool //Memory management tables __align(4) uint16_t memmapbase[MEM_ALLOC_TABLE_SIZE]; // __attribute__((at(0X10000000 + MEM3_MAX_SIZE))); //Internal CCM pools MAP //Memory management parameters const uint32_t memtblsize = MEM_ALLOC_TABLE_SIZE; //Memory table size const uint32_t memblksize = MEM_BLOCK_SIZE; //Memory block size const uint32_t memsize = MEM_MAX_SIZE; //Total memory size //Memory management controller struct _m_mallco_dev mallco_dev = { mymem_init, //Memory initialization mem_perused, //Memory usage membase, //Memory pool memmapbase, //Memory management tables 0, //Memory management is not ready }; //Copy memory //*des:Destination address //*src:Source address //n:Need to copy memory length (bytes) void mymemcpy(void *des,void *src,uint32_t n) { uint8_t *xdes = des; uint8_t *xsrc = src; while(n--) *xdes++ = *xsrc++; } //Setting memory //*s:Memory address //c :The value to be set //count:Need to set the memory size(Bytes) void mymemset(void*s,uint8_t c,uint32_t count) { uint8_t *xs = s; while(count--) *xs++=c; } //Memory management class //memx:Belongs to a block of memory void mymem_init(void) { mymemset(mallco_dev.memmap, 0, memtblsize * 2); // Memory status table is cleared to zero mymemset(mallco_dev.membase, 0, memsize); // Memory pool all data to zero mallco_dev.memrdy = 1; // Memory initialized OK } //Get memory usage //memx:Belongs to a block of memory //Return value: usage (0~100) uint8_t mem_perused(void) { uint32_t used = 0; uint32_t i; for (i = 0; i < memtblsize; i++) { if (mallco_dev.memmap[i]) used++; } return (used * 100) / (memtblsize); } // Memory allocation (internal call) // size:Amount of memory to allocate (in bytes) // The return value:0XFFFFFFFF,To indicate an error; the other, the memory offset uint32_t _mem_malloc(uint32_t size) { signed long offset = 0; uint16_t nmemb; // Required number of memory blocks uint16_t cmemb = 0; // Number of contiguous blocks of free memory uint32_t i; if (!mallco_dev.memrdy) mallco_dev.init(); // Is not initialized, perform the initialization if (size == 0) return 0XFFFFFFFF; // Do not need to allocate nmemb = size / memblksize; // Gets the required number of contiguous blocks of memory allocated if (size % memblksize) nmemb++; for (offset = memtblsize - 1; offset >= 0; offset--) // Search the entire memory control { if (!mallco_dev.memmap[offset]) cmemb++; // Increase the number of contiguous blocks of free memory else cmemb = 0; // Contiguous blocks of memory to zero if (cmemb == nmemb) // Find nmemb consecutive empty memory blocks { for (i = 0; i < nmemb; i++) // Mark a block of memory is not empty { mallco_dev.memmap[offset+i] = nmemb; } return (offset*memblksize); // Returns the offset address } } return 0XFFFFFFFF; // Not found consistent with allocated memory block } //Free memory (internal call) //offset:Memory address of offset //Return values: 0, release success; 1, release failed; uint8_t _mem_free(uint32_t offset) { int i; if (!mallco_dev.memrdy) // Is not initialized, perform the initialization { mallco_dev.init(); return 1; // Not initialized } if (offset < memsize) // Offset within the memory pool. { int index = offset / memblksize; // Offset where the memory block number int nmemb=mallco_dev.memmap[index]; // Number of memory blocks for (i = 0; i < nmemb; i++) // Zero out memory blocks { mallco_dev.memmap[index+i] = 0; } return 0; } else return 2; // Offset Super. } //Free memory (external call) //ptr:Memory address void myfree(void *ptr) { uint32_t offset; if (ptr == NULL) return; // Address 0. offset = (uint32_t)ptr - (uint32_t)mallco_dev.membase; _mem_free(offset); //Free up memory } //Allocating memory(External call) //size:Memory size (in bytes) //Return values: the first address of the allocated memory. void *mymalloc(uint32_t size) { uint32_t offset; offset = _mem_malloc(size); if (offset == 0XFFFFFFFF) return NULL; else return (void*)((uint32_t)mallco_dev.membase + offset); } //Reallocating memory (external call) //*ptr:The old memory address //size:Amount of memory to allocate (in bytes) //Return values: the first address of the newly allocated memory. void *myrealloc(void *ptr,uint32_t size) { uint32_t offset; offset = _mem_malloc(size); if (offset == 0XFFFFFFFF) return NULL; else { mymemcpy((void*)((uint32_t)mallco_dev.membase + offset), ptr, size); // Copy the old memory contents to the new memory myfree(ptr); // Free old memory return (void*)((uint32_t)mallco_dev.membase + offset); // Returns a new memory address } }