dyn. memory alloc
This commit is contained in:
parent
f2e8d126e5
commit
d74bef5e61
@ -1,9 +1,12 @@
|
|||||||
#ifndef STATIC_ALLOC_H_
|
#ifndef MEMALLOC_H_
|
||||||
#define STATIC_ALLOC_H_
|
#define MEMALLOC_H_
|
||||||
|
|
||||||
void * static_alloc(uint32_t size);
|
|
||||||
uint32_t static_alloc_used(void);
|
uint32_t static_alloc_used(void);
|
||||||
|
|
||||||
uint32_t next_powerof2(uint32_t value);
|
uint32_t next_powerof2(uint32_t value);
|
||||||
|
|
||||||
#endif /*STATIC_ALLOC_H_*/
|
void * static_alloc(uint32_t size);
|
||||||
|
|
||||||
|
void * alloc(uint32_t size);
|
||||||
|
void free(void *p);
|
||||||
|
|
||||||
|
#endif /*MEMALLOC_H_*/
|
2
main.c
2
main.c
@ -26,7 +26,7 @@
|
|||||||
#include "at91_twi.h"
|
#include "at91_twi.h"
|
||||||
|
|
||||||
#include "at91_tc1.h"
|
#include "at91_tc1.h"
|
||||||
#include "static_alloc.h"
|
#include "memalloc.h"
|
||||||
|
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -22,14 +22,13 @@
|
|||||||
#include "AT91SAM7S256.h"
|
#include "AT91SAM7S256.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "at91_pitc.h"
|
#include "at91_pitc.h"
|
||||||
#include "static_alloc.h"
|
|
||||||
|
|
||||||
static uint16_t adc_result[4];
|
static uint16_t adc_result[4];
|
||||||
|
|
||||||
static void at91_adc_isr(void)
|
static void at91_adc_isr(void)
|
||||||
{
|
{
|
||||||
AT91S_PDC *pdc = AT91C_BASE_PDC_ADC;
|
AT91S_PDC *pdc = AT91C_BASE_PDC_ADC;
|
||||||
pdc->PDC_RPR = (uint32_t) &adc_result;
|
pdc->PDC_RPR = (uint32_t) &adc_result;
|
||||||
pdc->PDC_RCR = ARRAY_SIZE(adc_result);
|
pdc->PDC_RCR = ARRAY_SIZE(adc_result);
|
||||||
pdc->PDC_PTCR = AT91C_PDC_RXTEN;
|
pdc->PDC_PTCR = AT91C_PDC_RXTEN;
|
||||||
|
|
||||||
@ -53,21 +52,21 @@ void at91_adc_test_init(void)
|
|||||||
/* ADC Software reset */
|
/* ADC Software reset */
|
||||||
AT91S_ADC *adc = AT91C_BASE_ADC;
|
AT91S_ADC *adc = AT91C_BASE_ADC;
|
||||||
adc->ADC_CR = AT91C_ADC_SWRST;
|
adc->ADC_CR = AT91C_ADC_SWRST;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC config: 10bit, no sleep
|
* ADC config: 10bit, no sleep
|
||||||
* 4.8MHz (48MHz / ((4 +1) * 2) = 4.8MHz)
|
* 4.8MHz (48MHz / ((4 +1) * 2) = 4.8MHz)
|
||||||
* 96 cycles Startup ((11 +1) * 8 / 4.8MHz = 20us)
|
* 96 cycles Startup ((11 +1) * 8 / 4.8MHz = 20us)
|
||||||
* 3 cycles SH ((2 +1) / 4.8MHz = 625ns)
|
* 3 cycles SH ((2 +1) / 4.8MHz = 625ns)
|
||||||
* Conversion time per channel @5MHz ~2us
|
* Conversion time per channel @5MHz ~2us
|
||||||
*/
|
*/
|
||||||
adc->ADC_MR = AT91C_ADC_TRGEN_DIS |
|
adc->ADC_MR = AT91C_ADC_TRGEN_DIS |
|
||||||
AT91C_ADC_LOWRES_10_BIT |
|
AT91C_ADC_LOWRES_10_BIT |
|
||||||
AT91C_ADC_SLEEP_NORMAL_MODE |
|
AT91C_ADC_SLEEP_NORMAL_MODE |
|
||||||
(AT91C_ADC_PRESCAL & (4 << 8)) |
|
(AT91C_ADC_PRESCAL & (4 << 8)) |
|
||||||
(AT91C_ADC_STARTUP & (11 << 16)) |
|
(AT91C_ADC_STARTUP & (11 << 16)) |
|
||||||
(AT91C_ADC_SHTIM & (2 << 24));
|
(AT91C_ADC_SHTIM & (2 << 24));
|
||||||
|
|
||||||
/* setup PDC */
|
/* setup PDC */
|
||||||
AT91S_PDC *pdc = AT91C_BASE_PDC_ADC;
|
AT91S_PDC *pdc = AT91C_BASE_PDC_ADC;
|
||||||
pdc->PDC_RPR = (uint32_t) &adc_result;
|
pdc->PDC_RPR = (uint32_t) &adc_result;
|
||||||
@ -83,7 +82,7 @@ void at91_adc_test_init(void)
|
|||||||
aic->AIC_SMR[AT91C_ID_ADC] = IRQPRIO_ADC | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL;
|
aic->AIC_SMR[AT91C_ID_ADC] = IRQPRIO_ADC | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL;
|
||||||
aic->AIC_SVR[AT91C_ID_ADC] = (uint32_t)at91_adc_isr;
|
aic->AIC_SVR[AT91C_ID_ADC] = (uint32_t)at91_adc_isr;
|
||||||
aic->AIC_IECR = (1<<AT91C_ID_ADC);
|
aic->AIC_IECR = (1<<AT91C_ID_ADC);
|
||||||
|
|
||||||
/* schedule trigger */
|
/* schedule trigger */
|
||||||
struct pitc_timer *adc_timer = alloc_pitc_timer(100, &adc_trigger, NULL);
|
struct pitc_timer *adc_timer = alloc_pitc_timer(100, &adc_trigger, NULL);
|
||||||
pitc_schedule_timer(adc_timer);
|
pitc_schedule_timer(adc_timer);
|
||||||
@ -94,6 +93,6 @@ void at91_adc_printresults(void)
|
|||||||
uint8_t i;
|
uint8_t i;
|
||||||
for (i = 0; i < ARRAY_SIZE(adc_result); i++)
|
for (i = 0; i < ARRAY_SIZE(adc_result); i++)
|
||||||
printf("%x:0x%03X ", i, adc_result[i]);
|
printf("%x:0x%03X ", i, adc_result[i]);
|
||||||
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "at91_pitc.h"
|
#include "at91_pitc.h"
|
||||||
#include "at91_sysc.h"
|
#include "at91_sysc.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "static_alloc.h"
|
#include "memalloc.h"
|
||||||
|
|
||||||
/* PIV is 20bit -> min. 3Hz @48MHz MCK */
|
/* PIV is 20bit -> min. 3Hz @48MHz MCK */
|
||||||
#define HZ_TO_PIV(HZ) (MCK / (16 * HZ))
|
#define HZ_TO_PIV(HZ) (MCK / (16 * HZ))
|
||||||
@ -35,7 +35,7 @@ struct pitc_timer * alloc_pitc_timer(uint32_t interval, uint32_t (*func)(struct
|
|||||||
timer->func = func;
|
timer->func = func;
|
||||||
timer->privdata = privdata;
|
timer->privdata = privdata;
|
||||||
|
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pitc_schedule_timer(struct pitc_timer *timer)
|
void pitc_schedule_timer(struct pitc_timer *timer)
|
||||||
@ -54,7 +54,7 @@ static void pitc_isr(uint32_t status)
|
|||||||
{
|
{
|
||||||
/* get Ticks and clear interrupt */
|
/* get Ticks and clear interrupt */
|
||||||
pitc_ticks += (*AT91C_PITC_PIVR & AT91C_PITC_PICNT) >> 20;
|
pitc_ticks += (*AT91C_PITC_PIVR & AT91C_PITC_PICNT) >> 20;
|
||||||
|
|
||||||
struct pitc_timer *search, *tmp;
|
struct pitc_timer *search, *tmp;
|
||||||
list_for_each_entry_safe(search, tmp, &timer_list, list) {
|
list_for_each_entry_safe(search, tmp, &timer_list, list) {
|
||||||
/* if this entry not scheduled yet, abort search */
|
/* if this entry not scheduled yet, abort search */
|
||||||
@ -84,7 +84,7 @@ void at91_pitc_init(void)
|
|||||||
{
|
{
|
||||||
sysc_register_isr(AT91_SYSIRQ_PIT, &pitc_isr);
|
sysc_register_isr(AT91_SYSIRQ_PIT, &pitc_isr);
|
||||||
|
|
||||||
*AT91C_PITC_PIMR = (AT91C_PITC_PIV & HZ_TO_PIV(100)) |
|
*AT91C_PITC_PIMR = (AT91C_PITC_PIV & HZ_TO_PIV(100)) |
|
||||||
AT91C_PITC_PITEN |
|
AT91C_PITC_PITEN |
|
||||||
AT91C_PITC_PITIEN;
|
AT91C_PITC_PITIEN;
|
||||||
}
|
}
|
||||||
|
48
src/fifo.c
48
src/fifo.c
@ -19,23 +19,23 @@
|
|||||||
#include "AT91SAM7S256.h"
|
#include "AT91SAM7S256.h"
|
||||||
#include "atomic.h"
|
#include "atomic.h"
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
#include "static_alloc.h"
|
#include "memalloc.h"
|
||||||
|
|
||||||
#define FIFO_MASK(x) ((x)->size -1)
|
#define FIFO_MASK(x) ((x)->size -1)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get used bytes (under lock)
|
* get used bytes (under lock)
|
||||||
* all other operations don't need locks:
|
* all other operations don't need locks:
|
||||||
* - only fifo_put/fifo_rxpdc are allowed to increment fifo->in
|
* - only fifo_put/fifo_rxpdc are allowed to increment fifo->in
|
||||||
* - only fifo_get/fifo_txpdc are allowed to increment fifo->out
|
* - only fifo_get/fifo_txpdc are allowed to increment fifo->out
|
||||||
* a integer overflow (4gb) of fifo->in / fifo->out could cause trouble
|
* a integer overflow (4gb) of fifo->in / fifo->out could cause trouble
|
||||||
*/
|
*/
|
||||||
static uint32_t fifo_used(struct fifo *fifo)
|
static uint32_t fifo_used(struct fifo *fifo)
|
||||||
{
|
{
|
||||||
disable_irqs();
|
disable_irqs();
|
||||||
uint32_t used = fifo->in - fifo->out;
|
uint32_t used = fifo->in - fifo->out;
|
||||||
restore_irqs();
|
restore_irqs();
|
||||||
return used;
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -48,12 +48,12 @@ uint32_t fifo_put(struct fifo *fifo, const char *buf, uint32_t len)
|
|||||||
if (len > left)
|
if (len > left)
|
||||||
len = left;
|
len = left;
|
||||||
|
|
||||||
uint32_t count = len;
|
uint32_t count = len;
|
||||||
while (count--)
|
while (count--)
|
||||||
fifo->buf[fifo->in++ & FIFO_MASK(fifo)] = *buf++;
|
fifo->buf[fifo->in++ & FIFO_MASK(fifo)] = *buf++;
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get data from fifo
|
* get data from fifo
|
||||||
@ -64,12 +64,12 @@ uint32_t fifo_get(struct fifo *fifo, char *buf, uint32_t len)
|
|||||||
uint32_t used = fifo_used(fifo);
|
uint32_t used = fifo_used(fifo);
|
||||||
if (len > used)
|
if (len > used)
|
||||||
len = used;
|
len = used;
|
||||||
|
|
||||||
uint32_t count = len;
|
uint32_t count = len;
|
||||||
while (count--)
|
while (count--)
|
||||||
*buf++ = fifo->buf[fifo->out++ & FIFO_MASK(fifo)];
|
*buf++ = fifo->buf[fifo->out++ & FIFO_MASK(fifo)];
|
||||||
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -79,16 +79,16 @@ uint32_t fifo_rxpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize)
|
|||||||
{
|
{
|
||||||
/* account previous PDC transfer */
|
/* account previous PDC transfer */
|
||||||
fifo->in += fifo->pdc_rx;
|
fifo->in += fifo->pdc_rx;
|
||||||
|
|
||||||
uint32_t free = fifo->size - fifo_used(fifo);
|
uint32_t left = fifo->size - fifo_used(fifo);
|
||||||
if (free) {
|
if (left) {
|
||||||
/* calc pointer for next transfer */
|
/* calc pointer for next transfer */
|
||||||
uint32_t first_idx = (fifo->in & FIFO_MASK(fifo));
|
uint32_t first_idx = (fifo->in & FIFO_MASK(fifo));
|
||||||
pdc->PDC_RPR = (uint32_t)(fifo->buf + first_idx);
|
pdc->PDC_RPR = (uint32_t)(fifo->buf + first_idx);
|
||||||
|
|
||||||
/* check for buffer end -> split transfer */
|
/* check for buffer end -> split transfer */
|
||||||
if (first_idx + free <= (fifo->size -1)) {
|
if (first_idx + left <= (fifo->size -1)) {
|
||||||
fifo->pdc_rx = free;
|
fifo->pdc_rx = left;
|
||||||
} else {
|
} else {
|
||||||
fifo->pdc_rx = fifo->size - first_idx;
|
fifo->pdc_rx = fifo->size - first_idx;
|
||||||
}
|
}
|
||||||
@ -97,32 +97,32 @@ uint32_t fifo_rxpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize)
|
|||||||
if (maxsize && fifo->pdc_rx > maxsize)
|
if (maxsize && fifo->pdc_rx > maxsize)
|
||||||
fifo->pdc_rx = maxsize;
|
fifo->pdc_rx = maxsize;
|
||||||
|
|
||||||
/* start transfer */
|
/* start transfer */
|
||||||
pdc->PDC_RCR = fifo->pdc_rx;
|
pdc->PDC_RCR = fifo->pdc_rx;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* no data in buffer */
|
/* no data in buffer */
|
||||||
fifo->pdc_rx = 0;
|
fifo->pdc_rx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fifo->pdc_rx;
|
return fifo->pdc_rx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* transmit fifo via PDC
|
* transmit fifo via PDC
|
||||||
* returns 0 if no transfer was started
|
* returns 0 if no transfer was started
|
||||||
*/
|
*/
|
||||||
uint32_t fifo_txpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize)
|
uint32_t fifo_txpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize)
|
||||||
{
|
{
|
||||||
/* account previous PDC transfer */
|
/* account previous PDC transfer */
|
||||||
fifo->out += fifo->pdc_tx;
|
fifo->out += fifo->pdc_tx;
|
||||||
|
|
||||||
uint32_t used = fifo_used(fifo);
|
uint32_t used = fifo_used(fifo);
|
||||||
if (used) {
|
if (used) {
|
||||||
/* calc pointer for next transfer */
|
/* calc pointer for next transfer */
|
||||||
uint32_t first_idx = (fifo->out & FIFO_MASK(fifo));
|
uint32_t first_idx = (fifo->out & FIFO_MASK(fifo));
|
||||||
pdc->PDC_TPR = (uint32_t)(fifo->buf + first_idx);
|
pdc->PDC_TPR = (uint32_t)(fifo->buf + first_idx);
|
||||||
|
|
||||||
/* check for buffer end -> split transfer */
|
/* check for buffer end -> split transfer */
|
||||||
if (first_idx + used <= (fifo->size -1)) {
|
if (first_idx + used <= (fifo->size -1)) {
|
||||||
fifo->pdc_tx = used;
|
fifo->pdc_tx = used;
|
||||||
@ -134,14 +134,14 @@ uint32_t fifo_txpdc(struct fifo *fifo, AT91S_PDC *pdc, uint16_t maxsize)
|
|||||||
if (maxsize && fifo->pdc_tx > maxsize)
|
if (maxsize && fifo->pdc_tx > maxsize)
|
||||||
fifo->pdc_tx = maxsize;
|
fifo->pdc_tx = maxsize;
|
||||||
|
|
||||||
/* start transfer */
|
/* start transfer */
|
||||||
pdc->PDC_TCR = fifo->pdc_tx;
|
pdc->PDC_TCR = fifo->pdc_tx;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* no data in buffer */
|
/* no data in buffer */
|
||||||
fifo->pdc_tx = 0;
|
fifo->pdc_tx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return fifo->pdc_tx;
|
return fifo->pdc_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "AT91SAM7S256.h"
|
#include "AT91SAM7S256.h"
|
||||||
#include "board.h"
|
#include "board.h"
|
||||||
#include "static_alloc.h"
|
#include "memalloc.h"
|
||||||
|
|
||||||
|
// TODO: make generic version and find better place
|
||||||
#define ALIGN(x) (((x) +3) & ~3)
|
#define ALIGN(x) (((x) +3) & ~3)
|
||||||
|
|
||||||
/* extern symbols, defined in ldscript */
|
/* extern symbols, defined in ldscript */
|
||||||
@ -91,7 +92,7 @@ static struct memchunk * alloc_add(uint32_t size)
|
|||||||
struct memchunk *newblock = static_alloc(size);
|
struct memchunk *newblock = static_alloc(size);
|
||||||
|
|
||||||
/* struct at end of memory block */
|
/* struct at end of memory block */
|
||||||
struct memchunk *endblock = (void *)newblock + size - sizeof(struct memchunk);
|
struct memchunk *endblock = (void *)((uint32_t)newblock + size - sizeof(struct memchunk));
|
||||||
|
|
||||||
/* link between them */
|
/* link between them */
|
||||||
newblock->next = endblock;
|
newblock->next = endblock;
|
||||||
@ -161,7 +162,7 @@ try_next:
|
|||||||
|
|
||||||
/* if we split the chunk, the remaining piece must be large enough */
|
/* if we split the chunk, the remaining piece must be large enough */
|
||||||
if (((uint32_t)GET_NEXT(found) - (uint32_t)found) > (size + 2 * sizeof(struct memchunk))) {
|
if (((uint32_t)GET_NEXT(found) - (uint32_t)found) > (size + 2 * sizeof(struct memchunk))) {
|
||||||
struct memchunk *end = (void *)found + size;
|
struct memchunk *end = (void *)((uint32_t)found + size);
|
||||||
end->next = SET_FLAGS(GET_NEXT(found), 0);
|
end->next = SET_FLAGS(GET_NEXT(found), 0);
|
||||||
found->next = SET_FLAGS(end, FLAG_CHUNKINUSE);
|
found->next = SET_FLAGS(end, FLAG_CHUNKINUSE);
|
||||||
|
|
@ -21,6 +21,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "board.h" // ARRAY_SIZE()
|
#include "board.h" // ARRAY_SIZE()
|
||||||
#include "telemetrie.h"
|
#include "telemetrie.h"
|
||||||
|
#include "memalloc.h"
|
||||||
|
|
||||||
/* extern symbols, defined in ldscript */
|
/* extern symbols, defined in ldscript */
|
||||||
extern struct tdc_value _tdc_value_table;
|
extern struct tdc_value _tdc_value_table;
|
||||||
@ -60,16 +61,6 @@ int32_t tdc_transmit(uint32_t addr, const uint8_t *data, uint32_t size)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void * alloc(uint32_t size)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free(void *p)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
void *blub = NULL;
|
void *blub = NULL;
|
||||||
func(&blub);
|
func(&blub);
|
||||||
|
Loading…
Reference in New Issue
Block a user