Страницы

Поиск по вопросам

Показаны сообщения с ярлыком embedded. Показать все сообщения
Показаны сообщения с ярлыком embedded. Показать все сообщения

пятница, 24 января 2020 г.

JLink (flash load)/MDR32F1QI в Linux

#linux #embedded


Недавно занялся программированием Российского микроконтроллера MDR32F1QI. Проблем
со сборкой не говоря уже про сам контроллер не возникло. Однако, вот уже месяц как
прошиваю контроллер из Windows c помошью Keil'a или програмки из поставки отладочной
платы, а отлаживаю в Linux/Eclipse/JLink V8. Поскажите пожалуйста что мне написать
в makefile'e для прошивки моего соотечественника (как угодно, хоть бы и вне makefile'a
отдельной утилитой). Пробовал вот такую строку:
    openocd -f target/1986ve1t.cfg -c init; reset halt; flash write_image erase $(RESULT).bin
0x00000000; reset run; shutdown 
В ответ получаю следующее:
    Open On-Chip Debugger 0.9.0 (2015-09-02-10:42)
Licensed under GNU GPL v2
For bug reports, read
    http://openocd.org/doc/doxygen/bugs.html
Error: Debug adapter does not support any transports? Check config file order.
Error: unable to select a session transport. Can't continue.
shutdown command invoked
reset: unknown terminal type halt
Terminal type? 
Что за "terminal type" и что не нравится openocd?  Имя файла конфигурации openocd
(1986ве1т.cfg) изменено (русские буквы в названиях файлов понятны не всем вспомогательным
утилитам)
    


Ответы

Ответ 1



unknown terminal type halt выдаёт команда linux reset (см. man reset, ну не находит она терминала с именем halt). Точки с запятой в командной строке разделяют команды shell, поэтому так получилось. По-видимому всё после -c следует заключить в апострофы: openocd -f target/1986ve1t.cfg -c 'init; reset halt; flash write_image erase $(RESULT).bin 0x00000000; reset run; shutdown'

суббота, 11 января 2020 г.

Как собрать программу, использующую стороннюю библиотеку

#cpp #linux #embedded #cross_compiling


Имеется программа, состоящая из одного .cpp-файла. Она использует библиотеку libcurl.
Необходимо скомпилировать это дело под встраиваемый Linux на процессоре Cortex A7 (arm
32-bit).

Как я понимаю, нужно сконфигурировать, а затем собрать библиотеку под нужную архитектуру,
после чего собрать саму программу посредством кросс-платформенного компилятора.

Проблема в том, что я не представляю, как указать компилятору, чтобы #include  понимал,
что библиотека лежит где-то рядом здесь.
    


Ответы

Ответ 1



как там указать, чтобы #include понимал, что библиотека лежит где-то рядом здесь На самом деле речь о заголовочном файле библиотеки (*.h) флаг -I. (инклюды ищутся в одной папке с компилируемым файлом) чтобы линкер знал, где лежит скомпиленная библиотека флаг -L.(в той же папке) чтобы при загрузке библиотека искалась в одной папке с исполняемым файлом флаги -Wl,-R,\$$ORIGIN Наверняка, этого недостаточно, чтобы решить вашу конкретную задачу, но это три стандартных метода, чтобы собрать и запустить что-то в одной папке. Может чем-то помочь.

понедельник, 23 декабря 2019 г.

Почему контроллер (stm32l476rg) падает в hard fault?

#c #embedded #stm32


Пытаюсь запустить программу моргания светодиодами на STM32L476RG. Программа успешно
прошивается и запускается. Выполняется начальная инициализация, но когда программа
делает переход на main() -- получаю hard fault:


  signal handler called () at 0xfffffff9


Для прошивки использую openocd. Использую библиотеку libopencm3, поэтому скрипт линкера
выглядит так:

MEMORY
{
   rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
   ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
}

INCLUDE libopencm3_stm32l4.ld


Полный скрипт libopencm3_stm32l4.ld ниже.

/*
 * This file is part of the libopencm3 project.
 *
 * Copyright (C) 2009 Uwe Hermann 
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this library.  If not, see .
 */

/* Generic linker script for STM32 targets using libopencm3. */

/* Memory regions must be defined in the ld script which includes this one. */

/* Enforce emmition of the vector table. */
EXTERN (vector_table)

/* Define the entry point of the output file. */
ENTRY(reset_handler)

