Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ну , что прощаемся с Atmel ?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
Kopa
Цитата(zombi @ Oct 16 2015, 10:18) *
Что вы имеете ввиду?
Пишут на СИ как на асме, или на асме как на СИ?
Можете пример привести?

Тоже интересно.
Т.к. одно из свойтв С декларируемая близость к ассемблеру и умение пользоваться данной возможностью должна потенциально приводить к быстрому и эффективному коду.
Не зря же, возможно, бывают срачи вроде Pascal vs C sm.gif

P.S. Догадки: чрезмерное увлечение арифметикой указателей и обращение к переменной через взятие её адреса,, вместо операций сложения, инкрементирования применяются cдвиги, не использование структур данных, неумение пользоваться макро средствами языка, использование GOTO и неправильных выходов из функций? Что ещё может быть?

Цитата(zltigo @ Oct 16 2015, 10:42) *
Вы не сможете, увы, его понять. Си Вы не знаете, но считаете, что как два пальца об асфальт програмировать сможете и на нем.
Так как мы сможем обсужать язык, который Вы не знаете на сколь-либо приличном уровне?

С lдостаточно простой язык и нет в нём сакраментальных понятий вне понимания обычного программирования для человека хорошо знакомого даже с ассемблером.
Или Вы думаете что на ассемблере не пишется сложного кода и его макро возможности недостаточны для этого?
adnega
Цитата(Kopa @ Oct 16 2015, 10:50) *
Тоже интересно.

Пример можно было видеть тут.
ASM-стиль:
Цитата
DDR = 0x10;

Си-стиль:
Цитата
set_pin(PWM_PIN, 1);

Обращаю внимание, что обе строки написаны на Си.
Abell
Цитата(Kopa @ Oct 16 2015, 10:50) *
Что ещё может быть?

Типы данных sm.gif
adnega
Цитата(Kopa @ Oct 16 2015, 10:50) *
С достаточно простой язык и нет в нём сакраментальных понятий вне понимания обычного программирования для человека хорошо знакомого даже с ассемблером.

Не надо сравнивать алфавит и "Войну и мир")) Технически разницы не будет, а смысловая разница - огромная.
У каждого популярного языка программирования есть своя ниша, свой круг задач и свой дух.
Kopa
Цитата(zltigo @ Oct 16 2015, 10:42) *
. Пока я не улышал лично от Вас ни об одной Вашей форт разработке. Только все дежурные заявы с первой страницы сайта фирмочки продвигающей свой форт инструментарий. Так-что если кто-то и делал "телескопы" и "аэропорты", то это не Вы.

А гуглом Вы не умеете пользоваться, чтобы понять уровень владения инструментарием? Вроде достаточно некоторых "публикаций материалов" в сети,
а фрилансом я не занимаюсь.
adnega
Цитата(Abell @ Oct 16 2015, 10:59) *
Типы данных sm.gif

+1
Собственно, я долго писал на Си в asm-стиле, а потом открыл для себя типы данных - мир перевернулся, и теперь не код управляет данными, а данные кодом.
SpiritDance
Цитата(zombi @ Oct 16 2015, 02:33) *
Если не знаешь СИ, то ты уже и не программист вовсе. biggrin.gif


Программист конечно, но в большинстве случаев в нынешнее время профнепригодный.

Цитата(zombi @ Oct 16 2015, 02:33) *
Если Вы профессионал, то должны прекрасно понимать что освоить СИ или любой другой язык высокого уровня человеку пишущему на ассемблере пара пустяков.


Освоить можно. А вот чтобы владеть на достойном уровне - нужен опыт.


Цитата(zltigo @ Oct 16 2015, 10:52) *
На любом языке можно писать, как на ассемблере. Удручающе большое количество людей после ассемблера так и пишут. Только это является демонстрацией полной профнепригодности такого "программиста".


С Днем Рождения, кстати!
HHIMERA
- И кто будет нести гроб с Атмэлом со слезами на глазах?
- Асм, Форт, Васик и ДИП-корпус...
SpiritDance
Цитата(Kopa @ Oct 16 2015, 11:50) *
P.S. Догадки: чрезмерное увлечение арифметикой указателей и обращение к переменной через взятие её адреса,, вместо операций сложения, инкрементирования применяются cдвиги, не использование структур данных, неумение пользоваться макро средствами языка, использование GOTO и неправильных выходов из функций? Что ещё может быть?


