Often programmers like to convert pointer to one type to pointer to another. It's a usually (and INCORRECT!) "method" to pick-up some integer from byte array. From C standard we know that pointer to one type IS NOT EQUAL to pointer to another. But programmers ignores this fact on x86 :)
They will not ignore this on AVR/AVR32 architecture :)
воскресенье, 30 сентября 2012 г.
среда, 19 сентября 2012 г.
Simplest (and fastest) allocator in C
I need to allocate strings (in UI) with the same length in my MCU program, so I can use: 1) static local buffer in functions or use 2) common buffer.
1) cons: implicit memory "eating" 2) cons: funcs are not reenterable.
I use next simple (simplest!) and fast allocator - it allocate strings with the same length. It has only to necessary functions in it's API: allocate and free. Here is the code:
Used bset.h is modified BSD select.h with API (macroses): BSET_SET(), BSET_CLR(), BSET_TGL(), BSET_ISSET(), BSET_FOREACH(), BSET_FORSET(), BSET_FORCLR(), BSET_FOREACHBYTE(), BSET_FOREACHMASK(), BSET_BYTE(), BSET_MASK(), BSET_COPY(), BSET_ZERO().
Most interesting are BSET_CLR() - clear item from bit's set, BSET_SET() - set item in bit's set, BSET_FORCLR() - iterate over cleared items in bit's set - looking for free strings in pool.
Little example:
#include <stdint.h>
#include "bset.h"
/** string count */
#define GUI_TMPSTR_N 3
/** max string length */
#define GUI_TMPSTR_MAXLEN 64
/// block of temporary strings with the same length
typedef struct gui_tmpstr_buf_t {
bset_t pool;
char buf[GUI_TMPSTR_N][GUI_TMPSTR_MAXLEN];
} gui_tmpstr_buf_t;
#define GUI_TMPSTR_BUF_INITIALIZER() { \
.pool = BSET_INITIALIZER(), \
.buf = {0} \
}
// global blocks for allocation
gui_tmpstr_buf_t _tmpstrbuf = GUI_TMPSTR_BUF_INITIALIZER();
/// allocate temporary string
char*
gui_tmpstr_alloc(void) {
int i;
BSET_FORCLR(i, &_tmpstrbuf.pool) {
if (i >= GUI_TMPSTR_N)
break;
BSET_SET(i, &_tmpstrbuf.pool);
return (_tmpstrbuf.buf[i]);
}
return (NULL);
}
/// free allocated tmp. string
void
gui_tmpstr_free(char* ptr) {
intptr_t i = ((intptr_t)ptr - (intptr_t)_tmpstrbuf.buf);
if (i <= 0) {
// ptr is BEFORE base addr (buf)
return;
}
if (i % GUI_TMPSTR_MAXLEN) {
// ptr is not align on GUI_TMPSTR_MAXLEN
return;
}
i /= GUI_TMPSTR_MAXLEN;
if (BSET_ISSET(i, &_tmpstrbuf.pool)) {
// free in pool
BSET_CLR(i, &_tmpstrbuf.pool);
}
}
GUI_TMPSTR_MAXLEN defines length of each string, GUI_TMPSTR_N defines available strings number. I used such string in UI (cutting strings, modifing, so on...).
Used bset.h is modified BSD select.h with API (macroses): BSET_SET(), BSET_CLR(), BSET_TGL(), BSET_ISSET(), BSET_FOREACH(), BSET_FORSET(), BSET_FORCLR(), BSET_FOREACHBYTE(), BSET_FOREACHMASK(), BSET_BYTE(), BSET_MASK(), BSET_COPY(), BSET_ZERO().
Most interesting are BSET_CLR() - clear item from bit's set, BSET_SET() - set item in bit's set, BSET_FORCLR() - iterate over cleared items in bit's set - looking for free strings in pool.
Little example:
char* ptr = gui_tmpstr_alloc();
if (ptr) {
// USAGE of ptr
...
// free:
gui_tmpstr_free(ptr);
}
понедельник, 17 сентября 2012 г.
ASF: simple utility for font editing
Used fonts in Atmel Software Framework are simple: each glyph is described with array of bytes - each set bit is pixel, no bit - no pixel :)
Next is the very-very simple Tcl utility to convert glyph bytes into console image of symbol and vice-verse.
Next is the very-very simple Tcl utility to convert glyph bytes into console image of symbol and vice-verse.
# parsing and loading font
#------------------------------------------------------------------------------
proc parsesymb str {
# Parse one symbol in notation like:
# "0x06,0x08,0x08,0x00,0x00,0x00,0x00,0x00"
set bytes [regexp -all -inline {0[xX][0-9a-fA-F]{2}} $str]
return $bytes
}
proc putsymbline byte {
# put on screen one line of a symbol
set mask 0b10000000
for {set i 0} {$i<8 data-blogger-escaped-bit="bit" data-blogger-escaped-byte="byte" data-blogger-escaped-expr="expr" data-blogger-escaped-i="i" data-blogger-escaped-incr="incr" data-blogger-escaped-mask="mask" data-blogger-escaped-set="set">>1}]
if $bit {
puts -nonewline "#"
} else {
puts -nonewline " "
}
}
}
proc putsymb symb_bytes {
# put on screen all symbol (all it's lines)
puts "+--------+"
foreach sb $symb_bytes {
puts -nonewline "|"
putsymbline $sb
puts "|"
}
puts "+--------+"
}
# Compile glyphs to font in C format
#-------------------------------------------------------------------------------
proc compsymbline line {
# Compile line like "# # # # " to 0xAA
set bits [string map { " " 0 # 1} $line]
return [format 0x%02X "0b$bits"]
}
proc compsymb symb_lines {
# Compile lines of symbol (what out 'putsymb')
set read 0
set res {}
foreach line $symb_lines {
if {0 == $read} {
if {$line eq "+--------+"} {
set read 1
}
} else {
if {$line eq "+--------+"} {
break
} else {
set line [string trim $line "|"]
lappend res [compsymbline $line]
}
}
}
return [join $res ","]
}
proc getlines {} {
set lines {}
while {[gets stdin line] >= 0} {
lappend lines $line
}
return $lines
}
proc main args {
global argc argv
if {$argc} {
set argv0 [lindex $argv 0]
if {$argv0 eq "comp"} {
set lines [getlines]
puts [compsymb $lines]
return
} elseif {$argv0 eq "put"} {
set line [gets stdin]
puts [putsymb [parsesymb $line]]
return
}
}
puts {\
Syntax on Linux:
1. cat file|PRG comp
2. cat file|PRG put
Syntax on Windows:
1. more file|PRG comp
2. more file|PRG put
This means:
1. Compile glyph image into C hex array
2. Put glyph hex array on the screen as glyph image
Glyph images and its' hex arrays are inverse}
}
main
}
Example of usage:
$echo 0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00|tclkitsh font.tcl put +--------+ | # | | #### | |# # | | ### | | # # | |#### | | # | | | +--------+ $This is the "$" symbol. It's bytes I get from et024006dhu.c (see const unsigned char FONT6x8[97][8]) From another hand, you can save this glyph (with ASCII-box!) in some file and then call:
$cat somefile.txt|tclkitsh font.tcl comp 0x20,0x78,0xA0,0x70,0x28,0xF0,0x20,0x00 $to get bytes of the glyph.
Подписаться на:
Комментарии (Atom)