/* Define sections. */
SECTIONS
{
    .text : {
        *(.vectors) /* Vector table */
        *(.text*)   /* Program code */
        . = ALIGN(4);
        *(.rodata*) /* Read-only data */
        . = ALIGN(4);
    } >rom

    /* C++ Static constructors/destructors, also used for __attribute__
     * ((constructor)) and the likes */
    .preinit_array : {
        . = ALIGN(4);
        __preinit_array_start = .;
        KEEP (*(.preinit_array))
        __preinit_array_end = .;
    } >rom
    .init_array : {
        . = ALIGN(4);
        __init_array_start = .;
        KEEP (*(SORT(.init_array.*)))
        KEEP (*(.init_array))
        __init_array_end = .;
    } >rom
    .fini_array : {
        . = ALIGN(4);
        __fini_array_start = .;
        KEEP (*(.fini_array))
        KEEP (*(SORT(.fini_array.*)))
        __fini_array_end = .;
    } >rom

    /*
     * Another section used by C++ stuff, appears when using newlib with
     * 64bit (long long) printf support
     */
    .ARM.extab : {
        *(.ARM.extab*)
    } >rom
    .ARM.exidx : {
        __exidx_start = .;
        *(.ARM.exidx*)
        __exidx_end = .;
    } >rom

    . = ALIGN(4);
    _etext = .;

    .data : {
        _data = .;
        *(.data*)   /* Read-write initialized data */
        . = ALIGN(4);
        _edata = .;
    } >ram AT >rom
    _data_loadaddr = LOADADDR(.data);

    .bss : {
        *(.bss*)    /* Read-write zero initialized data */
        *(COMMON)
        . = ALIGN(4);
        _ebss = .;
    } >ram

    /*
     * The .eh_frame section appears to be used for C++ exception handling.
     * You may need to fix this if you're using C++.
     */
    /DISCARD/ : { *(.eh_frame) }

    . = ALIGN(4);
    end = .;
}

PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));


Параметры компилятора:


  arm-none-eabi-g++ -mcpu=cortex-m4 -march=armv7e-m -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
-munaligned-access -O0 -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections
-g3 ...


Собственно как можно локализировать источник проблемы? Где собака зарыта?
    


Ответы

Ответ 1



В первую очередь откройте шестнадцатеричным редактором готовый бинарный файл и посмотрите, действительно ли в начале программы расположена таблица прерываний. В ней первое слово должно быть равно 0x20000000 + размер оперативной памяти - это указатель стека. Дальнейшие слова - указатели прерываний, и скорее всего, большинство из них должны указывать на один и тот же адрес - адрес метки DefaultHandler. Он должен иметь вид приблизительно 0x0800.... Если всё в порядке, идём дальше. [далее - догадки] В скрипте линкера присутствует переменная vector_table, которой нигде не присваивается значение. Скорее всего, она используется в стартовом ассемблерном коде программы для копирования таблицы прерываний в оперативную память, но так как этой переменной не присвоено значение, копирование происходит непонятно куда. Скорее всего, подразумевалось следующее: .text : { vector_table = . *(.vectors) /* Vector table */ *(.text*) /* Program code */ . = ALIGN(4); *(.rodata*) /* Read-only data */ . = ALIGN(4); } >rom Чтобы определить точно, нужно смотреть ассемблерные листинги. Поскольку вы располагаете отладчиком, вы можете их протрассировать и найти место, где (возможно) происходит копирование. Если причина не в этом, можно также проверить таблицу прерываний, действительно ли она подходит вашему контроллеру.

Ответ 2



В основном эта ошибка возникает при неправильной работе с памятью (обращение за границу допустимой области памяти). Надо убедиться, что: размер стека достаточен; не используется неинициализированный указатель.

Ответ 3



Возможные причины HardFault: Debugging a HardFault on Cortex-M Cortex-M3 / M4 Hard Fault Handler Методы отладки: Debugging a Hard Fault Debugging Hard Fault & Other Exceptions on ARM Cortex-M3 and ARM Cortex-M4 microcontrollers Debugging Hard Faults on ARM Cortex-M Developing a Generic Hard Fault handler for ARM Cortex-M3/Cortex-M4 Сам когда-то возился (причины были в некорректных указателях, порче памяти и переполнении стека). В вашем случае возможно что-то из 2-й ссылки.

пятница, 20 декабря 2019 г.

Литература по Embedded [закрыт]

#embedded


        
             
                
                    
                        
                            Закрыт. Этот вопрос не по теме. Ответы на него в данный
момент не принимаются.
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            Хотите улучшить этот вопрос? Update the question so it's
on-topic for Stack Overflow на русском.
                        
                        Закрыт 4 года назад.
                                                                                
           
                
        
Доброго времени суток знатокам ! Я сам из Украины, закончил местный ВУЗ, и хочу уйти
с головой в Embedded даже не смотря что это не перспективно и зарплаты значительно
ниже от WEB-разработчиков, но так сложилось что не люблю я копаться в тоннах HTML-кода
или JS просто WEB мне не по душе, мне нравиться работать на уровне ядра ОС и железячки.
Вопрос таков, кто-нибуть знает толковую литературу по этой теме ? Искал про контроллеры
ARM (с которыми хочу поработать) так либо всякий бред качаю, либо никто разумного ничего
не написал, ничего про Embedded толкового не нашёл, может кто-то ещё что либо подскажет
(в какую сторону двигаться, но только в Embedded направлении) ! Короче люди я буду
ждать любой совет, ресурс, подсказку, направление, очень хочу всё это охватить, познать
и поработать !!!    
    


Ответы

Ответ 1



