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)