Неумение отвязываться от железа и использовать абстракции, неумение проектировать внятную структуру приложения, увлечение оптимизацией - неумение полагаться на оптимизатор и писать понятный код. Например.
zombi
Цитата(adnega @ Oct 16 2015, 10:57) *
ASM-стиль:
DDR = 0x10;
Си-стиль:
set_pin(PWM_PIN, 1);

Пример не удачный.
К СИ или АСМ это не имеет никакого отношения.
Вы привели два стиля программирования.
Второй более наглядный и удобный.
Точно также эти две строки можно и асме написать.
Kopa
Цитата(zltigo @ Oct 16 2015, 10:42) *
Никакой дискриминации. Вопрос ПРЕЖДЕ всего в возможности работы в команде. Под Вас, как носителя форта, или носителя суахили, никто не будет подстраиватся. Такова жизненая реальность.

Жизненная реальность такова, что даже владеющие одним языком могут существенно различаться в способах и стилях его применения даже не считая дополнительных абстракций как ОС, автоматы, объектность и др. И есть большая вероятность что поддерживать код следующий программист станет с переписывания "кривых мест по его мнению" от предыдущего программиста. Не все же способны понять "Войну и мир" как понимал её автор, если это всё же возможно.

P.S. А работодателя, прежде всего, интересует результат, а не то какие средства выбрал для достижения его профессионал (если это действительно профессионал)
Ассемблер в ряду таких же средств, как и другие инструменты.
У "менеджеров", конечно, управляющими программистами несколько иная точка зрения на это и индивидуальные предпочтения в разработке они стараются убрать в принципе.
т.к. это им дополнительный "головняк" по работе.
zombi
Цитата(adnega @ Oct 16 2015, 11:05) *
+1
Собственно, я долго писал на Си в asm-стиле, а потом открыл для себя типы данных - мир перевернулся, и теперь не код управляет данными, а данные кодом.

biggrin.gif По Вашему типы данных есть только у языков высокого уровня?
HHIMERA
Цитата(Kopa @ Oct 16 2015, 11:28) *
работодателя, прежде всего, интересует результат, а не то какие средства выбрал для достижения его профессионал (если это действительно профессионал)
Ассемблер в ряду таких же средств, как и другие инструменты.

Угу... щазз... Перепишите чужой АСМ-исходник... если исходник без коментов... слабо??? biggrin.gif
SpiritDance
Цитата(zombi @ Oct 16 2015, 12:27) *
Пример не удачный.


Вполне удачный.

Цитата(zombi @ Oct 16 2015, 12:27) *
Вы привели два стиля программирования.
Второй более наглядный и удобный.


Которым матерые ассемблерщики обычно не пользуются.


HHIMERA
Цитата(zombi @ Oct 16 2015, 11:31) *
biggrin.gif По Вашему типы данных есть только у языков высокого уровня?

Вы не видите суслика??? В АСМе есть флоат... или дабле???
zombi
Цитата(SpiritDance @ Oct 16 2015, 11:35) *
Которым матерые ассемблерщики обычно не пользуются.

Матёрые как раз и пользуются.
Не пользуются начинающие.
adnega
Цитата(zombi @ Oct 16 2015, 10:18) *
Пишут на СИ как на асме, или на асме как на СИ?
Можете пример привести?



Цитата(zombi @ Oct 16 2015, 11:27) *
Пример не удачный.
Вы привели два стиля программирования.
Точно также эти две строки можно и асме написать.

Вы читаете то, что сами пишете и пишут вам в ответ?
Утверждалось, что на одном языке можно программировать в духе другого языка.
Вы попросили пример. Вам его привели. Вы утверждаете, что это "два стиля программирования" - да, в этом и был смысл примера.
Почему же вы его называете неудачным?
zombi
Цитата(HHIMERA @ Oct 16 2015, 11:36) *
Вы не видите суслика??? В АСМе есть флоат... или дабле???

