Files

181 lines
6.0 KiB
C

/**
******************************************************************************
* File Name : can_comm.c
* Description : This file provides code for the configuration
* of the CAN communication instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* 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
}
}