$avrdude -v -c usbasp -p atmega644 -U flash:w:file.hexСкорость выполнения составляет примерно 5 кбайт/сек, что тоже вполне неплохо. Бывают ошибки при попытке прошивки (пишет Expected Signature), причём судя по всему напрямую зависит от компьютера. Так на моём стационарном 6 из 10 попыток успешны, а на нетбуке все 10/10 оказались успешными.
понедельник, 1 февраля 2010 г.
USB-программатор для контроллеров Atmel
$avrdude -v -c usbasp -p atmega644 -U flash:w:file.hexСкорость выполнения составляет примерно 5 кбайт/сек, что тоже вполне неплохо. Бывают ошибки при попытке прошивки (пишет Expected Signature), причём судя по всему напрямую зависит от компьютера. Так на моём стационарном 6 из 10 попыток успешны, а на нетбуке все 10/10 оказались успешными.
вторник, 26 января 2010 г.
Библиотека для цифрового термометра DS18B20
- Работа по интерфейсу 1-wire, который требует всего одной линии для связи с МК;
- Возможность питания от одной линии данных;
- Уникальный 64-битный ID для каждого датчика;
- Возможность развёртывать целые микросети таких датчиков связанных одной шиной;
- Неплохая точность, ±0.5°C в диапазоне -10°C до 85°C;
- Оповещение о выходе температуры из заданных пределов;
- Совместимость с DS1822;
Особенности библиотеки
- Измерение температуры (convert);
- Чтение температуры (readTemp);
- Выбор датчика по его уникальному коду (selectSensor);
- Дополнительные функции (такие как recall, readScratchpad, copyScratchpad, writeScratchpad, и др.);
- Автоматическая проверка контрольной суммы при приёме данных;
- Поддержка датчиков питающихся паразитным током;
- Поиск устройств на шине а также датчиков чья температура выходит из заданных пределов (searchROM, searchAlarm);
- Дополнительные функции для обработки значения температуры, с целью дальнейшего вывода на дисплей (extractInt, extractFract);
Простой пример демонстрирующий вывод текущего значения температуры на дисплей:
#include "wh1602b/wh1602b.h" #include "ds18b20/ds18b20.h" #include <avr/pgmspace.h> void conf_my_lcd(); void loop(); int main(void) { conf_my_lcd(); // настроить вывод на жк-дисплей // выбрать текущий датчик (0 т.к. единственный у меня) if (!ds18b20_selectSensor(0)) { wh1602b_putsP(PSTR("Ошибка на линии!")); for (;;) ; } for (;;) loop(); // цикл обработки } void loop() { ds18b20_convert(); // попросить у датчика измерить температуру wh1602b_move(0,0); wh1602b_putsP(PSTR("t=")); int16_t t = ds18b20_readTemp(); // прочитать значение if (t < 0) // вывести минус если отрицательно wh1602b_putc('-'); wh1602b_puth(1, ds18b20_extractInt(t)); // вывести целую часть на дисплей wh1602b_putc('.'); wh1602b_puth(1, ds18b20_extractFract(t, 1)); // вывести дробную часть на дисплей wh1602b_putsP(PSTR("\1C")); } // <...>Вот что получилось:
Следующий пример демонстрирует вывод уникального кода микросхемы на дисплей:
#include "wh1602b/wh1602b.h" #include "ds18b20/ds18b20.h" #include <avr/pgmspace.h> void conf_my_lcd(); int main(void) { conf_my_lcd(); // настроить вывод на жк-дисплей uint8_t id[8]; if (!ds18b20_readROM(id)) { // прочитать уникальный код датчика в id wh1602b_putsP(PSTR("Ошибка CRC!")); // если ошибка for (;;) ; } wh1602b_putsP(PSTR("ROM Code =")); wh1602b_move(1,0); uint8_t i; for (i = 0; i < 8; ++i) wh1602b_puth(2, id[i]); for (;;) ; } // <...>И результат:
Следующий пример демонстрирует поиск устройств на шине:
#define F_CPU 20000000ULL /* частота мк, гц (для delay) */ #include <avr/pgmspace.h> #include <util/delay.h> #include "wh1602b/wh1602b.h" #include "ds18b20/ds18b20.h" void conf_my_lcd(); void loop(); int main(void) { conf_my_lcd(); // настроить вывод на жк-дисплей for (;;) loop(); // цикл обработки } void loop() { uint8_t i, dc = 0, id[8]; int8_t r; // поиск устройств на шине 1-wire while ((r = ow_searchROM(id))) { if (r < 0) continue; // повтор если ошибка crc wh1602b_move(0,0); // вывести уникальный код датчика на дисплей for (i = 0; i < 8; ++i) wh1602b_puth(2, id[i]); _delay_ms(2000); // пауза 2с. ++dc; } wh1602b_move(1,0); wh1602b_putn(dc); // вывести число датчиков wh1602b_putsP(PSTR(" devices.")); } // <...>И результат в моём случае:
Больше примеров можно будет найти в архиве с библиотекой, ссылка на который указана в разделе "скачать".
Настройка конфигурации
Перед компиляцией библиотеки необходимо задать порты к которым подключён дисплей, а также включаемые возможности. Для этого необходимо отредактировав файл ds18b20/conf.h:
#define F_CPU 20000000 /* частота мк, Гц */ #define USE_EXTRACTINT /* поддержка ds18b20_extractInt() */ #define USE_EXTRACTFRACT /* поддержка ds18b20_extractFract() */ // поддержка автоматической проверки данных контрольной суммой #define SUPPORT_CHECKSUM // поддержка возможности поиска устройств на шине #define SUPPORT_ROMSEARCH // поддержка датчиков питающихся паразитным током #define SUPPORT_PARASITE_MODE // поддержка некоторых дополнительных функций #define SUPPORT_COMPLETE /* порт к которому подключена линия данных */ #define DDR_SENSOR _SFR_IO_ADDR(DDRD) #define PIN_SENSOR _SFR_IO_ADDR(PIND) #define PORT_SENSOR _SFR_IO_ADDR(PORTD) /* ножка к которой подключена линия данных */ #define NPIN_SENSOR PD2Убрать лишние возможности тем самым уменьшив размер занимаемый библиотекой в памяти МК, можно закомментировав некоторые из строчек начинающихся с #define.
Полный перечень поддерживаемых функций
- uint8_t ds18b20_selectSensor(const uint8_t id[8])
Выбирает текущий датчик по его уникальному коду id. Если id = 0, то выбирается первое попавшееся устройство, которое должно быть единственным в сети. Если возвращаемое значение = 0, то вероятно линия данных не правильно настроена. В случае успеха возвращается значение > 0.
- void ds18b20_convert()
Отправляет команду текущему датчику чтобы тот начал измерение температуры.
- uint8_t ds18b20_readROM(uint8_t id[8])
Загружает уникальный код датчика в массив указанный аргументом id. В сети должно находиться только одно устройство, иначе возникнут коллизии. Если возвращаемое значение = 0, то вероятно линия данных не правильно настроена. В случае успеха возвращается значение > 0.
- int16_t ds18b20_readTemp()
Возвращает измеренное значение температуры текущего датчика в градусах. Младшие 4 бита определяют дробную часть, остальная часть - целое значение.
Например, если возвращаемое значение = 0x0191 = 0000000110010001 = 2^4+2^3+2^0+2^-4 = +25.0625°C
- uint8_t ds18b20_readPowerSupply()
Возвращает 1 если текущий датчик использует внешнее питание, 0 - питание от линии данных (паразитное).
- uint8_t ds18b20_readScratchpad(sspad* p)
Загружает состояние внутренней памяти текущего датчика в *p. Проверяется контрольная сумма, и возвращается значение > 0 в случае успеха. Если 0, то вероятно контрольная сумма не совпала, либо линия данных не правильно настроена.
Структура sspad определена в файле ds18b20/ds18b20.h и имеет следующее представление:
typedef struct { uint8_t t_lsb; // temperature LSB uint8_t t_msb; // temperature MSB int8_t t_h; // Th register int8_t t_l; // Tl register uint8_t config; // configuration register uint8_t reserved[3]; // reserved } sspad;
Подробней о назначении каждого параметра можно почитать в официальной документации к ds18b20.
- void ds18b20_writeScratchpad(const sspad* p)
Записывает данные в *p в память текущего датчика.
- void ds18b20_copyScratchpad()
Копирует состояние памяти текущего датчика в его eeprom. EEPROM определяется как энергонезависимая память, и при каждом включении питания, данные из eeprom датчика будут загружаться в его оперативную память.
- void ds18b20_recall()
Восстанавливает состояние памяти текущего датчика из его eeprom.
- int8_t ow_searchROM(uint8_t id[8])
Выполняет поиск следующего из устройств на шине 1-wire, и передаёт его уникальный код в параметр на который указывает id. Если возвращаемое значение = 0, то поиск завершён. Если возвращаемое значение = -1, то это означает что контрольная сумма не совпала, и данные были повреждены при приёме. В случае успеха возвращается значение > 0.
- int8_t ds18b20_searchAlarm(uint8_t id[8])
Выполняет поиск следующего датчика у которого пороговое значение температуры вышло из заданных пределов, и передаёт его уникальный код в параметр на который указывает id. Если возвращаемое значение = 0, то поиск завершён. Если возвращаемое значение = -1, то это означает что контрольная сумма не совпала, и данные были повреждены при приёме. В случае успеха возвращается значение > 0.
- uint16_t ds18b20_extractInt(int16_t t)
Возвращает целую часть значения температуры из двухбайтовой величины t, получаемой при помощи вызова функции readTemp. Возвращаемое значение является абсолютным и представлено в двоично-десятичном формате (bcd).
- uint16_t ds18b20_extractFract(int16_t t, uint8_t r)
Возвращает дробную часть значения температуры из двухбайтовой величины t, получаемой при помощи вызова функции readTemp, округляя его до 1/10^r. Возвращаемое значение является абсолютным и представлено в двоично-десятичном формате (bcd).
Думаю что библиотека будет совместима с большинством микроконтроллеров AVR серии Mega (в моём случае был использован Atmega644).
Скачать
- Исходный код библиотеки вместе с примером можно скачать здесь (или здесь). Лицензия GNU GPL v3+;
- Официальная документация по ds18b20 от производителя;
воскресенье, 10 января 2010 г.
Встречайте - Maxduino!))
PS. Название платы конечно шутка и пародие на Arduino и её многочисленные клоны=)
воскресенье, 27 декабря 2009 г.
Библиотека для семисегментного дисплея BQ-M322RD
- Используя ресурсы таймера 0
- Используя функцию m322_loop() которую программа должна будет непрерывно вызывать в процессе своего выполнения
Примеры использования
Простой пример:
/* программа использует библиотеку откомпилированную с опцией #define USE_TIMER0 */ #include "m322/m322.h" int main(void) { m322_init(); // инициализировать семисегментный дисплей m322_putn(1234); // вывести число 1234 m322_setdot(0, TRUE); // зажечь точку в разряде 0 for (;;) ; }Если библиотека откомпилирована вторым способом, то:
#include "m322/m322.h" int main(void) { m322_init(); // инициализировать семисегментный дисплей m322_putn(1234); // вывести число 1234 на семисегментный дисплей m322_setdot(0, TRUE); // зажечь точку в разряде 0 for (;;) m322_loop(80); // цикл динамической индикации }
/* программа использует библиотеку откомпилированную с опцией #define USE_TIMER0 */ #define F_CPU 16000000ULL /* частота работы мк (для _delay) */ #include <util/delay.h> #include "m322/m322.h" int main(void) { m322_init(); // инициализировать семисегментный дисплей uint16_t number = 0; uint8_t n_dot = 0; for (;;) { m322_setdot(n_dot, TRUE); // зажечь точку с заданным номером m322_putn(number); // вывести десятичное число на индикатор _delay_ms(100); // пауза 100мс m322_setdot(n_dot, FALSE); // погасить точку с заданным номером if (++n_dot == 5) n_dot = 0; if (++number == 10000) number = 0; } }
// // Порты используемые для доступа к отдельным сегментам // #define PORT_SEGDATA _SFR_IO_ADDR(PORTD) #define DDR_SEGDATA _SFR_IO_ADDR(DDRD) /* номера пинов для каждого отдельного сегмента */ #define NPIN_DP PD7 /* точка */ #define NPIN_G PD6 #define NPIN_F PD5 #define NPIN_E PD4 #define NPIN_D PD3 #define NPIN_C PD2 #define NPIN_B PD1 #define NPIN_A PD0 // // Порты используемые для доступа к отдельным разрядам // #define DDR_SEGCTL _SFR_IO_ADDR(DDRB) #define PORT_SEGCTL _SFR_IO_ADDR(PORTB) /* номера пинов для каждого отдельного разряда */ #define NPIN_SEGCTL0 PB4 /* D1 */ #define NPIN_SEGCTL1 PB1 /* D2 */ #define NPIN_SEGCTL2 PB2 /* D3 */ #define NPIN_SEGCTL3 PB3 /* D4 */ // // Дополнительные настройки // // заккоментируйте следующую опцию если не хотите использовать // ресурсы системного таймера0 для организации динамической // индикации семисегментного дисплея: /* использовать таймер */ #define USE_TIMER0 #ifdef USE_TIMER0 // частота мерцания семисегментного индикатора зависит // от коэффициента предделителя таймера0, // и вычисляется по формуле f = F_CPU/(P*256*4), где: // F_CPU - тактовая частота мк, Гц // P - коэффициент предделителя /* значение предделителя для таймера */ #define TIMER0_PRESCALER ((1<<CS00)|(1<<CS01)) /* предделитель 64 */ #endif // USE_TIMER0Я думаю здесь комментарии излишни=)
Схематическое изображение дисплея:
Полный перечень поддерживаемых функций
Библиотека поддерживает все самые необходимые функции, а именно:
- void m322_init()
Выполняет инициализацию семисегментного дисплея (настройка портов, таймера). - void m322_puthd(uint8_t c, uint8_t n)
Выводит шестнадцатеричную цифру n в разряд с номером c индикатора.
- void m322_puthh(uint8_t n)
Выводит шестнадцатеричное число n в старшую часть индикатора (разряды 0 и 1)
- void m322_puthl(uint8_t n)
Выводит шестнадцатеричное число n в младшую часть индикатора (разряды 2 и 3)
- void m322_setdot(uint8_t c, uint8_t b)
Задаёт точку в разряд с номером c индикатора. Если b = TRUE - зажечь, иначе погасить.
- void m322_putn(uint16_t n)
Выводит на индикатор беззнаковое десятичное число n
- void m322_loop(uint16_t n)
Цикл для организации динамической индикации без использования таймера0
Думаю что библиотека будет совместима с большинством микроконтроллеров AVR серии Mega (в моём случае был использован Atmega8).
Скачать
Исходный код библиотеки вместе с примером можно скачать здесь (или здесь).
воскресенье, 6 декабря 2009 г.
Библиотека для ЖК-дисплея WH1602b
- Поддержка знакогенератора (298+52 байт)
- Поддержка функции вывода десятичных чисел (298+66 байт)
- Поддержка функции вывода шестнадцатеричных чисел (298+72 байт)
- Вывод строк, символов
- Вывод чисел
- Очистка дисплея
- Управление курсором
- Поддержка знакогенератора (до 8-ми знаков, согласно спецификации)
- Настройка различных параметров работы
- Чтение памяти дисплея
- Текущее положение курсора нельзя определить
Библиотека использует 4-битную шину для передачи данных.
Примеры использования
Простой пример:
#include "wh1602b/wh1602b.h" int main(void) { wh1602b_init(); // инициализировать модуль, порты // настроить параметры управления дисплеем wh1602b_displayctl(DC_DISPLAY_ON); // дисплей включён // задать число строк wh1602b_funcset(FS_LINES_2); // 2 строки // очистить область wh1602b_clear(); // вывести строку на дисплей wh1602b_puts("Hello, World!"); for (;;) ; }Результат:
Следующий пример демонстрирует возможность загрузки собственного знака:
#include "wh1602b/wh1602b.h" // собственно массив представляющий собой // знак который надо загрузить static const uint8_t window_char[8] = { 0x1f, // 1 1 1 1 1 0x11, // 1 0 0 0 1 0x0e, // 0 1 1 1 0 0x04, // 0 0 1 0 0 0x0e, // 0 1 1 1 0 0x15, // 1 0 1 0 1 0x15, // 1 0 1 0 1 0x00 // 0 0 0 0 0 }; int main(void) { wh1602b_init(); // инициализировать модуль, порты // настроить параметры управления дисплеем wh1602b_displayctl(DC_DISPLAY_ON); // дисплей включён // задать число строк wh1602b_funcset(FS_LINES_2); // 2 строки // очистить область wh1602b_clear(); // записать символ ассоциировав его с кодом 5 wh1602b_genc(5, window_char); // вернуться в начало (команда аналогичная move). // этот вызов является обязательным после вызова genc() wh1602b_home(); // вывести строку на дисплей вместе с новым знаком :) wh1602b_puts("Крякозябла \5"); for (;;) ; }Результат:
#include "wh1602b/wh1602b.h" #include <avr/pgmspace.h> int main(void) { <...> // вывести строку1 из памяти программ wh1602b_putsP(PSTR("Здравствуй")); // переместить курсор на заданную позицию (нумерация с нуля) wh1602b_move(1,4); // 2 строка, 5 столбец // вывести строку2 из памяти программ wh1602b_putsP(PSTR("Мир!")); <...> }Результат:
Как настроить библиотеку под себя
#define F_CPU 16000000 /* частота мк, Гц */ #define USE_PUTN /* включить поддержку wh1602b_putn() */ #define USE_PUTH /* включить поддержку wh1602b_puth() */ #define USE_GENC /* включить поддержку wh1602b_genc() */ /* ножки к которым подключены выводы RS, RW, EN */ #define NPIN_RS PB4 #define NPIN_RW PB3 #define NPIN_EN PB2 /* порты к которым подключены выводы RS, RW, EN */ #define PORT_RS _SFR_IO_ADDR(PORTB) #define PORT_RW _SFR_IO_ADDR(PORTB) #define PORT_EN _SFR_IO_ADDR(PORTB) #define DDR_RS _SFR_IO_ADDR(DDRB) #define DDR_RW _SFR_IO_ADDR(DDRB) #define DDR_EN _SFR_IO_ADDR(DDRB) /* ножки к которым подключены выводы DB4-DB7 */ #define NPIN_DB7 PD7 #define NPIN_DB6 PD6 #define NPIN_DB5 PD5 #define NPIN_DB4 PD4 /* порты к которым подключены выводы DB4-DB7 */ #define PORT_DB7 _SFR_IO_ADDR(PORTD) #define PORT_DB6 _SFR_IO_ADDR(PORTD) #define PORT_DB5 _SFR_IO_ADDR(PORTD) #define PORT_DB4 _SFR_IO_ADDR(PORTD) #define DDR_DB7 _SFR_IO_ADDR(DDRD) #define DDR_DB6 _SFR_IO_ADDR(DDRD) #define DDR_DB5 _SFR_IO_ADDR(DDRD) #define DDR_DB4 _SFR_IO_ADDR(DDRD)
Соответствующие ножки дисплея показаны на следующем рисунке:
Как компилировать программы написанные с использованием этой библиотеки
# from to module cost alias WH-1602B// WH1602B// alias 1602B// WH1602B// module WH1602B// INTERNAL WH1602B 1 module INTERNAL WH1602B// WH1602B 1
Полный перечень поддерживаемых функций
- void wh1602b_init()
Выполняет инициализацию модуля дисплея.
- void wh1602b_funcset(uint8_t t)Устанавливает число строк и размера шрифта. В качестве аргументов может служить комбинация одного или нескольких параметров:
FS_LINES_2 - использовать две строки дисплея (по умолчанию одна строка, FS_LINES_1) FS_FONT_5x11 - использовать шрифт размером 5х11 (по умолчанию 5х8)
- void wh1602b_entrymode(uint8_t t)Настраивает режима ввода. В качестве аргументов может служит комбинация одного или нескольких параметров:
EM_CURSOR_DIR - использовать автоматическое перемещение курсора слева-направо EM_DISPLAY_SHIFT - разрешить смещение дисплея
- void wh1602b_displayctl(uint8_t t)Устанавливает параметры управления дисплеем. В качестве аргументов может служит комбинация одного или нескольких параметров:
DC_DISPLAY_ON - дисплей включён (по умолчанию выключен, DC_DISPLAY_OFF) DC_CURSOR_BLINK - использовать мигающий курсор DC_CURSOR_ON - использовать курсор
- void wh1602b_puts(const char* s)
Выводит строку s из RAM на дисплей.
- void wh1602b_putsP(const char* s)
Выводит строку s из памяти программ на дисплей.
- void wh1602b_putn(uint16_t n)
Выводит десятичное число n на дисплей.
- void wh1602b_puth(uint8_t w, uint16_t h)Выводит шестнадцатеричное число h на дисплей. Ширина поля определяется параметром w
- void wh1602b_genc(uint8_t n, const uint8_t* p)Записывает знак на который указывает p в знакогенератор. Если это последний записываемый знак, и при этом ожидается вывод на дисплей, то необходимо после выполнения genc вызвать wh1602b_home() или wh1602b_move().
- void wh1602b_home()
Возвращает курсор в начальное положение. Если дисплей при этом смещён то функция восстанавливает его.
- void wh1602b_move(uint8_t r, uint8_t c)Перемещает курсор на заданную позицию (r - строка, c - столбец). Нумерация начинается с нуля.
- void wh1602b_putc(uint8_t c)
Выводит символ c на экран дисплея.
- void wh1602b_clear()
Очищает экран дисплея.
Исходный код библиотеки вместе с примером можно скачать здесь.
понедельник, 30 ноября 2009 г.
Пишем драйвер для лампочки=) Часть 2.
Написание основного проекта
// файл ~/hard_project/libdrv/main.c #define F_CPU 16000000UL /* тактовая частота МК */ #include "leddrv/leddrv.h" int main(void) { led_init(); // инициализация лампочки for (;;) // бесконечный цикл led_blink_ms(500); // мигнуть с частотой 0,5сек }
$ make avr-gcc -g -Wall -O2 -mmcu=atmega168 -o .main.o -c main.c avr-gcc -g -Wall -O2 -mmcu=atmega168 -o .main.elf .main.o -static -Lleddrv/ -lleddrv avr-objcopy -j .text -j .data -O ihex .main.elf main.hex
А затем и прошил свой МК:
$ make program avrdude -v -c dapa -p atmega168 -P /dev/parport0 -b 115200 -U flash:w:main.hex
И вот оно, о чудо - работает!
Итог
Всё круто! Цель достигнута. В моих планах написать аналогичные библиотеки для ЖК-модуля и датчика температуры. Надеюсь это произойдёт в недалёкой перспективе:)
---
Скачать hard_project.tar.gz
воскресенье, 29 ноября 2009 г.
Пишем драйвер для лампочки=) Часть 1.
Подготовительная часть
3) Создать папку для основного проекта, у меня это ~/hard_project.
4) Создать папку для проекта библиотеки, у меня это ~/hard_project/libdrv.
Написание библиотеки
Основной файл будет иметь следующее содержание:
;; файл ~/hard_project/libdrv/leddrv.S: #include <avr/io.h> #include "conf.h" .global led_init ; void led_init() ; предварительная настройка порта led_init: sbi _SFR_IO_ADDR(LED_DDR),LED_NPIN ; установить ножку на вывод данных ret .global led_on ; void led_on() ; включение лампочки led_on: sbi _SFR_IO_ADDR(LED_PORT),LED_NPIN ; записать логическую 1 в порт ret .global led_off ; void led_off() ; выключение лампочки led_off: cbi _SFR_IO_ADDR(LED_PORT),LED_NPIN ; записать логический 0 в порт ret .global led_blink ; void led_blink(uint16_t f) ; мигание лампочки с заданной частотой led_blink: sbi _SFR_IO_ADDR(LED_PORT),LED_NPIN ; записать логическую 1 в порт push r24 push r25 rcall delay ; задержать выполнение cbi _SFR_IO_ADDR(LED_PORT),LED_NPIN ; записать логический 0 в порт pop r25 pop r24 rcall delay ; задержать выполнение ret ; задержка на заданное значение delay: ; до 770*65535/F_CPU, сек clr r0 0: com r0 1: dec r0 brne 1b sbiw r24,1 brne 0b ; 770 тактов за цикл ret
// файл ~/hard_project/libdrv/leddrv.h: #include <stdint.h> #ifdef F_CPU #define led_blink_ms(x) led_blink(((x)*(uint64_t)F_CPU)/(770*1000ul)) #endif void led_init(); void led_on(); void led_off(); void led_blink(uint16_t f);
// файл ~/hard_project/libdrv/conf.h: #define LED_PORT PORTC #define LED_DDR DDRC #define LED_NPIN PC1
$Make avr-gcc -Wall -x assembler-with-cpp -mmcu=atmega168 -o .leddrv.o -c leddrv.S avr-ar rcs libleddrv.a .leddrv.o
В следующий раз я покажу как использовал эту библиотеку в своём проекте=)
---
Скачать исходники libdrv.tar.gz
среда, 18 ноября 2009 г.
Программа IBCrypt v1.00
Лицензия: GNU GPL v3. Программа написана с использованием библиотеки Qt4
Скачать (с rapidshare.de):
- Версия для GNU/Linux, с включёнными зависимостями: (i686, amd64)
- Пакет для Arch Linux (i686, amd64)
- Пакет для Debian/Ubuntu (i686, amd64)
- Версия для Windows
- Исходный код
вторник, 17 ноября 2009 г.
Этот мир сошёл с ума...
Всё, нет пути. Мы все скоро умрём..
Мои впечатления о Chromium..
понедельник, 16 ноября 2009 г.
Программа MMixMulator
- MMixBuger - среда для разработки приложений MMIX. Представляет собой программу, имеющую графический интерфейс, которая содержит редактор кода с подсветкой синтаксиса, обозреватель памяти, регистров общего и специального назначения, встроенный отладчик. С помощью данной среды, программа MMIX может быть составлена, скомпилирована и выполнена. Результат выполнения отображается в командной строке (консоли). Программа может быть отлажена по шагам, точкам останова.
- MMixAS - ассемблер, совместимый с тем который описывается в книге Кнута (при этом некоторые фишки не поддерживаются на данный момент)
- MMixEx - интепретатор машинного кода MMIX. Позволяет запускать программы скомпилированные при помощи MMIX-ассемблера.
Скачать:
четверг, 15 октября 2009 г.
Программа «Я Труп» v1.0!)
Программа была написана на языке Си и Си++. Внешний вид показан на следующих рисунках:
Скачать (с rapidshare.de):
- Версия для GNU/Linux, 208кб (i686, amd64)
- Версия для Windows, 83мб (все зависимости включены!)
- Исходный код
Скачать (с альтернативного источника):
- Версия для GNU/Linux, 208кб (i686, amd64)
- Версия для Windows, 83мб (все зависимости включены!)
- Исходный код
вторник, 10 марта 2009 г.
Решение проблемы с модулем CGI::Ajax при передаче символов "+" и "%"
Наткнулся на один неприятный баг в данном модуле для Perl. Например есть вот такой код:
#!/usr/bin/perl -w
use strict;
use CGI; # or any other CGI:: form handler/decoder
use CGI::Ajax;
my $cgi = new CGI;
my $pjx = new CGI::Ajax( 'exported_func' => \&perl_func );
print $pjx->build_html( $cgi, \&Show_HTML);
sub perl_func {
return( join("<br>",@_) );
}
sub Show_HTML {
my $html = <<EOHTML;
<HTML>
<BODY>
Enter something:
<input type="text" id="val">
<input type="button" onclick='exported_func(["val"],["resultdiv"])' value="Do!"/>
<br>
<div id="resultdiv"></div>
</BODY>
</HTML>
EOHTML
return $html;
}
Так вот, если запустить этот Perl-скрипт из браузера, ввести в поле ввода "плохую" строку вроде "text % text + text", нажать кнопку "Do!" мы не увидим знака "+" в "resultdiv".
Есть решение, в нашем примере, после строки:
my $pjx = new CGI::Ajax( 'exported_func' => \&perl_func );
нужно добавить:
$pjx->js_encode_function('encodeURIComponent');
В таком случае, при вводе в поле "+", мы получим "+", но если добавить/заменить "+" на "%" то ничего не получим. Кроме того, браузер выдаст различные ошибки JavaScript.
Методом копания в исходниках CGI::Ajax, была обнаружено что неполадки возникают при попытке повторного раскодирования запрошенной строки. Файл /usr/share/perl5/CGI/Ajax.pm, строка 942:
<...>
pjxInitialized : function(){},
pjxCompleted : function(){},
readyState4 : function(){
var rsp = $decodefn(this.r.responseText); /* the response from perl */
var splitval = '__pjx__'; /* to split text */
/* fix IE problems with undef values in an Array getting squashed*/
rsp = rsp.replace(splitval+splitval+'g',splitval+" "+splitval);
var data = rsp.split(splitval);
<...>
В данном куске кода строка:
var rsp = $decodefn(this.r.responseText); /* the response from perl */
должна быть заменена на:
var rsp = this.r.responseText; /* the response from perl */
А также в нашем примере, после строки:
my $pjx = new CGI::Ajax( 'exported_func' => \&perl_func );
нужно добавить:
$pjx->js_encode_function('encodeURIComponent');
И ошибка будет решена! :-)
воскресенье, 22 февраля 2009 г.
Решение проблемы неработоспособности Slax 6.х при его загрузке.
Исходные данные таковы:
Приступим:
1) Загружаемся в Slax, открываем консоль :)
2) Подготовим файл в котором будут хранится настройки:
# dd if=/dev/zero of=/mnt/sda1/slax.dat bs=1M count=512
# /sbin/mkfs.ext2 /mnt/sda1/slax.dat
где:
/mnt/sda1/slax.dat - место хранения файла (в моём случае он хранится на разделе NTFS)
count=512 - размер файла в мб.
3) Находим файл boot/initrd.gz на CD-ROM, копируем его в /root
4) Распаковываем
# gzip -d initrd.gz
5) Монтируем:
# mkdir fs
# mount -t ext2 initrd fs -o loop
6) Качаем пакет e2fsprogs и его зависимости. Я нашёл его в репозиториях Debian (packages.debian.org):
# wget http://ftp.de.debian.org/debian/pool/main/e/e2fsprogs/e2fsprogs_1.39+1.40-WIP-2006.11.14+dfsg-2etch1_i386.deb
# wget http://ftp.de.debian.org/debian/pool/main/e/e2fsprogs/e2fslibs_1.39+1.40-WIP-2006.11.14+dfsg-2etch1_i386.deb
# wget http://ftp.de.debian.org/debian/pool/main/e/e2fsprogs/libcomerr2_1.39+1.40-WIP-2006.11.14+dfsg-2etch1_i386.deb
7) Собственно извлекаем:
# mkdir e2fsprogs
# dpkg --extract "e2fsprogs_1.39+1.40-WIP-2006.11.14+dfsg-2etch1_i386.deb" e2fsprogs
# cp e2fsprogs/sbin/fsck.ext2 fs/sbin
# cp e2fsprogs/sbin/e2fsck fs/sbin
# mkdir e2fslibs
# dpkg --extract "e2fslibs_1.39+1.40-WIP-2006.11.14+dfsg-2etch1_i386.deb" e2fslibs
# cp e2fslibs/lib/* fs/lib
# mkdir libcomerr2
# dpkg --extract "libcomerr2_1.39+1.40-WIP-2006.11.14+dfsg-2etch1_i386.deb" libcomerr2
# cp libcomerr2/lib/* fs/lib
if [ "$(basename "$CHANGESMNT" .dat)" != "$CHANGESMNT" ]; then
/sbin/fsck.ext2 -y "$CHANGESMNT"
fi
9) Заключительные шаги: Отмонтируем наш initrd и сожмём обратно программой gzip
# umount fs
# gzip initrd
При дальнейшей загрузке Slax не забываем указывать параметр "changes=/slax.dat"
суббота, 31 мая 2008 г.
Запуск Linux прямо из Glofiish M700
1) Ядро Linux
2) Наличие в устройстве карточки MicroSD объёмом не менее 128мб
3) Haret - программа-загрузчик ядра запускающийся прямо из Windows CE
4) Текстовый файл с параметрами загрузки ядра
5) Образ OPIE или GPE
Приступим.
1) Скачаем образ ядра (здесь)
2) Скачаем haret
3) Скопируем всё это хозяйство в память коммуникатора (не на карточку а на встроенную память)
4) Создадим в той папке в которую скопировали, файл default.txt с таким содержанием:
set MTYPE 0x664
set KERNEL "zImage_x500"
set RAMADDR 0x30000000
set RAMSIZE 0x4000000
set CMDLINE "root=/dev/mmcblk0p2 rootdelay=5 panic=360"
bootlinux
5) Необходимо подключить microSD карту к компьютеру (через кардридер или напрямую через USB кабель+WM5Storage), при этом убедится что не один раздел не смонтировался автоматически.
6) Создадим разделы на карточке согласно такой схеме - минимум 50мб для раздела с ext3, всё оставшееся свободное пространство оставим для fat16. Для своей карты объемом 2ГБ я разбил диск на разделы по такой схеме:
+================================================+ | 1800мб - FAT16 | 213мб - EXT3 | +================================================+для выполнения этого шага использовалась утилита cfdisk.
7) Необходимо записать на созданные разделы файловую систему:
$/sbin/mkfs.msdos /dev/sdc1 -n WINDOWS
$/sbin/mkfs.ext3 /dev/sdc2 -j -L LINUX
где:
/dev/sdc - имя устройства microSD карты
/dev/sdc1 - первый раздел с windows fat
/dev/sdc2 - второй раздел с linux ext3
8) Скачаем OPIE например отсюда
9) Скопируем всё содержимое скачаного архива на раздел с линуксом (/dev/sdc2 в моём случае)
10) Отмонтируем карточку с компьютера(если использовался кард-ридер), вставим обратно в зверька, убедимся что FAT раздел на карточке виден с КПК
Перед загрузкой ядра обязательно отключаем проверку пароля при загрузке мастдая, иначе потом придётся делать хард-ресет!
11) Запускаем haret, нажимаем кнопку RUN, и... нервно ожидаем загрузки....
Приятного использования :)
Да, совсем забыл сказать, чтобы обратно перезагрузится в винду нажмите одновременно Soft-Reset и клавишу выключения (только не удерживая долго)
Полезные программы для OPIE, а также пакеты с локализацией можно скачать здесь
Полезные ссылки:
1) http://linux.cybernet.net.ru (битая?)
2) http://www.handhelds.org
3) http://ipkgfind.handhelds.org





