Дружище поверь, ты будешь плеваться потом долго и упорно что не стал заниматься как я вебом, а ушел как я в железо. Для начала, Должен знать Си просто изумительно, asm по ходу будешь догонять, есть есть с++ знания. Если будешь знать что есть транзисторы и тп вообще прекрасно (разбираться в схеме) вообще прекрасно купи себе отладку недорогую, Например на LPC1111(14) Выглядит отладка так (http://im6-tub-ru.yandex.net/i?id=599861828-08-72&n=21 ) lpcexpresso. Прочитай даташит к процу и юзермануал, разберись, немного страниц 800 английским. Читай как работать с UART,SPI,I2C,RTC и другой периферией. На отладке есть термодатчик и еще что-то с чем можно повзаимодействовать. Покупай или дербань сотовые достовай из них дисплее ищи инфу и выводи что нибудь на экран. Если будет у тебя проц с USB, попробуй и в нем разобраться. Как поймешь что к чему, Купи получше проц и SWD или JTAG отладчик, GSM, GPS модули,SD карту, сделай например проект типа GPS маячек. Можешь попробовать проект реализовать на RTOS, и использовать многопоточность. К изучению как минимум http://books.tr200.ru/v.php?id=804485 Качай с сайтов примеры кода работы с периферией, смотри что к чему. Если тяжелой книга окажется, тогда уходи в RISC процессоры AVR или PIC(16)(24)

Ответ 2



Ну Embedded можно не только на С/asm. Есть там небольшое пространство и для Java. Позырь в сторону Java Embedded или Java Card

Ответ 3



А с английским как? Если хорошо, то для начала очень советую "Making Embedded Systems", Elecia White и "The Art of Designing Embedded Systems", Jack Ganssle Можно почитать довольно обширную тему на этом форуме. Из русскоязычного, можно почитать книги от М. Предко, "Устройства управления роботами" и другие (но надо делать скидку на время, к примеру, те же PIC-и нынче "не в моде" (хотя и всё ещё применяются) ). Практически все книги есть в сети. Не книги, но лично мне кажется полезным: сборник статей на этом сайте, а так-же курсы на edx ("Embedded systems - shape the world", "Circuits and Electronics " и "Electronic Interfaces: Bridging the Physical and Digital Worlds")

вторник, 17 декабря 2019 г.

Определить размерность типа int на контроллере

#c #embedded


Можно ли написать какую-нибудь функцию, чтобы узнать размерность типа int на конкретном
контроллере?
    


Ответы

Ответ 1



Вот так можно посчитать кол-во бит в байте, int CharBit() { unsigned char c = ~0U; int res = 1; for(; c >>= 1; ++res) {} return res; } а дальше (sizeof(int) * CharBit()). То есть кол-во char'ов и int'е умножить на кол-во битов в char'e равно кол-ву битов в int'e. Для x86: 4 * 8 = 32 Вот ещё: int IntBit() { int tmp = 0, res = 0; // 0xfffff... while(++res, tmp >>= 1) {} return res; }

понедельник, 16 декабря 2019 г.

Выбор ОС для embedded system

#windows #android #embedded #linux


Есть некий готовый дивайс безкорпусного исполнения с тачскрином. Работает на 
базе ARM Cortex-A8. По заверениям разработчиков поддерживает 3 ос: win ce 
6.0, android, linux. Дивайс будет использоваться только как "дисплей", т.е. визуализировать
опредленные данные, которые штатная сисистема не обрабатывает. Управления и  сложных
расчётов не предполагается. Возникает вопрос: что выбрать в качестве 
ОС для разработки?

Критерии такие:


сложность разработки драйверов (возможно, придется использовать что-нибудь 
нестандартное, скажем ацп контроллера; очевидно, чтоб это заработало на 
уровне ОС надо будет писать драйвер);
сложность использования библиотек граф. интерфейса (я далек от мысли 
делать собственные контролы типа gauge и graph);
ну, и в целом, если судить по вашему опыту.


Кстати отдельно стоит вопрос о тестировании разработки до его заливки на 
дивайс. Скажем, для linux предоставляется исходный код, для android'a 
snapshot, для ce - bsp исходник. Существует ли возможность запустить ОС в 
эмуляторе?

Пример того, что хотелось бы иметь на выходе:

снимок http://www.dundas.com/Libraries/Dashboard_Gallery/sales-performance-dashboard.jpg

    


Ответы

Ответ 1



Сложность разработки драйверов в целом одинаковая для всех трёх ос. Правда при использовании стандартных устройств есть шанс, что на CE заработает нахаляву, тогда как в Linux эта вероятность ниже. Наличие стандартных контролов, тут всё зависит от вас. В обоих случаях вам не придётся писать их самостоятельно. В случае android это ещё и выглядеть будет весьма эстетично. У меня есть только опыт с Embedded Linux и он (опыт) в целом положительный. OC в эмуляторе - qemu. Например, в нём работает стандартный android-эмулятор. Кроме того, в этом смысле Linux-системы предпочтительнее, так как удобно запускать и отлаживать приложения на живом устройстве по сети, в том числе и само ядро. UPD Думаю, учитывя, что вы хотите такую красоту, но не хотите писать это руками, то скорее всего ваш выбор - Android. Делать такие красивости другими средствами будет намного сложнее, хотя, нет сомнений, что возможно даже с помощью тормознутого GTK.

Ответ 2



Визуализация визуализации рознь. Как пример, использование плеера vogue в качестве монитора. Чем ближе к железу тем проще. В случае андройда, кроме драйвера к железу придется писать еще и "прокладку" в java. Зато граф интерфейс уже весь готовый есть.

Ответ 3



Dundash Dashboard)) Ох помучался я с ним. Собственно я работал на проекте конкуренте дундаса. Для визуализации использовали JavaScript библиотеку HightCharts; из OS тут конечно android - проблем будет меньше.

