Como posso usar malloc()
e free()
funções em um PIC? Eu verifiquei o stdlib.h
cabeçalho e não há menção a eles. Estou usando o MCC18.
Alguém já teve que usá-los?
Preciso deles porque estou portando uma biblioteca do Windows XP para o PIC. O guia de portabilidade diz para
adaptar as funções específicas do sistema operacional às funções do meu PIC
Mas não sei como "traduzir" as funções malloc()
e free()
.
Respostas:
Em muitos aplicativos, será necessário alocar memória, mas não será necessário liberar nada, mantendo algo que foi alocado após ele. Nesse sistema, tudo o que você precisa fazer é usar o vinculador para definir uma matriz usando toda a RAM disponível, definir um ponteiro para o início dessa matriz e usar uma função malloc fácil e agradável:
Agradável e fácil, e sobrecarga total de apenas dois bytes para qualquer número de alocações. Chamar free () em um bloco desalocará esse bloco e tudo o que está depois dele.
Padrões de alocação ligeiramente mais complicados podem ser manipulados usando dois ponteiros - um que aloca coisas da parte inferior da memória subindo e uma das quais vai da parte superior da memória para baixo. Também é possível usar um coletor de lixo compactador se os dados no heap forem homogêneos e se souber onde estão todas as referências externas a ele.
fonte
malloc()
em microcontroladores é geralmente considerado uma "coisa ruim". Mas, se você absolutamente precisar, encontrará uma versão de terceiros.Se você tiver sorte, o código que você está portando pode não depender da reutilização de blocos de memória. Se for esse o caso, você pode escrever um alocador simples que retorne um ponteiro para um buffer de RAM e avance o ponteiro pelo tamanho do bloco solicitado.
Eu já usei essa abordagem com êxito antes na transferência de bibliotecas de PC para microcontroladores.
Abaixo, você configuraria o alocador
my_malloc_init()
e alocaria memória commy_malloc()
.my_free()
existe para satisfazer a dependência, mas na verdade não faz nada. Eventualmente, você ficará sem espaço, é claro.Para fazer isso funcionar, você precisará medir o pior requisito de memória do seu código (faça isso em um PC, se possível) e configurar de
HEAP_SIZE
acordo. Antes de entrar na parte da sua biblioteca que requer memória dinâmica, liguemy_malloc_init()
. Antes de reutilizar, verifique se ainda não há nada apontadoheap
.(nota: no mundo real, pode ser necessário considerar o alinhamento do ponteiro, ou seja, arredondar para
heap_ptr
2 ou 4 bytes)Outra opção é usar uma estrutura de alocação mais simples do que
malloc()
normalmente é fornecida, como uma FreeList , embora isso possa não permitir a alocação de blocos de tamanho variável.fonte
Isso dificilmente é uma resposta para sua pergunta, mas a alocação dinâmica de memória geralmente é desaprovada em pequenos ambientes de RAM e na ausência de um sistema operacional (por exemplo, no mundo dos microcontroladores) ... o espaço de pilha disponível em um ambiente incorporado geralmente é medido em centenas de bytes ...
Implementar malloc e free é essencialmente a manutenção de uma lista vinculada de estruturas de "segmento livre" e, como você pode imaginar, os metadados associados aos segmentos livres não são substanciais quando comparados à quantidade de memória normalmente disponível ... que é a sobrecarga " "do gerenciamento de um conjunto de memórias dinâmicas consome uma quantidade significativa dos recursos disponíveis.
fonte
Não sei se a biblioteca padrão C18 suporta
malloc
efree
, mas a Microchip App Note AN914 mostra como você pode implementar seus próprios.De qualquer forma, Thomas e outros pôsteres sugeriram que o uso de memória dinâmica em PICs com seu espaço de RAM muito pequeno é repleto de perigos. Você pode ficar rapidamente sem espaço contíguo devido à falta de gerenciadores de memória virtual mais avançados que os sistemas operacionais completos oferecem, levando a falhas de alocações e falhas. Pior, pode não ser determinístico e provavelmente será um problema para depuração.
Se o que você está fazendo é realmente determinado dinamicamente em tempo de execução (raro para a maioria das coisas incorporadas), e você só precisa alocar espaço em algumas ocasiões muito especiais , eu poderia ver
malloc
efree
ser aceitável.fonte
Bem, qual é o tamanho do seu PIC em termos de memória?
O malloc é uma maneira muito ineficiente de alocar memória. O problema é que a memória pode se fragmentar com libertações frequentes e mallocs e com apenas alguns kilobytes de memória, as falhas de alocação são muito comuns. É bem provável que, se você estiver usando um chip menor ou um PIC18 anterior, não haja suporte para malloc, pois o Microchip o considerou muito difícil de implementar (ou talvez até impossível em alguns casos) ou não foi usado o suficiente para ser utilizado. Vale a pena. Sem mencionar isso, mas também é bastante lento, você está olhando para 1 ciclo para usar um buffer estático já disponível e de 100 a 1.000 para fazer um malloc.
Se você deseja alocar estaticamente, crie coisas como um buffer para as funções do sprintf (se houver, em torno de 128 bytes), um buffer para o cartão SD (se houver) e assim por diante, até remover a necessidade de malloc. Idealmente, você o usa apenas onde é absolutamente necessário e não pode se safar da alocação estática, mas essas situações geralmente são raras e talvez um sinal de que você deva observar microcontroladores maiores / mais poderosos.
E se você estiver desenvolvendo / portando um "sistema operacional" no PIC18 e se ele suportar microcontroladores, provavelmente terá suporte para alocação estática. Por exemplo, o SQLite3 suporta alocação estática - você aloca uma grande matriz de buffer e a utiliza sempre que possível, mesmo que não seja para microcontroladores. Caso contrário, você tem certeza de que foi projetado para um pequeno PIC18?
fonte
Se você está considerando
malloc()
efree()
para o seu software incorporado, sugiro que você dê uma olhada no uC / OS-IIOSMemGet()
e emOSMemPut()
. Emboramalloc()
você aloque um bloco de memória arbitrário,OSMem*()
ofereça um bloco de tamanho fixo de um pool pré-alocado. Acho essa abordagem um bom equilíbrio entre a flexibilidademalloc()
e a robustez da alocação estática.fonte
AFAIK, para fazer isso corretamente, você realmente precisa estar olhando para um dispositivo com algum tipo de unidade de gerenciamento de memória (MMU). Embora existam mecanismos de alocação dinâmica para a série PIC18, eles não serão realmente sólidos - e falando como alguém que trabalhou em firmware que ultrapassa os limites da série PIC18, posso dizer que você não vai conseguir um aplicativo considerável lá se você gastar toda a sobrecarga em um gerenciador de memória.
Melhor solução: tente entender o que está fazendo e por que ele precisa de alocação dinâmica. Veja se você não pode fatorar novamente para trabalhar com alocação estática. (Pode ser que isso simplesmente não seja possível - se a biblioteca / aplicativo for projetado para fazer algo que seja escalável livremente ou que não tenha limites da quantidade de entrada que pode aceitar.) Mas, às vezes, se você realmente pensa sobre o que você está tentando fazer, você pode achar que é possível (e possivelmente até fácil) usar a alocação estática.
fonte