C - offset položky ve struktuře

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Zpráva
Autor
Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#31 Příspěvek od lesana87 »

Tak jsem se inspirovala dokumentem od Zmije a stvořila jsem tohle:
Cčkový soubor struct.c:

Kód: Vybrat vše

#include <linux/sched.h>

#define offsetof(s, m) __builtin_offsetof (s, m)

typedef struct task_struct Ttask_struct;

int state_off = offsetof(Ttask_struct, state);
int mmu_pid_off = offsetof(Ttask_struct, mmu_pid);
int counter_off = offsetof(Ttask_struct, counter);
int priority_off = offsetof(Ttask_struct, priority);
int tstack_off = offsetof(Ttask_struct, tstack);
int timeout_off = offsetof(Ttask_struct, timeout);
který se zkompiluje sdcc.exe -mz80 -Iinclude -S struct.c do struct.asm:

Kód: Vybrat vše

;--------------------------------------------------------
; File Created by SDCC : free open source ANSI-C Compiler
; Version 3.6.0 #9615 (MINGW32)
;--------------------------------------------------------
	.module struct
	.optsdcc -mz80
	
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
	.globl _timeout_off
	.globl _tstack_off
	.globl _priority_off
	.globl _counter_off
	.globl _mmu_pid_off
	.globl _state_off
;--------------------------------------------------------
; special function registers
;--------------------------------------------------------
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
	.area _DATA
;--------------------------------------------------------
; ram data
;--------------------------------------------------------
	.area _INITIALIZED
_state_off::
	.ds 2
_mmu_pid_off::
	.ds 2
_counter_off::
	.ds 2
_priority_off::
	.ds 2
_tstack_off::
	.ds 2
_timeout_off::
	.ds 2
;--------------------------------------------------------
; absolute external ram data
;--------------------------------------------------------
	.area _DABS (ABS)
;--------------------------------------------------------
; global & static initialisations
;--------------------------------------------------------
	.area _HOME
	.area _GSINIT
	.area _GSFINAL
	.area _GSINIT
;--------------------------------------------------------
; Home
;--------------------------------------------------------
	.area _HOME
	.area _HOME
;--------------------------------------------------------
; code
;--------------------------------------------------------
	.area _CODE
	.area _CODE
	.area _INITIALIZER
__xinit__state_off:
	.dw #0x0000
__xinit__mmu_pid_off:
	.dw #0x0001
__xinit__counter_off:
	.dw #0x0002
__xinit__priority_off:
	.dw #0x0003
__xinit__tstack_off:
	.dw #0x0004
__xinit__timeout_off:
	.dw #0x0048
	.area _CABS (ABS)
a ten se následně přes grep -A1 __xinit__ struct.asm | tr --delete '\n' | sed -e 's/__xinit__/\n/g' -e 's/:/ = /g' -e 's/\t.dw #//g' > include/struct.inc profiltruje do struct.inc:

Kód: Vybrat vše

state_off = 0x0000
mmu_pid_off = 0x0001
counter_off = 0x0002
priority_off = 0x0003
tstack_off = 0x0004
timeout_off = 0x0048
a offsety jsou na světě, stačí je includnout do toho assembleru a je hotovo. :)
Díky Zmije za inspiraci. :)

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#32 Příspěvek od lesana87 »

Tak se mi konečně podařilo dopsat poslední důležité volání jádra sys_execve a už můžu i spustit nový program. Ještě včera jsem mohla jen forkovat. :)
Pro začátek obligátní Hello world, init a shell ještě nemám, ale funguje to, *nix na Z80. :)
Ale ten SDCC je hrůza, někdo mi zase může vykládat, jak je C efektivní, skoro jako assembler. Možná na ARMu, ale ne na Z80. Se zavřenýma očima bych to v assembleru napsala poloviční, s otevřenýma třetinový. Sotva se mi to do těch 56KB vejde, zbývá jen asi 400B místa. :?
Budu muset něco do assembleru přepsat, ještě mi tam pár věcí chybí.

Kód: Vybrat vše

*AZ80*
Memory test: 256KB OK

Loading OS..........