ЛЮБЫЕ которые мне нужны могу сделать.
SpiritDance
Цитата(Kopa @ Oct 16 2015, 12:28) *
P.S. А работодателя, прежде всего, интересует результат, а не то какие средства выбрал для достижения его профессионал (если это действительно профессионал)


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


Цитата(zombi @ Oct 16 2015, 12:38) *
Матёрые как раз и пользуются.
Не пользуются начинающие.



А по приведенному примеру этого что-то и не заметно sm.gif
zombi
Цитата(adnega @ Oct 16 2015, 11:38) *
Почему же вы его называете неудачным?

Потому что не наглядный стиль программирования вы приписываете ассемблеру.
SpiritDance
Цитата(zombi @ Oct 16 2015, 12:39) *
ЛЮБЫЕ которые мне нужны могу сделать.


Это абстракция в голове программиста, а не свойство языка.
Abell
Цитата(SpiritDance @ Oct 16 2015, 11:25) *
Неумение отвязываться от железа

Извиняюсь спросить - а для программиста это обязательное умение? Может, не стоит совсем-то от железа отвязываться, хотя бы в этой теме, а то будет как не помню у кого в подписи о цели программиста - "намагнитить участки поверхности быстро вращающихся дисков" biggrin.gif
Просто я больше как раз "железячник", и программный код для меня, скажем так, вторичен. И если к устройству, имеющему дискретных 8 входов и 4 выхода, программист потребует 32-х разрядный МК в корпусе BGA с мегабайтами флэша на борту, не меньше 40МГц тактовой, среду разработки на языке высочайшего уровня стоимостью несколько сотен килорублей и двухпроцессорный комп для симуляции - у меня возникнут подозрения не только в профпригодности, но и психическом здоровье такого специалиста.
Или, например, фразы типа "какую операционку лучше поставить на микроволновку", "разработать GUI для карандашной точилки".
С другой стороны, с программиста, обслуживающего базу данных бухгалтерии, требовать знания ассемблера - глупость другой степени крайности laughing.gif
adnega
Цитата(zombi @ Oct 16 2015, 11:31) *
biggrin.gif По Вашему типы данных есть только у языков высокого уровня?

Конечно нет. Но ими никто не пользуется.
Есть массив структур:
Код
typedef struct sRS485_MASTER_TASK
{
    BYTE    task:2;
    BYTE    flag:1;
    BYTE    address:5;
    BYTE    source;
    WORD    index;
} sRS485_MASTER_TASK;

Покажете как им пользоваться на asm?
Напишите аналог функции rs485_task_add?
CODE
void rs485_task_add(sCONFIG_ITEM item)
{
int i;

#ifdef DEBUG_RS485_TASK
con_str("rs485_task_add");
con_start();
#endif // DEBUG_RS485_TASK

if(item.driver == DRV_RS485_MASTER)
{
for(i = 0; i < RS485_MASTER_TASK_SIZE; i++)
{
if((rs485_master_task[i].task == item.rs485_task)
&& (rs485_master_task[i].source == item.source)
&& (rs485_master_task[i].index == item.index)
&& (rs485_master_task[i].address == item.id)
)
{
#ifdef DEBUG_RS485_TASK
con_str(" @ ");
con_dec(i);
con_str("\n\r");
con_start();
#endif // DEBUG_RS485_TASK

rs485_master_task[i].flag = 0;
return;
}
}

if(i == RS485_MASTER_TASK_SIZE)
{
for(i = 0; i < RS485_MASTER_TASK_SIZE; i++)
{
if(rs485_master_task[i].task == RS485_TASK_OFF)
{
#ifdef DEBUG_RS485_TASK
con_str(" new ");
con_dec(i);
con_str("\n\r");
con_start();
#endif // DEBUG_RS485_TASK

rs485_master_task[i].task = item.rs485_task;
rs485_master_task[i].source = item.source;
rs485_master_task[i].index = item.index;
rs485_master_task[i].address = item.id;
rs485_master_task[i].flag = 0;
return;
}
}
}
}
}

