LinuxæèŒã®EmbedSky E8ããã³ã³ãã¥ãŒã¿ãŒãããŒã¹ã«æ§ç¯ããããœãããŠã§ã¢ã·ã³ã»ãµã€ã¶ãŒã«ããµãŠã³ããçæããããŒããŠã§ã¢ãå®å
šã«çœ®ãæããããšã§ãæ°ããåœãå¹ã蟌ãããšããŠããå€ã䜿ãå€ãããã·ã³ã»ãµã€ã¶ãŒã«é¢ãã話ã®ç¶ãã ããããããã«ãèšäºã®ç¬¬1éšãšç¬¬2éšã®çºè¡ã«ã¯ãèšç»ãããã¯ããã«é·ãæéãããããŸããããããã§ãç¶ç¶ããŸãã
åã®ããŒãã§ã¯ãã·ã³ã»ãµã€ã¶ãŒã®æ°ãããé è³ãçšã®ããŒããŠã§ã¢ãã©ãããã©ãŒã ãéžæããããã»ã¹ã«ã€ããŠããœãªã¥ãŒã·ã§ã³ã®æè¡çç¹åŸŽã«ã€ããŠèª¬æããå¿
èŠãªã©ã€ãã©ãªãŒãçµã¿ç«ãŠãããã»ã¹ãšããã»ã¹ã§ééããåé¡ã«ã€ããŠç°¡åã«èª¬æããŸããã ããŠãéã«ã€ããŠã¯ãã·ã³ã»ãµã€ã¶ãŒã®ããŒããŒããããªãã¯ã¹ãã©ã®ããã«é
眮ãããŠãããã確èªãããœãããŠã§ã¢éšåã«ã€ããŠããã«è©³ãã説æããŸãã
ããŒããŒããããªãã¯ã¹
ã·ã³ã»ãµã€ã¶ãŒã®ããŒããŒããããªãã¯ã¹ã¯ããã€ã¯ãã³ã³ãããŒã©ãŒã®å€ãã®ãã¡ã³ãããããArduinoã«æ¥ç¶ããŠããéåžžã®ããŒããŒããããªãã¯ã¹ã«éåžžã«äŒŒãŠããŸãã ã·ã³ã»ãµã€ã¶ãŒããŒããšã«ã1ã€ã®ïŒæãå®äŸ¡ãªã¢ãã«ã®ïŒã¹ã€ãããã2ã€ã®ïŒã¢ãã«ã®å€§éšåã®ïŒã¹ã€ãããæäŸããŸãã ããŒãæŒããããšãã«äžæ¹ãå°ãæ©ãéãã2ã€ã®é£æ¥ããã¹ã€ããã䜿çšããŠããã€ã¯ãã³ã³ãããŒã©ãŒã¯æ¡ä»¶ä»ãã®åããŸãã¯ããŒãæŒãããé床ã決å®ã§ããããã察å¿ããããªã¥ãŒã ã®é³ãåçãããŸãã 次ã®ããã«ãªããŸãã
ããŒãã®èé¢ã«ã¯ãæŒãããããŒã®ã誀ã£ããèªã¿åããé²ããã€ãªãŒãããããŸãããåæã«ããã€ãã®ããŒãæŒããŠããŸãã ããŒããŒããããªãã¯ã¹ã®åè·¯å³ã®äžéšã次ã«ç€ºããŸãããããã®2ã€ã®ã¹ã€ãããšãããã«æ¥ç¶ãããŠãããã€ãªãŒãã衚瀺ãããŠããŸãã
ãããªãã¯ã¹ãã¹ãã£ã³ããããã«ããã€ã¯ãã³ã³ãããŒã©ãŒã¯åïŒNã®ã©ãã«ãä»ãããã³ïŒãé çªã«ãã«ããè¡ã®ã¬ãã«ïŒBã®ã©ãã«ãä»ãããã³ïŒã確èªããŸãã è¡ã®ã¬ãã«ãé«ãå ŽåãçŸåšã¢ã¯ãã£ããªãåãšè¡ãã®çµã¿åããã«å¯Ÿå¿ããããŒãæŒãããŸãã å³ã¯ããŒããŒãã®äžéšã®ã¿ã瀺ããŠããŸã-åèš76åã®ããŒããããŸãïŒ13è¡ãš6 x 2åãããã«ããããããªãã¯ã¹ã®ã¹ãã£ã³ã«åèš156ã®ãªãã·ã§ã³ãããã€ã¯ãã³ã³ãããŒã©ãŒã®25ã®äœ¿çšæžã¿åºåãæäŸãããŸãïŒã ããŒããŒãå
šäœã®ã¹ãã£ã³ã¯æ¯ç§æ°ååå®è¡ãããå®è¡è
ã«ã¯èŠããŸããã
ç§ã®ã·ã³ã»ãµã€ã¶ãŒã§ã¯ãããŒããŒãã®ã¹ãã£ã³ãæ
åœãããã€ã¯ãã³ã³ãããŒã©ãŒã¯ããšããšã8 MHzã®åšæ³¢æ°ã§åäœãã4 KBã®ROMãš192ãã€ãã®RAMã¡ã¢ãªãåãã8ãããã®ã¯ã³ã¿ã€ã ããã°ã©ããã«Hitachi HD63B05V0ãã€ã¯ãã³ã³ãããŒã©ãŒã§ããã æ®å¿µãªããšã«ããã®ã³ã³ãããŒã©ãŒã¯ãæåã®èšäºã®åé ã§èª¬æããé»åäºæ
ã®åŸãäœåäžèœã§ããããšãå€æããŸããã ãããã幞ããªããšã«ãããã¯ç§ã®æ¢åã®ATmega162ã³ã³ãããŒã©ãŒãšã»ãŒäºææ§ããããããŒãäžã®2ã€ã®ãã©ãã¯ã®ã¿ãåæããŠåã¯ãã ä»ãããããšã§çœ®ãæããŸããããã®1ã€ã¯RESETãã³ã§ãééã£ãå Žæã«ããããšãå€æããŸããHD63B05V0ãªã©ã
ãã®ã³ã³ãããŒã©ãŒããªã³ã«ãããšïŒä»ã®ãã³ã«ãããããïŒçµã¿èŸŒã¿ã®UARTã䜿çšã§ããªãã£ããããæŒãããããŒã«é¢ããæ
å ±ã衚瀺ããããã«ã·ãªã¢ã«ããŒãã®
ãã®äžæ¹åïŒæžã蟌ã¿å°çšïŒå®è£
ã䜿çšããŸããã ãŸããã·ãªã¢ã«ããŒãã®ãœãããŠã§ã¢å®è£
ã䜿çšãã
TinySafeBootããŒãããŒããŒã¯ãå°æ¥ã®ãã¡ãŒã ãŠã§ã¢æŽæ°ãå¯èœã«ããããã«ãã€ã¯ãã³ã³ãããŒã©ãŒã«æ³šãããŸããã ãã¹ãŠã®é«ã¬ãã«ã·ã³ã»ãµã€ã¶ãŒãœãããŠã§ã¢ã®è¿
éãªéçºã®ããã®èšèªãšããŠPython + Qt5ãéžæãããããTinySafeBootã®ããã«ãAVRãã€ã¯ãã³ã³ãããŒã©ãŒã®ãã¡ãŒã ãŠã§ã¢ãèªã¿æžãã§ããPythonã¢ãžã¥ãŒã«ãäœæããŸããã AVRãã€ã¯ãã³ã³ãããŒã©ãŒèªäœã¯ãEmbedSky E8ããŒãã®UART1ã·ãªã¢ã«ããŒãã«æ¥ç¶ãããã¬ãã«å€æã®å¿
èŠæ§ãåé¿ããããã«3.3Vã§é§åãããŸãã
AVRã®ãã¡ãŒã ãŠã§ã¢ãœãŒã¹#include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #include <string.h> #include "dbg_putchar.h" #define MIDI_BASE 18 #define ZERO_BASE 28 #define KEYS_COUNT 76 #define hiz(port, dir) do { \ (dir) = 0; \ (port) = 0; \ } while(0) #define alow(port, dir) do { \ (dir) = 0xff; \ (port) = 0; \ } while(0) uint8_t keys[KEYS_COUNT]; /* Get state of a row by its index * starting from 1 to 13 */ uint8_t getRow(uint8_t idx) { if (idx <= 8) { return (PINC & (1 << (8 - idx))); } else if (idx >= 9 && idx <= 11) { return (PINE & (1 << (11 - idx))); } else if (idx == 12) { return (PINA & (1 << PIN6)); } else if (idx == 13) { return (PINA & (1 << PIN4)); } return 0; } inline void activateColumn1(uint8_t idx) { PORTD = 0x00 | (1 << (8 - idx)); PORTB = 0x00; } void activateColumn2(uint8_t idx) { if (idx <= 3) { PORTB = 0x00 | (1 << (idx + 4)); PORTD = 0x00; } else if (idx == 4) { PORTB = 0x00 | (1 << PIN4); PORTD = 0x00; } else if (idx == 5 || idx == 6) { PORTD = 0x00 | (1 << (idx - 5)); PORTB = 0x00; } } inline void deactivateColumns(void) { PORTD = 0x00; PORTB = 0x00; } inline void initPorts(void) { hiz(PORTA, DDRA); hiz(PORTC, DDRC); hiz(PORTE, DDRE); PORTB = 0x00; DDRB = 0xfe; DDRD = 0xff; } void resetRows(void) { /* output low */ alow(PORTC, DDRC); alow(PORTE, DDRE); /* don't touch PA7 & PA5 */ DDRA |= 0x5f; PORTA &= ~0x5f; _delay_us(10); /* back to floating input */ hiz(PORTC, DDRC); hiz(PORTE, DDRE); DDRA &= ~0x5f; } /* base MIDI note number is 25: C#0 */ int main(void) { uint8_t row, col, layer; uint8_t note, offset; initPorts(); memset(keys, 0, sizeof(keys)); dbg_tx_init(); dbg_putchar('O'); dbg_putchar('K'); while(1) { for (layer = 0; layer < 2; layer++) { for (col = 1; col <= 6; col++) { if (!layer) activateColumn1(col); else activateColumn2(col); for (row = 1; row <= 13; row++) { note = 6 * row + col + MIDI_BASE; offset = note - ZERO_BASE; if (getRow(row)) { if (!layer) { /* increase velocity counter */ if (keys[offset] < 254 && !(keys[offset] & 0x80)) keys[offset]++; } else { if (!(keys[offset] & 0x80)) { /* generate note-on event */ dbg_putchar(0x90); dbg_putchar(note); /*dbg_putchar(keys[offset]);*/ dbg_putchar(0x7f); /* stop counting */ keys[offset] |= 0x80; } } } else { if (layer) continue; if (keys[offset] & 0x80) { /* generate note off event */ dbg_putchar(0x90); dbg_putchar(note); dbg_putchar(0x00); /* reset key state */ keys[offset] = 0x00; } } } deactivateColumns(); resetRows(); } } } return 0; }
TinySafeBootçšã®Pythonã¢ãžã¥ãŒã« import serial import binascii import struct import intelhex import sys class TSB(object): CONFIRM = '!' REQUEST = '?' def __init__(self, port): self.port = serial.Serial(port, baudrate=9600, timeout=1) self.flashsz = 0 def check(self): if not self.flashsz: raise Exception("Not activated") def activate(self): self.port.write("@@@") (self.tsb, self.version, self.status, self.sign, self.pagesz, self.flashsz, self.eepsz) = \ struct.unpack("<3sHB3sBHH", self.port.read(14)) self.port.read(2) self.pagesz *= 2 self.flashsz *= 2 self.eepsz += 1 assert(self.port.read() == self.CONFIRM) def rflash(self, progress=None, size=0): self.check() self.port.write("f") self.addr = 0 self.flash = "" size = self.flashsz if not size else size while self.addr < size: if progress is not None: progress("read", self.addr, size) self.port.write(self.CONFIRM) page = self.port.read(self.pagesz) if len(page) != self.pagesz: raise Exception("Received page too short: %d" % len(page)) self.addr += len(page) self.flash += page return self.flash.rstrip('\xff') def wflash(self, data, progress=None): if len(data) % self.pagesz != 0: data = data + "\xff" * (self.pagesz - (len(data) % self.pagesz)) assert(len(data) % self.pagesz == 0) self.check() self.port.write("F") self.addr = 0 assert(self.port.read() == self.REQUEST) while self.addr < len(data): if progress is not None: progress("write", self.addr, len(data)) self.port.write(self.CONFIRM) self.port.write(data[self.addr:self.addr + self.pagesz]) self.addr += self.pagesz assert(self.port.read() == self.REQUEST) self.port.write(self.REQUEST) return self.port.read() == self.CONFIRM def vflash(self, data, progress=None): fw = self.rflash(progress, len(data)) return fw == data def info(self): print "Tiny Safe Bootloader: %s" % self.tsb print "Page size: %d" % self.pagesz print "Flash size: %d" % self.flashsz print "EEPROM size: %d" % self.eepsz if __name__ == "__main__": import argparse def progress(op, addr, total): sys.stdout.write("\r%s address: $%0.4x/$%0.4x" % (op, addr, total)) sys.stdout.flush() parser = argparse.ArgumentParser() parser.add_argument("filename", help="firmware file in Intel HEX format") parser.add_argument("--device", help="Serial port to use for programming", default="/dev/ttyUSB0") args = parser.parse_args() tsb = TSB(args.device) tsb.activate() tsb.info() fw = intelhex.IntelHex(args.filename) assert(tsb.wflash(fw.tobinstr(), progress)) assert(tsb.vflash(fw.tobinstr(), progress)) print "\nOK\n"
AVRã®ããã°ã©ããŒãšããŠãç§ã¯ãŸã
Launchpad MSP430ãããŒã¹ã«ãã
ããã°ã©ããŒã䜿çšããŸãããããã®ãã¡ããã€ãããããŸããããã®ä»®èšã®å¥è·¡ïŒã¡ãªã¿ã«ããŸããããŸãïŒã¯ãäžåœããå°çããTL866CS MiniProããã°ã©ããŒã«åã£ãŠä»£ãããŸããã æ°ããããã°ã©ããŒã®æ°æã¡ã¯éåžžã«ããžãã£ãã§ãã
å€éšRAMããããæ¥ç¶ããããã®AVRãã€ã¯ãã³ã³ãããŒã©ãŒã€ã³ã¿ãŒãã§ãŒã¹ãä»ããéåžžã«ç¬åµçãªã¹ãã£ã³æ¹æ³ãå«ããã·ã³ã»ãµã€ã¶ãŒã®ããŒããŒãèšèšãšã¹ãã£ã³æ¹æ³ã«é¢ããéåžžã«è©³çŽ°ãªæ
å ±ã¯ã
OpenMusicLabsãŠã§ããµã€ãã§èª¬æãããŠããŸã
Realtime PreemptionãµããŒãã䜿çšããã«ãŒãã«ã®ã¯ããã³ã°
ã¹ã±ãžã¥ãŒã©ããã现ããå¶åŸ¡ãããµãŠã³ããåçããéã®ã¬ã€ãã³ã·ãŒãæžãããããšãã¹ããŒãã®é¢å¿ã®ããã«ãç§ã¯ã«ãŒãã«ã
PREEPMT RTããããšãšãã«äœ¿çšããããšã«æ±ºããŸããããã®äž»ãªæ©èœã®1ã€ã¯å²ã蟌ã¿ããããã»ã¹ãã«ãªããŸãåªå
床ã«åºã¥ããŠã¹ã±ãžã¥ãŒã©ãŒã«ãã£ãŠæšªåããããŸãã S5PV210ããã»ããµçšã«SamsungãæäŸããå
ã®ã³ã¢ã¯ãã·ã¹ãã ã®æ§ç¯ã«åºã¥ããŠãæããã«Androidã®ã«ãŒãã«ããŒãžã§ã³3.0.8ã«åºã¥ããŠããŸãã ãã®ã«ãŒãã«ããŒãžã§ã³ïŒ3.0.8ïŒã®ãããžã§ã¯ããµã€ãã§å©çšå¯èœãªRT_PREEMPTãããã¯ã競åãªãã§ãœãŒã¹ã«éãåãããããšãæã¿ãŸããã§ããããæçµçã«ã¯ãã¹ãŠã®ç«¶åãæåã§è§£æ±ºããããŒãžã§ã³3.0.8-rt23ã«ããããé©çšããããšãã§ããŸããã
ã¹ãã³ããã¯ããã¥ãŒããã¯ã¹ãªã©ã®åºæ¬æ§é ããã®æ¹æ³ã§å€æŽãããã«ãŒãã«ã§å€æŽãããããšãå€æããããããããªã«ã¡ã©ãéé»å®¹éåŒã¿ããã¹ã¯ãªãŒã³ã³ã³ãããŒã©ãŒãªã©ã®äžéšã®åšèŸºæ©åšã®ç¬èªãã©ã€ããŒã¯ãææªã®å Žåãã³ã³ãã€ã«ããããªããžã§ã¯ããã¡ã€ã«ãšããŠãªã³ã¯ãããªããªããŸãããªãŒãã£ãªã³ãŒããã¯ã åŸã§ãããã«æ»ãããããããªãã«ããŠãæ°ããçµã¿ç«ãŠããããªã¢ã«ã¿ã€ã ã«ãŒãã«ã䜿çšããŠããŒããåããŠèµ·åããããšãããšãããã«ã«ãŒãã«ãããã¯ãçºçããŸãã kgdbãããã¬ãŒãèµ·åããåã§ãçºçããããïŒåŸã§å€æããããã«ãèµ·åããŠãåäœããŸããïŒããããã°ã®ããã«ã
start_kernel
init/main.c
ãã¡ã€ã«ïŒ
start_kernel
é¢æ°ïŒã«æ¿å
¥ããŠå Žæãç¹å®ããå¿
èŠããããŸãããã¹ãŠã厩ããŠããŸãã ãããã£ãŠãã«ãŒãã«
hrtimers_init()
æåŸ
hrtimers_init()
ãã£ãããšã¯ã
hrtimers_init()
é¢æ°ãåŒã³åºãããšã§ãããããã¯é«è§£å床ã¿ã€ããŒãšãã®å²ã蟌ã¿ãåæåããããšã§ããã ãã®ã³ãŒãã¯ãã©ãããã©ãŒã åºæã§ããããã®å Žåã¯
arch/arm/plat-s5p/hr-time-rtc.c
ãŸãã åè¿°ããããã«ãPREEMPT RTãããã䜿çšããã«ãŒãã«ã®äž»ãªæ©èœã®1ã€ã¯ãå²ã蟌ã¿ãã¹ã¬ããã«ãªãããšã§ãã ããã¯éåžžã®ã«ãŒãã«ã§å¯èœã§ãããããã©ã«ãã§PREEMPT RTã䜿çšããã«ãŒãã«ã¯ããã®ãããªã»ãšãã©ãã¹ãŠã®å²ã蟌ã¿ãäœæããããšããŸãã ã³ãŒããããã«åæãããšãkthreadd_taskã¿ã¹ã¯ããããã®ã¹ã¬ããã®æäœã«äœ¿çšããã
start_kernel
é¢æ°ã®æåŸã§åæåãããããšã瀺ãããŸãããã¿ã€ããŒãåæåãããããããã£ãšåŸã§ãã ãã®äœäžã¯ãkthreadd_taskããŸã NULLã§ãã£ãã®ã«ãã«ãŒãã«ãã¹ããªãŒãã³ã°ã«ãã£ãŠã¿ã€ããŒãäžæããããšããããã§ãã ããã¯ãã©ã®ãããªç¶æ³ã§ãã¹ããªãŒãã³ã°ãããã¹ãã§ã¯ãªãåã
ã®å²ã蟌ã¿ãèšå®ããããšã§è§£æ±ºãããŸããIRQF_NO_THREADãã©ã°ã¯ã
hr-time-rtc.c
ã¿ã€ããŒå²ã蟌ã¿ãã©ã°ã«è¿œå ãããŸããã ãã£ãïŒ ã«ãŒãã«ã¯èµ·åããŸããããããã¯ã»ãã®å§ãŸãã§ã...
åè¿°ããããã«ãå¯äœçšã®1ã€ã¯ããªãŒãã£ãªå
¥å/åºåãæ
åœããã¢ãžã¥ãŒã«ãæ°ããã«ãŒãã«ãšã®ãªã³ã¯ãåæ¢ããããšã§ãã ããã¯ãPREEMPT RTã䜿çšããã«ãŒãã«ãïŒããŒãžã§ã³3.0.8ã§ïŒSLABã¡ã¢ãªç®¡çã¡ã«ããºã ã®ã¿ããµããŒãããæåã¯ã¢ãžã¥ãŒã«ãæ°ããã«ãŒãã«ã§ãµããŒããããŠããªãSLUBã¡ã«ããºã ãæå¹ã«ããŠã³ã³ãã€ã«ãããããã§ãã ããããKaspersky Labã§åãããšãã§ããã®ã¯å¹žéã§ãARMã®Hex-Raysãã³ã³ãã€ã©ãŒã䜿çšããŠãã©ã€ããŒãšã³ãŒããã¯ãã¡ã€ã«ãéã³ã³ãã€ã«ããããååã«èª¬åŸãããã®åŸããœãŒã¹ã³ãŒããã»ãŒå®å
šã«åäœæããããšãã§ããŸããã å®éã«ã¯ããã®çµæããªãŒãã£ãªã€ã³ã¿ãŒãã§ã€ã¹ã¯ãæ°ããããã©ã€ãã§æ±ºå®ããããããWM8960ãã€ã¯ããµãŒãããã¬ãžã¹ã¿ãåæåããããã®äœã¬ãã«ã®æé ã®éãã«ããããµãŠã³ãã¯ã¢ãŒãã£ãã¡ã¯ãã§åçãããŸããã ãã°ããã®éããã©ã€ããŒã調æŽããããšããŸãããããã®åŸãããç°¡åãªæ¹æ³ãéžæããŸãã-ç§ã¯äžåœã®äŒç€ŸEmbedSky Techã«éã£ãŠãããã§ããã³ã³ãã¥ãŒã¿ãŒãšPREEMPT_RTã®ãããã賌å
¥ãããªãŒãã£ãªãã©ã€ããŒãã¡ã€ã«ã®ã³ã³ãã€ã«ãšéä¿¡ãäŸé ŒããŸããã ããã«å¿çããæçµçã«ãµãŠã³ããæåŸ
ã©ããã«æ©èœãããã¡ã€ã«ãéã£ãŠãããŸããã
ãšããã§ãéã³ã³ãã€ã«ãããã©ã€ããŒã§å¿ããã£ãã®ã§ãããkgdbãããã¬ãŒãèªåã®ã«ãŒãã«ã§ãå
ã®ã«ãŒãã«ã§ãåäœããªãããšãããããŸããã å€æããããã«ãã·ãªã¢ã«ããŒãã®åæããŒãªã³ã°ãå¿
èŠã§ããããã¯ãSamsungã·ãªã¢ã«ããŒããã©ã€ããŒïŒ
drivers/tty/serial/samsung.c
ïŒã§ã¯å©çšã§ããŸããã§ããã
ãã®ãããã«åºã¥ããŠãã©ã€ããŒã«å¿
èŠãªãµããŒããè¿œå ãããã®åŸãããã¬ãŒãåäœããŸããã
ããã«æããŸãã æ°ããã³ã¢ã®ç¬¬2ã®å¯äœçšã¯éåžžã«äœãã倧ããªãé
ãããS5PV210ãããäžã®ã·ã¹ãã ã®4ã€ã®ãã¹ãŠã®é·ãã·ãªã¢ã«ããŒãã®é床ã§ããããšãå€æããŸãããããŒãªã³ã°ããŒããŒãã·ã³ã»ãµã€ã¶ãŒã é·ãéãç§ã¯ãã®çç±ãç解ããããšããŸãããã端æ«ã«åæåãå
¥åãããšãæ°çŸäžã®ã·ãªã¢ã«ããŒãå²ã蟌ã¿ãçæãããããšã«æ°ã¥ããŸãã-ã«ãŒãã«ã¯ããããåŠçããããã«æ¥ãã§ããªãããã§ããã æåŸã«ãäžèšã®ãã©ã°ã䜿çšããŠIRQF_NO_THREADãã¹ãŠã®ã·ãªã¢ã«ããŒãå²ã蟌ã¿ãéã¹ã¬ããã«ããããšã§ããã®åé¡ã解決ããŸããã ãã®ãœãªã¥ãŒã·ã§ã³
serial_core.c
ãSamsungãã©ã€ããŒã«å ããŠã
serial_core.h
ãš
serial_core.h
ãå€æŽããªããã°ãªãããäžè¬çã«ãã¹ãŠã®ã·ãªã¢ã«ããŒãã«åœ±é¿ãããããããŸãçŸãããããŸããã§ããã PREEMPT RTã䜿çšããã«ãŒãã«ã§ã¯ãNO_THREADã®ãã©ã€ããŒã§spin_lock_tã䜿çšã§ããªãããraw_spinlock_tã䜿çšããå¿
èŠãããããã
åè¿°ããããã«ã512 MBã®RAMãããããªã«ã¡ã©ãããŒããŠã§ã¢ã³ãŒããã¯ãHDMIãªã©ã®ããŸããŸãªåšèŸºæ©åšããµããŒãããå
ã®ã«ãŒãã«ã§ã¯ãçŽ390 MBãã䜿çšã§ãããæ®ãã¯äžèšã®ããã€ã¹çšã«äºçŽãããŠããŸãããåžžã«ïŒã«ãŒãã«æ§æããã»ã¹äžã«ç¡å¹ã«ãããå Žåã§ãïŒã ç¹ã«ã·ã³ã»ãµã€ã¶ãŒããµã³ãã«ãä¿åããã®ã«äœåãª120 MBã®RAMãéªéã«ãªããªãããšãèãããšãéåžžã«ç¡é§ã§ãã ã¡ã¢ãªã¯ãã¡ã€ã«
arch/arm/mach-s5pv210/mach-tq210.c
ã«äºçŽãããŠããŸãããããã¯ãç¹å®ã®ãã·ã³ïŒãã®å Žåã¯ããŒãïŒã®æ§æãšããã€ã¹ã«é¢ãããã¹ãŠã®æ
å ±ãåéããããã®äž»èŠãªãã€ã³ãã§ãã ã¡ã¢ãªã®å²ãåœãŠ
s5p_reserve_bootmem
é¢æ°ã®åŒã³åºãã«ã€ããŠã³ã¡ã³ããã
s5p_reserve_bootmem
æ©èœããããã«120 MBã®è¿œå ã¡ã¢ãªãååŸããŸãã
ã«ãŒãã«ã«å ããããæåŸã®å€æŽã¯ããªãŒãã£ãªããŒã¿ã®æå°ãããã¡ãµã€ãºã«é¢ãããã®ã§ãå
ã®ã¡ã¢ãªã®1ããŒãžã«çžåœãã44100 Hzã®ãµã³ããªã³ã°åšæ³¢æ°ã§ã16ãããã®2ãã£ãã«ãããããçŽ20ããªç§-å°ãå€ãã£ãã ãã®å€ã¯ããã¡ã€ã«
sound/soc/samsung/dma.c
ã§128ãã€ãã«å€æŽããããã®åŸãå®å®æ§ãšããã©ãŒãã³ã¹ãç ç²ã«ããããšãªããæå°ãããã¡ãŒãµã€ãºãæ°ããªç§ã«åæžãããŸããã
PREEMPT RTããã³GitHubã®ãã¹ãŠã®å€æŽãå«ãã«ãŒãã«ãœãŒã¹ã³ãŒãAVRãã€ã¯ãã³ã³ãããŒã©ãŒã¯ã©ã®ããã«LinuxSamplerãšéä¿¡ããŸãã
AVRã¯ããã³ã³ãã¥ãŒã¿ãŒããŒãã®ã·ãªã¢ã«ããŒãã«æ¥ç¶ãããæ¢è£œã®MIDIã¡ãã»ãŒãžããœãããŠã§ã¢UARTã«åºåããŸãã ãã©ã€ããŒãèšè¿°ããå¿
èŠããªããããã«ããã¹ãŠã®ãªãŒãã£ãªããã³MIDIããŒã¿ã®ãã©ã³ã¹ããŒããšããŠJACKãµãŒããŒã䜿çšããããšã決å®ãããŸããã Cã®å°ããªã¢ããªã±ãŒã·ã§ã³ãã·ãªã¢ã«ããŒãã«æ¥ç¶ããJACKã«èªèº«ãMIDI-OUTãšããŠç»é²ããåä¿¡ãããã¹ãŠã®MIDIã¡ãã»ãŒãžã®ãªãã€ã¬ã¯ããéå§ããŸããJACKã¯ãã§ã«ããããLinuxSamplerã«é
ä¿¡ããŸãã å®ããŠéœæ°ãªã
ã·ãªã¢ã«ããŒããšJACKéã®ããªããžã¢ããªã±ãŒã·ã§ã³ã®ãœãŒã¹ã³ãŒã #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/time.h> #include <unistd.h> #include <assert.h> #include <string.h> #include <sysexits.h> #include <errno.h> #include <signal.h> #include <fcntl.h> #include <termios.h> #include <jack/jack.h> #include <jack/midiport.h> #define UART_SPEED B9600 jack_port_t *output_port; jack_client_t *jack_client = NULL; int input_fd; void init_serial(int fd) { struct termios termios; int res; res = tcgetattr (fd, &termios); if (res < 0) { fprintf (stderr, "Termios get error: %s\n", strerror(errno)); exit (EXIT_FAILURE); } cfsetispeed (&termios, UART_SPEED); cfsetospeed (&termios, UART_SPEED); termios.c_iflag &= ~(IGNPAR | IXON | IXOFF); termios.c_iflag |= IGNPAR; termios.c_cflag &= ~(CSIZE | PARENB | CSTOPB | CREAD | CLOCAL); termios.c_cflag |= CS8; termios.c_cflag |= CREAD; termios.c_cflag |= CLOCAL; termios.c_lflag &= ~(ICANON | ECHO); termios.c_cc[VMIN] = 3; termios.c_cc[VTIME] = 0; res = tcsetattr (fd, TCSANOW, &termios); if (res < 0) { fprintf (stderr, "Termios set error: %s\n", strerror(errno)); exit (EXIT_FAILURE); } } double get_time(void) { double seconds; int ret; struct timeval tv; ret = gettimeofday(&tv, NULL); if (ret) { perror("gettimeofday"); exit(EX_OSERR); } seconds = tv.tv_sec + tv.tv_usec / 1000000.0; return seconds; } double get_delta_time(void) { static double previously = -1.0; double now; double delta; now = get_time(); if (previously == -1.0) { previously = now; return 0; } delta = now - previously; previously = now; assert(delta >= 0.0); return delta; } static double nframes_to_ms(jack_nframes_t nframes) { jack_nframes_t sr; sr = jack_get_sample_rate(jack_client); assert(sr > 0); return (nframes * 1000.0) / (double)sr; } static double nframes_to_seconds(jack_nframes_t nframes) { return nframes_to_ms(nframes) / 1000.0; } static jack_nframes_t ms_to_nframes(double ms) { jack_nframes_t sr; sr = jack_get_sample_rate(jack_client); assert(sr > 0); return ((double)sr * ms) / 1000.0; } static jack_nframes_t seconds_to_nframes(double seconds) { return ms_to_nframes(seconds * 1000.0); } static void process_midi_output(jack_nframes_t nframes) { int t, res; void *port_buffer; char midi_buffer[3]; jack_nframes_t last_frame_time; port_buffer = jack_port_get_buffer(output_port, nframes); if (port_buffer == NULL) { printf("jack_port_get_buffer failed, cannot send anything.\n"); return; } jack_midi_clear_buffer(port_buffer); last_frame_time = jack_last_frame_time(jack_client); t = seconds_to_nframes(get_delta_time()); res = read(input_fd, midi_buffer, sizeof(midi_buffer)); if (res < 0 && errno == EAGAIN) return; res = jack_midi_event_write(port_buffer, t, midi_buffer, 3); if (res != 0) { printf("jack_midi_event_write failed, NOTE LOST."); } } static int process_callback(jack_nframes_t nframes, void *notused) { if (nframes <= 0) { printf("Process callback called with nframes = 0; bug in JACK?"); return 0; } process_midi_output(nframes); return 0; } int connect_to_input_port(const char *port) { int ret; ret = jack_port_disconnect(jack_client, output_port); if (ret) { printf("Cannot disconnect MIDI port."); return -3; } ret = jack_connect(jack_client, jack_port_name(output_port), port); if (ret) { printf("Cannot connect to %s.", port); return -4; } printf("Connected to %s.", port); return 0; } static void init_jack(void) { int i, err; jack_client = jack_client_open("midibridge", JackNullOption, NULL); if (jack_client == NULL) { printf("Could not connect to the JACK server; run jackd first?"); exit(EXIT_FAILURE); } err = jack_set_process_callback(jack_client, process_callback, 0); if (err) { printf("Could not register JACK process callback."); exit(EXIT_FAILURE); } char port_name[32]; snprintf(port_name, sizeof(port_name), "midi_out"); output_port = jack_port_register(jack_client, port_name, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); if (output_port == NULL) { printf("Could not register JACK output port '%s'.", port_name); exit(EXIT_FAILURE); } if (jack_activate(jack_client)) { printf("Cannot activate JACK client."); exit(EXIT_FAILURE); } } static void usage(void) { fprintf(stderr, "usage: midibridge -a <input port>\n"); exit(EXIT_FAILURE); } int main(int argc, char *argv[]) { int ch; char *autoconnect_port_name = NULL; while ((ch = getopt(argc, argv, "a:")) != -1) { switch (ch) { case 'a': autoconnect_port_name = strdup(optarg); break; default: usage(); } } input_fd = open("/dev/ttySAC1", O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if (input_fd < 0) { fprintf(stderr, "Cannot open serial port %s\n", strerror(errno)); return EXIT_FAILURE; } init_serial (input_fd); init_jack(); if (autoconnect_port_name) { if (connect_to_input_port(autoconnect_port_name)) { printf("Couldn't connect to '%s', exiting.", autoconnect_port_name); exit(EXIT_FAILURE); } } getc(stdin); return 0; }
ãã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ãJACKãžã®ãªãŒãã£ãªåºåããµããŒãããmplayerãä»ããŠARMããã³WAV / MP3çšã«ã³ã³ãã€ã«ãã
jack-smf-player
ã䜿çšããŠãJACKã§MIDIãã¡ã€ã«ãåçããããšãã§ããŸãã
ããŒãã¹
以åã®æçš¿ã«å¯Ÿãã
nefelim4agã®ã³ã¡ã³ãã®ãããã§ãç§ã¯libhybris-éåžžã®Linuxã·ã¹ãã ã§Androidãã©ã€ããŒã䜿çšã§ããã©ã€ãã©ãªãŒã®ååšã«ã€ããŠåŠã³ãŸããã ã¿ã³ããªã³ãšã®ããã€ãã®ãã³ã¹ã®åŸãæ®å¿µãªãããç§ã¯ã·ã¹ãã ã§libhybrisãååŸããOpenGL ES 2.0ãEGLFSãããã³Qt Quick 2.0ããµããŒãããŠQt 5ããã³PyQt5ãåæ§ç¯ã§ããŸããã çŸåšãç§ã®ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã¯Qt Quickã䜿çš
ããŠããã Android 4.0ã§åãåãã
ãŠããææ°ã®ãã¡ãã·ã§ã³ãã¬ã³ãã«æ²¿ã£ãŠããŸãã
æåŸã«
ã·ã³ã»ãµã€ã¶ãŒãååã«åé¡ãããç¶æ
ã«ãããããå°ããª
ãã¢ã¯ãããŸã§ã®ãšãããªãŒãã£ãªã®ã¿ã§ãã ãããªã¯ãäžåœã§æ³šæããããã¶ãŒããŒããå°çããã·ã³ã»ãµã€ã¶ãŒã®ãã¹ãŠã®éšåãæ¥ç¶ããåŸã8æã«çãŸããå¯èœæ§ãé«ã次ã®æçš¿ã«ãããŸãã ããã«ã次ã®æçš¿ã¯ããã®ãããªäœã¬ãã«ã®ã«ãŒãã«æäœã§ã¯ãªããPyQt5ããã³QtQuickã®ãœãããŠã§ã¢ã®ãŠãŒã¶ãŒéšåã念é ã«çœ®ããŠããã¡ãããçµæãå®èšŒããããã»ã¹ã«å°å¿µããã§ãããã
誰ããèå³ãããå ŽåïŒ
ARMçšã«ã¯ãã¹ã³ã³ãã€ã«ããããã¹ãŠã®ãœãããŠã§ã¢ããªã¹ããã- alsa-lib-1.0.27.2
- alsa-utils-1.0.27.2
- libaudiofile-0.3.6
- dbus-1.8.0
- dropbear-2014.63
- fftw-3.3.3
- fluidsynth-1.1.6
- fontconfig-2.11.0
- freetype-2.5.3
- glib-2.34.3
- libicu-52.1
- jack-audio-connection-kit-0.121.3
- jack-smf-utils-1.0
- libffi-3.0.13
- libgig-3.3.0
- libgig-svn
- ãªããªããªã¹
- libsamplerate-0.1.8
- libsndfile-1.0.25
- linuxsampler-1.0.0
- linuxsampler-svn
- mplayer SVN-r36900-4.4.6
- openssl-1.0.0l
- psutil-1.2.1
- pajack-0.5.2
- PyQt-gpl-5.2
- pyserial-2.7
- Python 2.7.6
- strace-4.8
- tslib-1.4.1
ãã®ãªã¹ãããäœããåéããå¿
èŠããããåé¡ãããå Žåã¯ãåãã§ç§ã®çµéšãå
±æããŸãã ããã«ãããã§è¿°ã¹ãããŠããããšã®å€ãã¯ãFriendlyARM Tiny210ãšåŒã°ããå¥ã®äžè¬çãªãã©ãããã©ãŒã ã«ãåœãŠã¯ãŸããŸããããã¯ãåãS5PV210ããã»ããµã«åºã¥ããŠããããããã誰ãããªã¢ã«ã¿ã€ã ã³ã¢ã䜿çšããå¿
èŠããããŸãã