Annix Z80 V0.01_2016
Kernel code/data end: 0x9905/0xDE14
rs_init: port 0D8
0 virtual consoles
1 serial consoles
Buffers: 16
ROOTinode: dev=(1,0), mode=040111, cnt=3, lnks=4
File: 00F3, hello.a
243 bytes written.

ls:
  1: .
  1: ..
 64: dev
 63: bin
 60: hello.a

Task-info:
0: s=1, sig=0, pid=0, ppid=0, ut=    9, st=  14, ks: 166/1961
Forking task 1...
Task 1

Task-info:
0: s=1, sig=0, pid=0, ppid=0, ut=   11, st=  14, ks: 166/1961
1: s=1, sig=0, pid=1, ppid=0, ut=    0, st=   0, ks: 108/1961
Test /dev/cua0.
Press enter to continue...

Exec: hello.a
235 bytes of image loaded.
Hello world! :o)
Press enter to continue...

End.

Task-info:
0: s=1, sig=8, pid=0, ppid=0, ut=  378, st=  14, ks: 166/1961
1: s=4, sig=0, pid=1, ppid=0, ut=    1, st=   7, ks: 166/1961
Wait: 1
Task-info:
0: s=1, sig=8, pid=0, ppid=0, ut=  778, st=  14, ks: 166/1961

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#33 Příspěvek od lesana87 »

Už mám i malinkej shell, tak už to začíná vypadat unixově. :)

Kód: Vybrat vše

> cd /
> ls
d--x--x--x   6   0   0     128 ./
d--x--x--x   6   0   0     128 ../
drwxr-xr-x   2   0   0      96 dev/
drwxr-xr-x   2   0   0     176 bin/
-rwxrwxrwx   1   0   0    1382 hello.a
drwxr-xr-x   2   0   0      32 etc/
drwxr-xr-x   2   0   0      32 usr/
> cd bin
> ls
drwxr-xr-x   2   0   0     176 ./
d--x--x--x   6   0   0     128 ../
-rwxrwxrwx   1   0   0    2710 ls
-rwxrwxrwx   1   0   0    3281 sh
-rwxrwxrwx   1   0   0    1413 rm
-rwxrwxrwx   1   0   0     157 sync
-rwxrwxrwx   1   0   0      60 nop
-rwxrwxrwx   1   0   0    1630 cat
-rwxrwxrwx   1   0   0    1353 echo
-rwxrwxrwx   1   0   0    1464 mkdir
-rwxrwxrwx   1   0   0    2400 mknod
> cd dev
sh: No such file or directory
> cd /dev
> ls
drwxr-xr-x   2   0   0      96 ./
d--x--x--x   6   0   0     128 ../
crw-rw-rw-   1   0   0    4, 0 tty0
crw-rw-rw-   1   0   0    4, 4 cua0
brw-rw-rw-   1   0   0    1, 0 sra
brw-rw-rw-   1   0   0    1, 1 srb
> echo ahoj lidi :)
ahoj lidi :)
>

Wolfik
Příspěvky: 1076
Registrován: 28 črc 2009, 02:00

#34 Příspěvek od Wolfik »

holka...ty sis nehrála s panenkama, když si byla malá, viď? :D

upřímně...respekt :!:

Uživatelský avatar
Zmije
Příspěvky: 1513
Registrován: 30 čer 2005, 02:00
Bydliště: Pardubický kraj

#35 Příspěvek od Zmije »

Gratuluji !

Budou k dispozici zdrojáky (github, bitbucket...) ?

Ještě jsem se chtěl zeptat, jestli nechceš zkusit některý port GCC, možna by pomohly optimalizace na velikost -os.

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#36 Příspěvek od lesana87 »

Do světa se s tím nějak nechystám, kvalitou to na rozdávání moc není, stále nacházím chyby a navíc k čemu by to někomu bylo, když je to šité na hardware, který mám jen já? :oops:
Portem GCC myslíš co, ono existuje GCC pro Z80?

P.S.: Panenky jsou nuda.

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#37 Příspěvek od lesana87 »