вторник, 10 декабря 2019 г.

Виртуальная машина Java (или подобное), написанная на Java

#виртуальная_машина #java #embedded #jvm


Здравствуйте.
Недавно начал изучать виртуальные машины. Возник такой вопрос. Есть некоторые VM,
например, Monty, Squawk. Данные виртуальные машины частично или полностью написаны
на Java. Вот эта фраза меня немного в тупик загнала. (В силу недостатка знаний или
понимания, наверное).
Есть у нас виртуальная машина, написанная на низкоуровневых языках относительно Java
- C++, C, Assembler. Тут все ясно. Машина пишется для каждой платформы, привязываясь
к железу на низкоуровневых языках, для того чтобы интерпретировать псевдокод (байткод)
там, где установлена виртуальная машина. Таким образом достигается кроссплатформенность. 
То есть мы тратим ресурсы железа, для того чтобы поднять виртуальную машину на ней,
а затем генерировать машинный код для платформы на этапе исполнения. Из-за того, что
у нас есть промежуточный слой исполнение, программа, написанная на таких языках, проигрывает
компилируемым языкам.
Ну и собственно вопрос. Зачем писать виртуальную машину на основе другой, точнее
внутри другой. Есть у нас Java VM на устройстве, зачем нужно добавлять еще один слой
абстракции? Выходит, что мы пишем виртуальную машину на основе функционала, который
нам предоставляет уже существующая ВМ на устройстве. То есть таким образом мы, во-первых,
не можем сделать больше, чем предоставляет нам обрамляющая ВМ, к тому же используем
дополнительные вычислительные ресурсы ЭВМ.
Я правильно понимаю?
Хорошо, можно предположить, что это удобно в некоторых случаях, когда не требуется
весь функционал обрамляющей ВМ или же абстрагирование от реализации с целью упрощения
написания кода.   
Конечно, если компьютер предоставляет ресурсы, то можно сделать так, и разница практически
будет незаметна. НО обычно такие ВМ используются на мобильных, портативных устройствах.
Где здесь логика? Зачем добавлять дополнительный слой, ладно если бы это было бесплатно
относительно ресурсов, но ведь это ведет к большим затратам ресурсов, которых на мобильных
устройствах и так очень мало. 
Пожалуйста, объясните идею и преимущества. Может быть, я просто что-то неправильно
понимаю, поправьте, пожалуйста. 
Спасибо большое заранее.    


Ответы

Ответ 1



Squawk VM - не полностью написана на Java, а только часть. На вопрос, "зачем" это все существует, отвечает короткая статья в википедии: https://ru.wikipedia.org/wiki/Squawk. Я предполагаю, что Monty, которая также используется на мобильных устройствах, имеет тот же самый бэкграунд, что и squawk, только со своей спецификой.

Ответ 2



Похоже, что главная цель -- заставить конечного пользователя покупать все более мощные (и дорогие) устройства. Она никогда не формулируется явно, но органически следует из стремления большинства разработчиков получить всего побольше, побыстрее и с меньшими усилиями (кстати, все вышесказанное относится не только к IT).

Ответ 3



переносимость ВМ и ПО для нее между разными устройствами, в частности для запуска на Android и других устройствах без перекомпиляции: автор ВМ может самостоятельно контролировать степень подобия работы ПО на разных устройствах/ОС в т.ч. look&feel GUI интерфейсов потери скорости можно обойти бинарной трансляцией байткода myVM->JVM и встроенным в JVM JIT-компилятором в нативный код: контроль за работой приложений остается, при этом скорость исполнения стремится к скорости машинного кода (при хорошей реализации JIT) [backdoor] обновление ПО без ведома пользователя в обход системы безопасности Android: пользователю достаточно при установке VM один раз подтвердить права, а обновления байткода можно грузить хоть ежечасно и запускать втихую

понедельник, 9 декабря 2019 г.

Выделение памяти на локальные и глобальные переменные

#cpp #c #микроконтроллеры #embedded


В программировании встраиваемых систем не рекомендуется использовать динамическое
выделение памяти. Отсюда у меня возник следующий вопрос. В случае глобальных переменных,
на сколько я знаю, память выделяется сразу. Что делать с локальными? Компилятор сразу
выделяет и на них память или возможна такая ситуация, что при вызове функции с локальными
переменными, память МК будет переполнена, что вызовет печальные последствия?
    


Ответы

Ответ 1