Только прошу учесть, что завтра я (может быть) поменяю тип на такой:
Код
typedef struct sRS485_MASTER_TASK
{
    DWORD    task;
    DWORD    flag;
    DWORD    address;
    DWORD    source;
    DWORD    index;
} sRS485_MASTER_TASK;

Перекомпиляции будет достаточно или нужно шерстить весь код на предмет работы с данным типом?
Kopa
Цитата(HHIMERA @ Oct 16 2015, 11:34) *
Угу... щазз... Перепишите чужой АСМ-исходник... если исходник без коментов... слабо??? biggrin.gif

Отчего же?
Но без знания метрик повторяемого решения это может быть трудно осуществимо если утерян "пласт" метаинформации на основе знаний которой делалось решение.
А "механический" перенос возможен даже и в этом случае, хотя он и не тривиален. sm.gif Есть даже личный какой то опыт в этом.
Качество решения и необходимые инструментарии для этого можно себе сделать или закупить существующие (АSM -> псевдо C есть например в IDA и др))
SpiritDance
Цитата(HHIMERA @ Oct 16 2015, 12:34) *
Угу... щазз... Перепишите чужой АСМ-исходник... если исходник без коментов... слабо??? biggrin.gif


Речь как всегда про размер исходников. Несколько мегабайт ассемблера, например, не рискнет переписать даже автор. Выкинуть и переделать все с нуля будет проще.
adnega
Цитата(zombi @ Oct 16 2015, 11:39) *
ЛЮБЫЕ которые мне нужны могу сделать.

Пацан сказал - пацан сделал...?
HHIMERA
Цитата(Kopa @ Oct 16 2015, 11:50) *
Отчего же?
Но без знания метрик повторяемого решения это может быть трудно осуществимо если утерян "пласт" метаинформации на основе знаний которой делалось решение.
А "механический" перенос возможен даже и в этом случае, хотя он и не тривиален. sm.gif Есть даже личный какой то опыт в этом.

Забыл добавить... с АВР-АСМа на АРМ-АСМ... biggrin.gif
chu
Цитата(SpiritDance @ Oct 16 2015, 15:25) *
использовать абстракции
сферический конь в вакууме - наше фсё
Kopa
Цитата(HHIMERA @ Oct 16 2015, 11:55) *
Забыл добавить... с АВР-АСМа на АРМ-АСМ... biggrin.gif

Это, как может показаться ни парадоксальным, гораздо проще!
Примеры этому, например, динамическая трансляция кода, реализованные разные эмуляторы ...
У производителей сериных изделий такие решения встречались чтобы не переписывать АSM (например так поступил HP для выпуска своих очередных калькуляторов на ARM процессоре HP48? вместо ранее применяемого своего и при этом тактовая частота ARM была ограничена на величине ~70 МГц )

P.S. Хотя, в общем виде, решение данной задачи может потребовать "изобретения" ноу-хау если это действительно того стоит. sm.gif
zombi
Цитата(adnega @ Oct 16 2015, 11:50) *
Напишите аналог функции rs485_task_add?
Только прошу учесть, что завтра я (может быть) поменяю тип на такой:

Ну да, изменение размерности переменных на асме выполнить сложнее.
Я как правило выбираю тип для каждой переменной изначально и стараюсь в дальнейшем её не менять.
Если Вам часто нужно менять размерность, то может вы на начальном этапе что то не предусмотрели.
zltigo
QUOTE (zombi @ Oct 16 2015, 10:48) *
Бла бла бла. Как всегда.

Когда человк, как в данном случае Вы, не имеет достаточного уровня для понимания. то тогда, конечно, для него все, что превышает уровень его понимания это действительно "Бла бла бла".

SpiritDance
Цитата(Abell @ Oct 16 2015, 12:49) *
Извиняюсь спросить - а для программиста это обязательное умение?


На практике- необходимое.

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

А так как на разработку ПО уходит гораздо большая часть времени и сил, нежели для разработки схемы, то без отвязывания от конкретного железа - часто становиться грустно.

Цитата(Abell @ Oct 16 2015, 12:49) *
Просто я больше как раз "железячник", и программный код для меня, скажем так, вторичен.


Это возможно только из-за того, что его очень мало. Кода.