Trošku jsem s tím *nixem pokročila. :) Dodělala jsem do kernelu pár driverů. Taky funkce pro job control, ale ještě musím dodělat job control do shellu. Execve jsem rozšířila o možnost spouštět interpretované skripty (viz ukázka skriptu ah ve výpisu). Aby na to bylo místo, musela jsem už docela velkou část kernelu přepsat do assembleru. Libc se taky rozrostla, naposledy o funkce pro konverzi času. Přibyla spousta utilit, největší fsck má skoro 10KB. Program count, spuštěný na pozadí v ukázce, jen počítá ovečky, slouží k testování multitasku a zatěžování procesoru. :) Dokonce mám už i celoobrazovkový editor ue. Akorát jsem musela ten původní z Public domain řádně překopat, aby byl použitelný na sériovém terminálu a nepřekresloval při každé klávese celou obrazovku. No, už se to začíná zaplňovat, za chvíli mi bude 128KB disk malý. :D

Kód: Vybrat vše

*AZ80*
Memory test: 128KB OK

Loading OS..........

Annix ver. 0.3.1 [#46 2017-01-15] on AZ80
Kernel code/data end: 0x9BB5/0xDB2D
rs_init: port 0D8
0 virtual consoles
1 serial consoles
Buffers: 16
ROOT (1,0)
Memory: 128KB total, 72KB free
fsck 0.1a (23-Dec-2016)
/dev/sra: 49/96 inodes free, 113/248 blocks free
/dev/epr on /mnt

Welcome to Annix 0.3.1

Simple shell v0.4a
> ps -l
Task-info:
 #  st  sig cnt pri uid pid ppid pgrp ses tty  wch    utime    stime  name
 0:  S 0000   0  15   0   0   0    0    0 255 0000        1     2721 _idle_
 1:  S 0000  25  15   0   1   0    0    0 255 0000        0        5 _init_
 2:  S 0000   5  15   0  10   1   10   10   4 0000        0       10 sh
 3:  S 0000  21  15   0   6   1    0    0 255 A606        1        1 update
 4:  R 0000  12  15   0  11  10   10   10   4 0000        2       20 ps
> count &
> ps -l
Task-info:
 #  st  sig cnt pri uid pid ppid pgrp ses tty  wch    utime    stime  name
 0:  S 0000   0  15   0   0   0    0    0 255 0000        4     3044 _idle_
 1:  S 0000  29  15   0   1   0    0    0 255 0000        0        5 _init_
 2:  S 0000  25  15   0  10   1   10   10   4 0000        0       18 sh
 3:  S 0000  29  15   0   6   1    0    0 255 A606        1        1 update
 4:  R 0000   3  15   0  12  10   10   10   4 0000      118        2 count
 5:  R 0000  13  15   0  13  10   10   10   4 0000        1       23 ps
> ls -l /dev
drwxr-xr-x   2   0   0     192 13:54 15-01-2017 ./
drwxr-xr-x   7   0   0     160 19:41 08-01-2017 ../
crw-rw-rw-   1   0   0    4, 4 16:35 29-12-2016 cua0
crw-rw-rw-   1   0   0    5, 0 16:42 29-12-2016 tty
crw-rw-rw-   1   0   0    1, 1 16:43 29-12-2016 mem
crw-rw-rw-   1   0   0    1, 2 16:43 29-12-2016 kmem
crw-rw-rw-   1   0   0    1, 3 16:43 29-12-2016 null
crw-rw-rw-   1   0   0    1, 4 16:43 29-12-2016 port
brw-rw-rw-   1   0   0    1, 0 16:43 29-12-2016 sra
brw-rw-rw-   1   0   0    1, 1 16:43 29-12-2016 srb
brw-rw-rw-   1   0   0    2, 0 16:44 29-12-2016 epr
crw-rw-rw-   1   0   0    1, 5 13:54 15-01-2017 zero
> ls -l /bin
drwxr-xr-x   2   0   0     464 17:12 14-01-2017 ./
drwxr-xr-x   7   0   0     160 19:41 08-01-2017 ../
-rwxrwxrwx   1   0   0    4362 14:36 07-01-2017 sh
-rwxrwxrwx   1   0   0    1346 16:52 29-12-2016 cp
-rwxrwxrwx   1   0   0    9757 16:52 29-12-2016 fsck
-rwxrwxrwx   1   0   0    1887 16:52 29-12-2016 mount
-rwxrwxrwx   1   0   0    2280 16:52 29-12-2016 mkfs
-rwxrwxrwx   1   0   0     146 16:52 29-12-2016 sync
-rwxrwxrwx   1   0   0    3679 20:01 07-01-2017 ls
-rwxrwxrwx   1   0   0     353 16:53 29-12-2016 mkdir
-rwxrwxrwx   1   0   0    1345 16:53 29-12-2016 mknod
-rwxrwxrwx   1   0   0    1151 16:53 29-12-2016 rm
-rwxrwxrwx   1   0   0     587 16:53 29-12-2016 cat
-rwxrwxrwx   1   0   0     333 09:46 15-01-2017 echo
-rwxrwxrwx   1   0   0    1658 16:53 29-12-2016 rdb
-rwxrwxrwx   1   0   0    1817 16:53 29-12-2016 umount
-rwxrwxrwx   1   0   0    1971 16:53 29-12-2016 df
-rwxrwxrwx   1   0   0     294 16:53 29-12-2016 sleep
-rwxrwxrwx   1   0   0     112 16:53 29-12-2016 update
-rwxrwxrwx   1   0   0    2566 18:59 10-01-2017 ps
-rwxrwxrwx   1   0   0    1153 16:53 29-12-2016 rmdir
-rwxrwxrwx   1   0   0    1418 16:53 29-12-2016 kill
-rwxrwxrwx   1   0   0      82 16:53 29-12-2016 count
-rwxrwxrwx   1   0   0    3757 11:45 08-01-2017 ue
-rw-rw-rwx   1   0   0      66 11:55 15-01-2017 ah
-rwxrwxrwx   1   0   0    1305 15:19 01-01-2017 chmod
-rwxrwxrwx   1   0   0    3545 14:36 07-01-2017 date
-rwxrwxrwx   1   0   0    5072 10:11 08-01-2017 dd
-rwxrwxrwx   1   0   0     714 09:30 15-01-2017 uname
> date
Su Jan 15 13:59:16 2017
> uname -a
Annix  0.3.1 #46 2017-01-15 AZ80
>
> cat /bin/ah
#!/bin/sh
echo Ahoj lidi :)
echo Zda se, ze to funguje. :o)
ps -l
> ah
Ahoj lidi :)
Zda se, ze to funguje. :o)
Task-info:
 #  st  sig cnt pri uid pid ppid pgrp ses tty  wch    utime    stime  name
 0:  S 0000   0  15   0   0   0    0    0 255 0000        4     3044 _idle_
 1:  S 0000  29  15   0   1   0    0    0 255 0000        0        5 _init_
 2:  S 0000  27  15   0  10   1   10   10   4 0000        0       48 sh
 3:  S 0000  29  15   0   6   1    0    0 255 A606        1        1 update
 4:  R 0000  15  15   0  12  10   10   10   4 0000     3073        2 count
 5:  S 0000  11  15   0  20  10   10   10   4 0000        0       19 sh
 6:  R 0000  11  15   0  23  20   10   10   4 0000        6       24 ps