Компилятор не может "сразу" выделять память под локальные автоматические переменные, ибо при каждом рекурсивном входе в одну и ту же функцию она должна получать новый, независимый набор автоматических переменных. Это требует стекообразного динамического распределения памяти для локальных переменных во время выполнения. Что, разумеется, может приводить и к переполнению памяти во время выполнения. Если запретить рекурсивные вызовы в языке, то теоретически компилятор будет в состоянии предсказать максимальный вариант потребления памяти локальными переменными и даже выполнить "раннее" распределение памяти для таких переменных еще на этапе компиляции, фактически заменив их на глобальные переменные. Но что-то подобное можете сделать и вы сами, отказавшись от использования локальных переменных вообще. (Хотя даже в таком случае компилятору будет проще обеспечить максимальную экономию памяти путем "совместного использования" одних и тех же областей памяти теми локальными переменными, которые заведомо не могут существовать одновременно. Выполнить такую "упаковку" переменных вручную теоретически можно, но задача это тяжелая, трудноподдерживаемая и чреватая ошибками.)

Ответ 2



Да, это запросто - потому что локальные переменные выделяются в стеке, и его можно переполнить. Особенно при рекурсии или просто глубокой вложенности функций. Так что нужно или очень строго контролировать, что вызывается и как, и чего и сколько выделяется на стеке, или... С другой стороны, локальные переменные - если их немного - позволяют не заботиться о возможных неприятностях типа перекрытия имен и т.п. "По-моему, так" (с) Пух

суббота, 7 декабря 2019 г.

Повреждение файлов при отключении питания и исключениях в процессах

#c #windows #файлы #исключения #embedded


Я занимаюсь разработкой автономных систем управления и анализа для тяжелой промышленности.
Использую язык C (C99-C11). Очень беспокоит вопрос повреждения файлов и файловых систем,
использующихся в Windows (Embedded, CE и пр.) при внезапном обесточивании или при жестком
прерывании рабочего процесса/потока, например из-за исключения.

Хотелось бы разобраться в этом вопросе, достойной литературы по этой теме найти не
удалось. Посоветуйте что-нибудь, желательно не на английском языке. Или, может быть,
кто-нибудь сможет упрощенно объяснить следующее:


Ясное дело, если мы открыли файл и пишем в него, и в этот момент происходит отключение
питание, или возникает фатальное исключение в одном из потоков процесса, то операция
прерывается на полпути. Это практически гарантированно приводит к повреждению файла/файловой
системы в том районе, где происходит работа. 

Но ведь даже если мы не работаем с файлом, а в этот момент отключается питание, файл
может быть поврежден из-за того, что ОС в фоновом режиме занимается дефрагментацией/индексацией.
Это так?
Есть ли гарантия, что после возврата управления в программу после функций fclose()
или fwrite() данные гарантированно корректно занесены на носитель?

Например, ситуация: 


Процесс имеет два потока, в одном потоке происходит сохранение данных в файл, а в
другом возникает ситуация, после которой мы можем лишь завершить процесс. Например,
посреди сложной логики malloc() вернул NULL, или отказало устройство, или еще что.


Я предполагал защитить файл критической секцией, и использовать эту же критическую
секцию для инициации аварийного завершения. Тогда, предположительно, после того как
работа с файлом закончится, критическая секция освободится, и второй поток сможет в
нее зайти и вызвать abort() или аналогичную функцию планируемого жесткого прерывания
процесса.

Проблема на мой взгляд в том, что даже после того, как мы сделали fopen() + fwrite()
+ fclose(), нет гарантий, что файл корректно сохранен, а не гуляет где-то в буферах,
которые связаны с нашим процессом.
И как контролируется процесс переноса данных из внутреннего промежуточного буфера-кэша
жесткого диска на сам носитель?

Например, файл записан и закрыт, и даже процесс, который все это делал, уже закрыт.
Но данные частично или полностью еще находятся во внутреннем буфере-кэше накопителя.
Если в этот момент произойдет обрыв питания, то данные, я почти уверен, будут повреждены
или уничтожены.

Как ОС отслеживает перед своим завершением факт того, что данные из буфера накопителя
записаны окончательно?

    


Ответы

Ответ 1