Цитата(Abell @ Oct 16 2015, 12:49) *
И если к устройству, имеющему дискретных 8 входов и 4 выхода, программист потребует 32-х разрядный МК в корпусе BGA с мегабайтами флэша на борту, не меньше 40МГц тактовой, среду разработки на языке высочайшего уровня стоимостью несколько сотен килорублей и двухпроцессорный комп для симуляции - у меня возникнут подозрения не только в профпригодности, но и психическом здоровье такого специалиста.


Вы придумали себе в голове картину убиения мухи из РСЗО и с этой картиной сражаетесь. А между тем эта картина не имеет с отвязкой алгоритмов от железа ничего общего.
chu
Цитата(zltigo @ Oct 16 2015, 16:07) *
Когда человк, как в данном случае Вы, не имеет достаточного уровня для понимания. то тогда, конечно, для него все, что превышает уровень его понимания это действительно "Бла бла бла".

Очень точно характеризует Ваше отношение к Forth.
adnega
Цитата(zombi @ Oct 16 2015, 12:05) *
Ну да, изменение размерности переменных на асме выполнить сложнее.
Я как правило выбираю тип для каждой переменной изначально и стараюсь в дальнейшем её не менять.

Все понятно. Это я и понимал под отсутствием типов данных.
Хотелось бы увидеть пример изменения размерности данных пусть и очень сложный в реализации.
Есть мнение, что это невозможно.
SpiritDance
Цитата(HHIMERA @ Oct 16 2015, 12:55) *
Забыл добавить... с АВР-АСМа на АРМ-АСМ... biggrin.gif


Конкретно сейчас решаю перенос немалого проекта с coldfire на kinetis

Если б там не было некого, пусть местами сильно криво написанного, hal я бы наверно спился (искал бы другую работу конечно, но пусть будет "спился" sm.gif )