> dd if=/dev/zero of=/dev/srb bs=2048 count=64
64+0 records in
64+0 records out
> dd if=/dev/sra of=/dev/srb bs=4k count=32
32+0 records in
32+0 records out
> fsck -v /dev/srb
fsck 0.1a (23-Dec-2016)
/dev/srb: 49/96 inodes free, 113/248 blocks free
 (31 REG, 6 DIR, 7 CHR, 3 BLK, 0 SLNK, 0 FIFO)
> 

Uživatelský avatar
FHonza
Příspěvky: 1443
Registrován: 20 lis 2012, 01:00
Bydliště: Praha

#38 Příspěvek od FHonza »

Upřímně obdivuji Tvoje zapálení :) Bez ironie, myslím to opravdu.

Wolfik
Příspěvky: 1076
Registrován: 28 črc 2009, 02:00

#39 Příspěvek od Wolfik »

taky bych chtěl takhle rozumět embedded věcem jako lesana

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#40 Příspěvek od lesana87 »

A co ti v tom brání? :)

Wolfik
Příspěvky: 1076
Registrován: 28 črc 2009, 02:00

#41 Příspěvek od Wolfik »

priority, energie a čas :roll:

Uživatelský avatar
Habesan
Příspěvky: 6924
Registrován: 12 led 2009, 01:00
Bydliště: Plzeňsko
Kontaktovat uživatele:

#42 Příspěvek od Habesan »

Kdybych 40 let denně cvičil, taky bych měl svaly jako Martin Maxa.
Sháním hasičák s CO2 "sněhový", raději funkční.
(Nemusí mít platnou revizi.)
(Celkově budu raději, když se to obejde bez papírů.)

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#43 Příspěvek od lesana87 »

Ještě před rokem jsem se plácala úplně bez energie a nic mě nebavilo, pak mě chytlo tohle a úplně tím žiju. Čas si člověk udělá, když chce, stačí si upravit ty priority. :)

Wolfik
Příspěvky: 1076
Registrován: 28 črc 2009, 02:00

#44 Příspěvek od Wolfik »

já bych nevěděl, kde začít
třeba jak sis nastudovala portaci, tak starého linuxu?
tvoje znalosti Céčka a ASM si nabrala zřejmě víceletou praxí, já si připadám, že poslední roky v čistým C dělám víceméně pořád dokola to samý...

Uživatelský avatar
lesana87
Příspěvky: 3296
Registrován: 20 zář 2014, 02:00

#45 Příspěvek od lesana87 »

No vidíš, tak v C jsi napřed, já v C začala programovat až teď, dřív jsem programovala jen v assembleru. :)
Nevím, co přesně máš na mysli tou portací a jejím studováním. Prostě jsem prolejzala zdrojáky starýho linuxu a snažila jsem se v tom vyznat. K tomu se mi nepovedlo najít žádnou dokumentaci, všechno je až k verzi 2.0 a výše, ale i to trochu pomůže s pochopením. A pak taky zdrojáky unixu V6, k těm existuje i nějaká dokumentace od Thompsona a Ritchieho a povídání od J. Lionse. Přečetla jsem knížku The Design of the Unix Operating System od Maurice Bacha, ta je taky k novější verzi unixu, ale tam se toho moc nezměnilo. Četla jsem i Tanenbaumovo Operating Systems Design and Implementation o minixu. A pár dalších knížek. No a pak jsem to začala postupně přepisovat pro ten můj hardware. Některé části se daly převzít jen s malýma úpravama, třeba scheduler nebo funkce kolem souborového systému z linuxu. Některé jsem musela překopat úplně od základu, protože se vázaly na hw, třeba přepínání procesů, správa paměti, obsluhy přerušení, signály, přenosy dat mezi kernelem a procesama... Unix V6 je mnohem jednodušší než linux, tak z unixu jsem se snažila brát "jednoduchost" a z linuxu funkce, které unix neměl a přijdou mi užitečné. :) Hlavně unix V6 běžel na procesoru s 64KB adresním prostorem jako má Z80, i když byl 16-bitovej a podobal se spíš ARMu, byl teda napsanej hodně úsporně. Takže z unixu mám převzatý hlavně datový struktury, protože ty jsou v linuxu dost paměťově rozežraný. Na ty struktury jsem se ale snažila naroubovat některé funkce z linuxu, protože byly třeba líp řešený než v unixu. Tohle kombinování si samozřejmě taky vyžádalo rozsáhlý úpravy kódu. Linux jako takový, ani ten úplně první, se do 64KB na osmibitu prostě nacpat nedá a unix V6 je zase takový moc omezený nebo jak to nazvat. :) (Prapůvodně jsem začala portovat minix 1.1, ale ten je ještě omezenější.) Prostě je to takový kompromisní slepenec z unixu a linuxu. :)

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“