Но ведь даже если мы не работаем с файлом, а в этот момент отключается питание, файл может быть поврежден из-за того, что ОС в фоновом режиме занимается дефрагментацией/индексацией. Это так? Во-первых, сомневаюсь, что драйвер самостоятельно будет дефрагментировать что-либо (хотя и не буду утверждать обратное), а отсутствие насущности проблемы фрагментации объясняется в первую очередь грамотными алгоритмами выбора блоков для хранения файлов. А критические, неустранимые ошибки ФС в таких случаях — это практически невероятный сценарий (скажем, внезапный отказ HDD — куда более вероятен). Но повреждения данных (файлов) с которыми велась активная работа в момент отказа — штатная ситуация. 2) Есть ли гарантия, что после возврата управления в программу после функций fclose() или fwrite() данные гарантированно корректно занесены на носитель? Нет. fwrite () гарантирует только занесение данных в пользовательский буфер, но не гарантирует, что эти данные будут переданы ОС. Чтобы принудительно сбросить пользовательский буфер есть функция fflush (). При скоропостижной кончине процесса данные могут быть потеряны. fclose () и fflush () сбрасывают пользовательский буфер, но не гарантируют, что ОС передаст данные на носитель. Если процесс умрёт после их возврата, то изменения не потеряются, но они могут быть потеряны в случае внезапного отключения питания. 3) И как контролируется процесс переноса данных из внутреннего промежуточного буфера-кэша жесткого диска на сам носитель? Для того чтобы гарантировать запись данных на диск средств Си недостаточно, необходимо пользоваться API ОС. В POSIX-системах (и в linux в частности) есть вызов fsync (). Он гарантирует, что вернёт управление (само собой без ошибки) только после того как данные физически попадут на диск и переживут внезапный отказ системы. В Win API аналогом FlushFileBuffers (), согласно документации он сбрасывает системные буферы, но, гарантирует ли сброс буферов самого HDD или нет, я не знаю. Как ОС отслеживает перед своим завершением факт того, что данные из буфера накопителя записаны окончательно? Просто посылает определённую команду HDD. Например, в ATA она так и называется, FLUSH CACHE, опкод E7h. (здесь должен быть ещё десяток оговорок, которые должны быть интересны только разработчикам драйверов)

Ответ 2



Гарантированную запись на диск можно достичь использованием флага FILE_FLAG_NO_BUFFERING при вызове функции CreateFile(). Способ имеет два минуса Замедление операций чтения/записи. Чтобы этого избежать, нужно работать с файлом большими буферами, кратными разделу кластера диска. Альтернативой использования этого флага является функция FlushFileBuffers() Этот флаг гарантирует, что ОС не будет использовать дополнительных буферов, но буферизация есть еще на самом жестком диске. Чтобы отключить буферизацию диска нужно использовать флаг FILE_FLAG_WRITE_THROUGH, но не все устройства этот флаг поддерживают Еще один способ решения проблемы, это писать не в оригинальный файл, а в его копию. А после завершения записи вызывать функцию ReplaceFile() и заменять исходный файл. В одной системе у меня используется два идентичных файла данных и к каждому файлу в отдельном файле лежит контрольная сумма. Запись файлов идет в такой последовательности: Запись основного файла Запись контрольной суммы этого файла Запись копии Запись контрольной суммы копии По старту системы я считываю основной файл и проверяю его контрольную сумму. Если совпало — работаем. Если нет — эту пару удаляем и проверяем копию. Ну и классическое решение задачи — зеркальный RAID массив А вообще все упирается в ценность спасаемых данных. В одной системе мы легко можем потерять базу, восстановить ее из чистого бэкапа и работать. А в другой не спасли ни упсы ни рейды. Экскаватор во дворе зацепил силовой кабель и серверная погибла. Правда в саппорте (вроде тогда еще Dell) сказали ничего не трогать, через неделю приехали специалисты и данные подняли.

суббота, 6 июля 2019 г.

Преобразование шрифта в массив

Посоветуйте, пожалуйста, утилиты (доступные для скачивания) для преобразования шрифта в заголовочный файл *.h с массивом, содержащим растр для всех нужных символов для использования во встраиваемых системах. Типа такого: Freescale Embedded GUI Converter Utility 2.0 (судя по всему, его так просто не скачать).


Ответ

Нашел ответ на stackoverflow. Предлагается использовать утилиту convert из imagemagick. Например команда:
convert -resize 7x13\! -font /Library/Fonts/Arial.ttf -pointsize 10 label:A A.xbm
генерирует побитовое представление буквы A:
#define A_width 7 #define A_height 13 static char A_bits[] = { 0x00, 0x00, 0x04, 0x0C, 0x0A, 0x0A, 0x1E, 0x1F, 0x11, 0x11, 0x00, 0x00, 0x00, };

вторник, 19 марта 2019 г.

JLink (flash load)/MDR32F1QI в Linux