[
zombi
Цитата(zltigo @ Oct 16 2015, 12:07) *
Когда человк, как в данном случае Вы, не имеет достаточного уровня для понимания. то тогда, конечно, для него все, что превышает уровень его понимания это действительно "Бла бла бла".

Да понял я Вас уже. Не утруждайте себя повторными "Бла бла бла".
adnega
Началось?
Kopa
Цитата(chu @ Oct 16 2015, 12:10) *
Очень точно характеризует Ваше отношение к Forth.

+1

zombi
Цитата(adnega @ Oct 16 2015, 12:11) *
Есть мнение, что это невозможно.

Такое мнение ошибочно.
SpiritDance
Цитата(adnega @ Oct 16 2015, 13:11) *
Все понятно. Это я и понимал под отсутствием типов данных.
Хотелось бы увидеть пример изменения размерности данных пусть и очень сложный в реализации.
Есть мнение, что это невозможно.


Возможно, только на макроассемблере весьма трудоемко.


[sarcasm] Для этого придется изобразить компилятор C [/sarcasm]
HHIMERA
Цитата(Abell @ Oct 16 2015, 11:49) *
Просто я больше как раз "железячник", и программный код для меня, скажем так, вторичен. И если к устройству, имеющему дискретных 8 входов и 4 выхода, программист потребует 32-х разрядный МК

И что??? Я тоже железячник... я знаю что и как может разное железо... Накой мне лепить унылую Мегу... если я возьму копеечный 030-й... который легко, не напрягаясь... половину функций будет молотить хардварно... обслуживая ещё целый ряд полезных плюшек... которые Меге просто противопоказаны...
Abell
Цитата(SpiritDance @ Oct 16 2015, 12:09) *
Типичная проблема жизни удачного изделия - перенос наработанного функционала на новое железо. По причине исчерпания аппаратных возможностей, устаревания элементной базы, удешевления себестоимости, переориентации на новых поставщиков... да чего угодно.

Уважаемый, КМК, типичная проблема жизни современного удачного изделия с микроконтроллерами на борту - постоянные обновления "прошивок". То есть, железо одно и то же, а "наработанный функционал" превращается в миф, откровенный брак и заплаты на ходу. Поэтому про исчерпание аппаратных возможностей мне не заливайте.
Про устаревание элементной базы тоже не надо - как это для "наработанного функционала" раньше хватало базы, а теперь вдруг нет, это что - история Винды, переписанная для микроконтроллера?
Насчет удешевления и переориентации согласился бы, да не верится laughing.gif
zltigo
QUOTE (Kopa @ Oct 16 2015, 10:50) *
Или Вы думаете что на ассемблере не пишется сложного кода и его макро возможности недостаточны для этого?

Я не думаю совершенно. Я знаю на своей шкуре, что такое сложный код на ассемблере. Я отлично владею тремя ассемблерами и перфектно ASM 80286->486, на котором мною была написана операционная система и виртуальная машина. Причем ассемблер борландовский в режиме поддержки Ideal Mode, действительно с весьма продвинутыми в сторону языков высокого уровня надстройками. Большинству ASM до такого и сейчас не дотянуться. Объем кода - более 300K. По этой причине, я так-же великолепно понимаю, что писать это на ASM было только по причине отсутствия в 1990 году сколь-нибудь приличных компиляторов и невозможности в те-же времена использовать что либо мощнее i80286 12MHz.

adnega
Цитата(zombi @ Oct 16 2015, 12:17) *
Такое мнение ошибочно.

Есть конкретный пример. Приведите пожалуйста реализацию. Пусть и очень сложную.
Если Вы не можете этого сделать, не является ли это определением "невозможности"?
Пусть и в узком смысле "невозможно для программистов вашего уровня".
Kopa
Цитата(SpiritDance @ Oct 16 2015, 12:21) *
Возможно, только на макроассемблере весьма трудоемко.

Да, однозначно возможно, но понимания данной реализации может не хватить для конретного индивидумама sm.gif
Пример: в проекте HiAsm есть некоторая реализация пакета для генерации кода по схеме HiAsm на FASM,
так вот уровень способа реализации абстракции для составления необходимых базовых компонентов там "запредельный" и сравним c 'высшей математикой" использования макросредств FASM ассемблера! Почти чистая ООП на макросредствах.
zltigo
QUOTE (Kopa @ Oct 16 2015, 11:04) *
А гуглом Вы не умеете пользоваться, чтобы понять уровень владения инструментарием? Вроде достаточно некоторых "публикаций материалов" в сети,
а фрилансом я не занимаюсь.

Умею. Но буду благодарен, если вы поддвердите свое авторство хоть в одном их проектов о которых так настойчиво говорите. Это хоть неменого изменит мое отношение к Вам - гики собравшиеся в команду уже таковыми в общем-то и не являются. Но пока, повторю, я вижу в Вас гика одиночку.
zombi
Цитата(adnega @ Oct 16 2015, 12:27) *
Есть конкретный пример. Приведите пожалуйста реализацию. Пусть и очень сложную.
Если Вы не можете этого сделать, не является ли это определением "невозможности"?
Пусть и в узком смысле "невозможно для программистов вашего уровня".

Что Вы хотите увидеть?
Резервирование в RAM другого количества байт и замены всех вызываемых подпрограмм для которых в качестве аргумента выступает изменяемая переменная?
chu
только что T1 — дискретный 8-битный DIY компьютер
HHIMERA
Цитата(Abell @ Oct 16 2015, 12:22) *
про исчерпание аппаратных возможностей мне не заливайте.
Про устаревание элементной базы тоже не надо - как это для "наработанного функционала" раньше хватало базы, а теперь вдруг нет

Акститесь!!! Время на месте не стоит... Вы же железячник... сравните возможности крутой Меги32 и порезанного STM32F0xx... Не можете??? Тогда о чём разговор???
Kopa
Цитата(zltigo @ Oct 16 2015, 12:31) *
Умею. Но буду благодарен, если вы поддвердите свое авторство хоть в одном их проектов о которых так настойчиво говорите. Это хоть неменого изменит мое отношение к Вам - гики собравшиеся в команду уже таковыми в общем-то и не являются. Но пока, повторю, я вижу в Вас гика одиночку.

О каких проектах или разработках речь?
И Ваше мнение к моей персоне меня АБСОЛЮТНО не волнует! т.к. из диалога с Вами не получается сделать какой то полезный "конструктив".

P.S. Не вижу для себя ничего уничижительного в гике-одиночке sm.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.