Недавно занялся программированием Российского микроконтроллера MDR32F1QI. Проблем со сборкой не говоря уже про сам контроллер не возникло. Однако, вот уже месяц как прошиваю контроллер из Windows c помошью Keil'a или програмки из поставки отладочной платы, а отлаживаю в Linux/Eclipse/JLink V8. Поскажите пожалуйста что мне написать в makefile'e для прошивки моего соотечественника (как угодно, хоть бы и вне makefile'a отдельной утилитой). Пробовал вот такую строку: openocd -f target/1986ve1t.cfg -c init; reset halt; flash write_image erase $(RESULT).bin 0x00000000; reset run; shutdown В ответ получаю следующее: Open On-Chip Debugger 0.9.0 (2015-09-02-10:42) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Error: Debug adapter does not support any transports? Check config file order. Error: unable to select a session transport. Can't continue. shutdown command invoked reset: unknown terminal type halt Terminal type? Что за "terminal type" и что не нравится openocd? Имя файла конфигурации openocd (1986ве1т.cfg) изменено (русские буквы в названиях файлов понятны не всем вспомогательным утилитам)


Ответ

unknown terminal type halt выдаёт команда linux reset (см. man reset, ну не находит она терминала с именем halt). Точки с запятой в командной строке разделяют команды shell, поэтому так получилось.
По-видимому всё после -c следует заключить в апострофы:
openocd -f target/1986ve1t.cfg -c 'init; reset halt; flash write_image erase $(RESULT).bin 0x00000000; reset run; shutdown'

вторник, 6 ноября 2018 г.

Литература по Embedded [закрыт]

Доброго времени суток знатокам ! Я сам из Украины, закончил местный ВУЗ, и хочу уйти с головой в Embedded даже не смотря что это не перспективно и зарплаты значительно ниже от WEB-разработчиков, но так сложилось что не люблю я копаться в тоннах HTML-кода или JS просто WEB мне не по душе, мне нравиться работать на уровне ядра ОС и железячки. Вопрос таков, кто-нибуть знает толковую литературу по этой теме ? Искал про контроллеры ARM (с которыми хочу поработать) так либо всякий бред качаю, либо никто разумного ничего не написал, ничего про Embedded толкового не нашёл, может кто-то ещё что либо подскажет (в какую сторону двигаться, но только в Embedded направлении) ! Короче люди я буду ждать любой совет, ресурс, подсказку, направление, очень хочу всё это охватить, познать и поработать !!!


Ответ

Дружище поверь, ты будешь плеваться потом долго и упорно что не стал заниматься как я вебом, а ушел как я в железо. Для начала, Должен знать Си просто изумительно, asm по ходу будешь догонять, есть есть с++ знания. Если будешь знать что есть транзисторы и тп вообще прекрасно (разбираться в схеме) вообще прекрасно купи себе отладку недорогую, Например на LPC1111(14) Выглядит отладка так (http://im6-tub-ru.yandex.net/i?id=599861828-08-72&n=21 ) lpcexpresso. Прочитай даташит к процу и юзермануал, разберись, немного страниц 800 английским. Читай как работать с UART,SPI,I2C,RTC и другой периферией. На отладке есть термодатчик и еще что-то с чем можно повзаимодействовать. Покупай или дербань сотовые достовай из них дисплее ищи инфу и выводи что нибудь на экран. Если будет у тебя проц с USB, попробуй и в нем разобраться. Как поймешь что к чему, Купи получше проц и SWD или JTAG отладчик, GSM, GPS модули,SD карту, сделай например проект типа GPS маячек. Можешь попробовать проект реализовать на RTOS, и использовать многопоточность. К изучению как минимум http://books.tr200.ru/v.php?id=804485 Качай с сайтов примеры кода работы с периферией, смотри что к чему. Если тяжелой книга окажется, тогда уходи в RISC процессоры AVR или PIC(16)(24)

вторник, 16 октября 2018 г.

Виртуальная машина Java (или подобное), написанная на Java

Здравствуйте. Недавно начал изучать виртуальные машины. Возник такой вопрос. Есть некоторые VM, например, Monty, Squawk. Данные виртуальные машины частично или полностью написаны на Java. Вот эта фраза меня немного в тупик загнала. (В силу недостатка знаний или понимания, наверное). Есть у нас виртуальная машина, написанная на низкоуровневых языках относительно Java - C++, C, Assembler. Тут все ясно. Машина пишется для каждой платформы, привязываясь к железу на низкоуровневых языках, для того чтобы интерпретировать псевдокод (байткод) там, где установлена виртуальная машина. Таким образом достигается кроссплатформенность. То есть мы тратим ресурсы железа, для того чтобы поднять виртуальную машину на ней, а затем генерировать машинный код для платформы на этапе исполнения. Из-за того, что у нас есть промежуточный слой исполнение, программа, написанная на таких языках, проигрывает компилируемым языкам. Ну и собственно вопрос. Зачем писать виртуальную машину на основе другой, точнее внутри другой. Есть у нас Java VM на устройстве, зачем нужно добавлять еще один слой абстракции? Выходит, что мы пишем виртуальную машину на основе функционала, который нам предоставляет уже существующая ВМ на устройстве. То есть таким образом мы, во-первых, не можем сделать больше, чем предоставляет нам обрамляющая ВМ, к тому же используем дополнительные вычислительные ресурсы ЭВМ. Я правильно понимаю? Хорошо, можно предположить, что это удобно в некоторых случаях, когда не требуется весь функционал обрамляющей ВМ или же абстрагирование от реализации с целью упрощения написания кода. Конечно, если компьютер предоставляет ресурсы, то можно сделать так, и разница практически будет незаметна. НО обычно такие ВМ используются на мобильных, портативных устройствах. Где здесь логика? Зачем добавлять дополнительный слой, ладно если бы это было бесплатно относительно ресурсов, но ведь это ведет к большим затратам ресурсов, которых на мобильных устройствах и так очень мало. Пожалуйста, объясните идею и преимущества. Может быть, я просто что-то неправильно понимаю, поправьте, пожалуйста. Спасибо большое заранее.


Ответ

Squawk VM - не полностью написана на Java, а только часть. На вопрос, "зачем" это все существует, отвечает короткая статья в википедии: https://ru.wikipedia.org/wiki/Squawk. Я предполагаю, что Monty, которая также используется на мобильных устройствах, имеет тот же самый бэкграунд, что и squawk, только со своей спецификой.

суббота, 13 октября 2018 г.

Повреждение файлов при отключении питания и исключениях в процессах

Я занимаюсь разработкой автономных систем управления и анализа для тяжелой промышленности. Использую язык C (C99-C11). Очень беспокоит вопрос повреждения файлов и файловых систем, использующихся в Windows (Embedded, CE и пр.) при внезапном обесточивании или при жестком прерывании рабочего процесса/потока, например из-за исключения.
Хотелось бы разобраться в этом вопросе, достойной литературы по этой теме найти не удалось. Посоветуйте что-нибудь, желательно не на английском языке. Или, может быть, кто-нибудь сможет упрощенно объяснить следующее:
Ясное дело, если мы открыли файл и пишем в него, и в этот момент происходит отключение питание, или возникает фатальное исключение в одном из потоков процесса, то операция прерывается на полпути. Это практически гарантированно приводит к повреждению файла/файловой системы в том районе, где происходит работа.
Но ведь даже если мы не работаем с файлом, а в этот момент отключается питание, файл может быть поврежден из-за того, что ОС в фоновом режиме занимается дефрагментацией/индексацией. Это так? Есть ли гарантия, что после возврата управления в программу после функций fclose() или fwrite() данные гарантированно корректно занесены на носитель?
Например, ситуация:
Процесс имеет два потока, в одном потоке происходит сохранение данных в файл, а в другом возникает ситуация, после которой мы можем лишь завершить процесс. Например, посреди сложной логики malloc() вернул NULL, или отказало устройство, или еще что.
Я предполагал защитить файл критической секцией, и использовать эту же критическую секцию для инициации аварийного завершения. Тогда, предположительно, после того как работа с файлом закончится, критическая секция освободится, и второй поток сможет в нее зайти и вызвать abort() или аналогичную функцию планируемого жесткого прерывания процесса.
Проблема на мой взгляд в том, что даже после того, как мы сделали fopen() + fwrite() + fclose(), нет гарантий, что файл корректно сохранен, а не гуляет где-то в буферах, которые связаны с нашим процессом. И как контролируется процесс переноса данных из внутреннего промежуточного буфера-кэша жесткого диска на сам носитель?
Например, файл записан и закрыт, и даже процесс, который все это делал, уже закрыт. Но данные частично или полностью еще находятся во внутреннем буфере-кэше накопителя. Если в этот момент произойдет обрыв питания, то данные, я почти уверен, будут повреждены или уничтожены.
Как ОС отслеживает перед своим завершением факт того, что данные из буфера накопителя записаны окончательно?


Ответ

Но ведь даже если мы не работаем с файлом, а в этот момент отключается питание, файл может быть поврежден из-за того, что ОС в фоновом режиме занимается дефрагментацией/индексацией. Это так?
Во-первых, сомневаюсь, что драйвер самостоятельно будет дефрагментировать что-либо (хотя и не буду утверждать обратное), а отсутствие насущности проблемы фрагментации объясняется в первую очередь грамотными алгоритмами выбора блоков для хранения файлов.
А критические, неустранимые ошибки ФС в таких случаях — это практически невероятный сценарий (скажем, внезапный отказ HDD — куда более вероятен). Но повреждения данных (файлов) с которыми велась активная работа в момент отказа — штатная ситуация.
2) Есть ли гарантия, что после возврата управления в программу после функций fclose() или fwrite() данные гарантированно корректно занесены на носитель?
Нет.
fwrite () гарантирует только занесение данных в пользовательский буфер, но не гарантирует, что эти данные будут переданы ОС. Чтобы принудительно сбросить пользовательский буфер есть функция fflush (). При скоропостижной кончине процесса данные могут быть потеряны. fclose () и fflush () сбрасывают пользовательский буфер, но не гарантируют, что ОС передаст данные на носитель. Если процесс умрёт после их возврата, то изменения не потеряются, но они могут быть потеряны в случае внезапного отключения питания.
3) И как контролируется процесс переноса данных из внутреннего промежуточного буфера-кэша жесткого диска на сам носитель?
Для того чтобы гарантировать запись данных на диск средств Си недостаточно, необходимо пользоваться API ОС. В POSIX-системах (и в linux в частности) есть вызов fsync (). Он гарантирует, что вернёт управление (само собой без ошибки) только после того как данные физически попадут на диск и переживут внезапный отказ системы. В Win API аналогом FlushFileBuffers (), согласно документации он сбрасывает системные буферы, но, гарантирует ли сброс буферов самого HDD или нет, я не знаю.
Как ОС отслеживает перед своим завершением факт того, что данные из буфера накопителя записаны окончательно?
Просто посылает определённую команду HDD. Например, в ATA она так и называется, FLUSH CACHE, опкод E7h. (здесь должен быть ещё десяток оговорок, которые должны быть интересны только разработчикам драйверов)