« 2023年7月 | トップページ | 2023年9月 »

2023.08.24

交付申請の差し戻し対応に対する返答

事業再構築補助金に関して、昨日送った交付申請の差し戻し対応に対する返答が来ました

事務局の中の人はこの内容で審査をかけてくれようとしたのですが、審査のほうからどうしても相見積を要求されたということでした。話し方から想像すると、事務局の窓口の人が審査をしているのではなく、別の機関(中小企業診断士とかだろうか)に審査をお願いしているようでした。

事務局は書類の形式的な検査で、中身の実質的な審査は別の機関が担当しているようでした。(「これで審査に出してみます」という言い方)

私の事業再構築プランは自社で半導体テスタを作ってICを検査するということなのですが、他社の類似品の相見積を要求されたので、海外製のものの相見積とカタログを添付して送ったのですが、

・特電のは2340ピンで〇〇万円

・海外のは84ピンで〇〇万円

ということで、価格だけみて海外のほうが安いから作る必要ないじゃないか、と言われるということでした。

スペックがどうとか機能がどうという表を作ろうともしたのですが、専門外だとわかりにくくなるので一番単純な数字であるピン数だけに絞って比較したのですが、金額で比較して最安値を採択するという方針だそうです。なので、スペックや機能の表を付けてこれだけのことができるのに何円=だから特電が自社制作するのが一番安い、というストーリーにもっていかなければなりません。

交付申請の審査というものが完全に形骸化していますね。

あと、広告宣伝費。

ネットメディアの広告を出そうとしたのですが、やはり相見積を出してほしいとのことでした。

同一規模(顧客数)のネットメディアの広告を探してきて、価格を比較して、最安値であるからということで選ばなければならないとも言われました。それは無茶です。物品の購入じゃないのだから、最安値を選択するというのはおかしな話です。

ほとんど知られていないような謎の安いネットメディアのほうが見つかったら、そっちにしなければならなくなります。

 

事務局の人は事情を理解してくれているのですが、どうしても審査が通らないのでなんとかしてほしいということでした。

ここまで相見積にこだわる背景もなんとなくわかります。こういうプロジェクトや補助金で謎の厳しいルールがあるときには、だいたい過去に不正とか癒着とかがあったときです。

その時の審査をした人が責任を問われたり、理由書による随意契約をやめようということなったとかそういうことなんじゃないかと思います。相見積で最安値を機械的に選択するようにすれば、万が一不正があった場合でも審査した人は「知らなかった」で通せるから責任を問われなくなります。

展示会も同一規模・地域・面積で比較しなければならないと言われたのですが、これは別の展示会の価格表で通りました。

似たような広告の相見積を取るという意味のない作業と、絶対に採用されない相見積を取るという、業者に申し訳ない作業をしなければならないことでモーチベーションダダ下がりです。

重大なことが一つわかったのですが、現時点でも相見積は1つでよいということです。

| | コメント (0)

2023.08.23

事業再構築補助金の交付申請の差し戻し対応

交付申請の差し戻し対応の文章を作り、他社製品の見積書などを参考資料として添付し、申請しました。

Sasimodoshitaiou

海苔弁のところは具体的な業者名が入ります。

この文書に加えて見積書などを添付して送ー信ー!

 

| | コメント (0)

2023.08.22

事業再構築補助金(第6回)の交付申請差戻が来た

第6回事業再構築補助金の交付申請の結果がまだ来ないので、事務局に問い合わせてみました。

要点は3つ

Q1 審査状況は?

Q2 交付決定が長引いて事業期間が短くなった場合どうなる?

Q3 11月15日~17日に行われる展示会に出展した場合に経費にできるか?(採択日は2022年9月15日)

この件に関して明確な解答が得られました。

A1 審査は次の段階に進んでいる(複数の人が見ているらしい)

A2 もし交付決定が遅くなって事業期間が短くなってしまった場合は個別対応となる(救済措置はありそうだ!)

A3 展示会期間と事業期間が一部重なっている場合は不可。採択日から14カ月後は2023年11月14日になるので15日からの展示会はそもそも不可。

 

どうやら交付決定が遅くなって事業期間が延びればこの限りではないそうです。採択日から14カ月後よりも交付決定に記載された事業期間のほうが優先されるので、記載された事業期間が延びていれば11月15日からの展示会も経費にできそうです。EdgeTech+の出典料を経費にできる可能性はワンチャンありそうです。

  

夕方に事務局から電話が来ました。電話の内容は交付申請の差し戻しに関するものだったのですが、7つほど修正してほしいことがあるということでした。

① 別表1のエクセルのシートが新しいものがあるので、そっちを使ってほしい。

② 自社製品で半導体検査装置を作るとのことだが、他社で似たような類似品があればその相見積もりを作ってほしい

③ X線検査装置に相見積もりが必要

④ K社の検査機器と静電気対策機器を購入するが静電気対策機器が50万円を超えているので相見積が必要

⑤ ネットメディアの広告が50万円を超えているので相見積もりが必要

⑥ 展示会の出店料が50万円を超えているので相見積が必要

⑦ クラウドサービス利用料が見積と800円ちがっている。事業実施期間を書いてほしい。クラウドサービス利用料の価格表が添付されているが見積依頼がない。

ということでした。

ほとんどが相見積もりに関するものだったのですが、電話で即時反論しました。

② 世の中にないものを作っているわけであるから類似のものはない。しいていうなら半導体工場が導入する半導体検査装置があるが、値段が決まっているわけではなく相見積を取るためのいわゆる冷やかし行為はできない。

③ 理由書に書いたとおりX線検査装置はメーカー直販で購入しており同一商品では最安値である。事前に問い合わせた際には、相見積は同一商品を様々な購入ルートで購入する場合の最安価格を比較するものなので、他のX線検査装置と比較することは意味がない。

④ 区分が異なれば50万を超えていても相見積もりは不要であると、事前に問い合わせたときにそう聞いた

⑤⑥ 手引きによれば、建設費と機械設備には相見積は必要だが、広告宣伝費には相見積が必要とは書いていない。事前の問い合わせでもそう聞いた。そもそも展示会で相見積を取ることはおかしい。

⑦ もう面倒くさいのでクラウドサービス利用料は削除でいいや

と回答しました。

交付申請の状況はどうですかと聞いたら、すぐに差し戻し連絡が来たので、やはり、つっついてみるのは重要ですね。

 

| | コメント (0)

2023.08.21

eMMCを使う基板を設計してみた

eMMCというのがあります。簡単に言えばSDカードを表面実装のICにしたようなものだと思います。

昔はメーカーとNDAを結ばないと買えないしデータシートも見られなかったような気がするのですが、今見たら、Digikeyで小売りされていてデータシートもダウンロードできました。

eMMCの規格には100ピンのBGAと153ピンのBGAがあり、100ピンは14mm×18mm、153ピンは11.5mm×13mmです。両方ともほとんどのピンはNCピンで、信号や電源ピンはごくわずかです。

153ピンのほうがサイズが小さくてよいのですが、0.5mmピッチのBGAなので、各プリント基板メーカーの0.1mmルールでは作りにくいのも事実です。

下の図は、ZYNQの225ピン(0.8mm)と153ピンeMMC(0.5mm)を配置して配線してみたところです。

Emmc

ZYNQもかなりの狭ピッチですがeMMCはさらに狭ピッチであることがわかります。

| | コメント (0)

2023.08.14

Spartan-7ボード大量生産祭り

Spartan-7ボードを大量に生産しています。

Sp7x22_1

取り急ぎ22台作り、出荷です。

Sp7x22

| | コメント (0)

2023.08.12

特電Artix-7ボードのVivadoデザインを更新

Artix-7ボードのダウンロードページを更新しました。

サンプルプロジェクトの更新や、USB用APIの更新、それからPythonのサンプルプログラムをアップロードしました。

https://www.tokudenkairo.co.jp/art7/download.html

そのほかに、Vivadoのプロジェクトについても更新しました。

今まで公開していたプロジェクトはVivado 2016用だったので、さすがに古いままでした。2020までバージョンを上げることにしました。

しかしながら、Vivadoのプロジェクトというのはバージョンが異なるとアップデートしなければならず、バージョンアップはできるものの、バージョンダウンができないとか、バージョンをあまり急激に上げるとIPがエラーを起こしてしまうという問題がありました。すべてのVivadoバージョン用のプロジェクトを用意するのが理想なのですが、Vivadoのプロジェクトフォルダは数百MBytesあって圧縮しても数十MBはあるので、ファイルサイズが大変なことになります。

そこで、NahiVivaというツールを使って、Vivadoのプロジェクトを最小限の必須要素だけに減らすことにしました。

Vivadoのサンプルデザインなのですが、わずか5.4MByteのサイズしかありません。

Before_folder

それもそのはず。Vivadoのプロジェクトは入っておらず、その元になるHDLファイルやTCLファイルしかないのです。

このフォルダにあるcmdファイルを実行すると、Vivadoが起動してVivadoプロジェクトを再生してくれるというしくみになっています。

SETTINGS.TXTというファイルを開くと、

VIVADO_VERSION=2020.1

という行があるので、これをお好みのVivadoのバージョンに書き換えて、open_project_gui.cmdを実行してみてください。

百聞は一見に如かずなので、動作をぜひご覧ください。

 

| | コメント (0)

2023.08.11

ctypesを使ってPythonからバイナリデータをDLLに入出力する

WindowsのDLLには2種類あります。一つは昔から使われているCやC++のDLLで、もう一つは.NETとかで使われているDLLです。Pythonにはctypesというライブラリがあり、これを使うとCやC++のDLLを利用することができます。

今日はctypesを使って特電Artix-7ボードで使われているUSB3.0 APIをPythonからアクセスできるようにしてみました。

Artix7python

まず、ctypesを使ってDLLを読み込むには

import ctypes
fx3 = ctypes.WinDLL("./tkusbfx3.dll")

と書きます。PythonのファイルとDLLが同じディレクトリにある場合は./で相対パス指定しないといけないようです。

さて、CのDLLには「型」の情報が含まれていません。そこで、Pythonからアクセスするには引数の型と戻り値の型を指定してあげなければなりません。Pythonでは型は動的に付けられますが、ctypesにはc_uint16やc_uint32といった型が用意されているので、形無し言語が苦手な私のような人でも安心です。

このTKUSBFX3Openという関数は、開いたUSBデバイスのベンダIDやプロダクトID、デバイス名など複数の戻り値をポインタにいれて返してくるので、

bool  TKUSBFX3Open(int num, unsigned short *vid, unsigned short *pid, char *DeviceName, int MaxDevnameLength);

というプロトタイプ宣言なのですが、ここでいきなり難題にぶちあたりました。

CのDLLからポインタで書き込まれる戻り値をどうやって受け取ればいいのでしょうか?

文字列ポインタはc_char_pで受け取ればよいのはググればすぐにわかりますが、uint16の値をポインタ渡しで受け取る方法はなかなか見つかりません。

答えは、

fx3.TKUSBFX3Open.argtypes = (ctypes.c_int, ctypes.POINTER(ctypes.c_uint16), ctypes.POINTER(ctypes.c_uint16), ctypes.c_char_p, ctypes.c_int)
fx3.TKUSBFX3Open.restype = ctypes.c_bool

でした。

uint16 *で戻ってくる値は、ctypes.POINTER(ctypes.c_uint16)と書けばいいようです。

いちいちctypes.を付けるのが面倒なのですが、Python初心者なので詳しくはわかりませんが、importの代わりにfrom ctypes import *にすればPOINTER(c_uint16)と書けるのではないかと思います。

さて、この関数を呼び出してオープンする部分は、

vid = ctypes.c_uint16()
pid = ctypes.c_uint16()
buf = ctypes.create_string_buffer(100)
status = fx3.TKUSBFX3Open(index, vid, pid, buf, 100)

と書きます。

ctypesの中にあるc_uint16というクラスを使うことで明示的に型が指定できます。整数なのにわざわざクラスでコンストラクタを呼ばなければならないのが大げさな感じがしますが仕方がありません。それから、関数を呼び出すときに参照を取らなくてもよいのかもしれません。

そして、文字列を配列に格納して返す関数を呼び出すには、create_string_buffer(100)というのを使って配列を用意しておきます。これはchar *型のmallocに相当するものだと理解しています。DLLで文字列を操作することはよくあるのでcreate_string_bufferはよく使うことになるのかなと思います。

create_string_bufferを使えばmallocみたいなことができるので、文字列以外にもなんでも使えるのではないかと思ったのですが、どうやらこれはc_char_pと一緒に使うらしいのです。c_char_pは\0で終わる文字列なので、バイナリのバッファで使うのはあまりよくないのではないかという気がしてきました。

USBに大量に大量のバイナリデータを送受信するようなアプリではどうすればよいかを考えてます。

int   USBWriteData(unsigned long addr, unsigned char *data, int len, unsigned short flag);

という関数があります。これをctypesを使って引数と戻り値の型を書くと、

fx3.USBWriteData.argtypes = (ctypes.c_uint32, ctypes.POINTER(ctypes.c_ubyte), ctypes.c_int, ctypes.c_uint16)
fx3.USBWriteData.restype = ctypes.c_int

になりました。

unsigned char * → POINTER(c_ubyte)

と変換すればよいようです。

送信するデータのバッファをcreate_string_bufferで作ると、mutableではないと言ってエラーになります。

初めて知ったのですが、Pythonでは変更できない変数やオブジェクトがあるようです。

変更可能なバイト列バッファを作るには

wbuf = bytearray(INOUT_BUFFER_SIZE) # ミュータブルなバイト配列
for i in range(length):
wbuf[i] = int(random.random() * 256)

としておきます。

そして、実際に送信するところでは、

fx3.USBWriteData(addr , (ctypes.c_ubyte * length).from_buffer(buf) , min(length,len(buf)) , flag)

とします。

ここで謎の記法が出てきました。

(ctypes.c_ubyte * len(wbuf)).from_buffer(wbuf)

とは何かということです。本当にPythonのことはよくわからないのですが、ctypes.c_ubyteの型がwbufの長さの分だけ並べた配列という新たな型を作っているようです。そして、そのオブジェクトを作る際に既存のbufを参照して使うということであるようです。

他にも、

(ctypes.c_ubyte * len(wbuf))(*wbuf)

という書き方をすることもできるのですが、wbufという配列の実体を作ってそれを(ctypes.c_ubyte * len(wbuf))にキャストするようなので、実行に非常に時間がかかります。16MBytesの配列で2秒くらいかかるようです。

Pythonartix7

だから、from_bufferを使うのがよいのでしょう。from_bufferを使えばC/C++で書いたのと同じ速さで送受信ができたので、おそらくデータのコピーは発生していません。

このような感じでArtix-7ボードのEZ-USB FX3をPythonからアクセスして、C/C++と同じ速度でデータの入出力ができるようになりました。

 

C/C++のときと比べて全く遜色のない速度が出ています。

Pythonartix72

いろいろ実験してみた結果ですが、

  • create_string_buffer はmutableではないので変更できない。そのためバイナリデータ(カメラ画像とか計測データ)の扱いには向いていない
  • バイナリデータを格納する配列自体はbytearrayで作るのがよい
  • バイナリな配列は (c_ubyte * 長さ).from_buffer(バイトアレイのバッファ) でキャストする
  • 関数の引数にポインタを与えて戻り値を受け取るには、
    uint16_t *  は POINTER(c_uint16)   に変換する
  • 関数の引数にポインタを与えてバイナリの配列を送受信する、
    uint16_t *  は POINTER(c_uint16)  に変換する
  • bytearrayで作ったバッファをbufとすると、uint8_t*配列に変換するには
    (c_ubyte * length).from_buffer(buf)
  • bytearrayで作ったバッファをbufとすると、uint16_t*配列に変換するには
    (c_uint16 * length).from_buffer(buf)
  • bytearrayで作ったバッファをbufとすると、uint32_t*配列に変換するには
    (c_uint32 * length).from_buffer(buf)
  • そもそもuint16配列 やuint32配列
    data 
    = (c_uint16 * length).from_buffer(bytearray(length * 2))
    で作ってしまってもよい。

ようです。

 

| | コメント (0)

2023.08.10

VisualC++でDLLを作るときのランタイムライブラリ/MT /MTd /MD /MDdの指定

長年リリースしていたした「特電Artix-7ボード用のEZ-USB FX3ライブラリ」をPythonで操作できるようにしようとしていたのですが、PythonのctypesでLoadLibraryをしようとしたらエラーが出てしまいました。

Pythonerror

エラーコードらしきものは

OSError: [WinError -529697949] Windows Error 0xe06d7363

と書かれています。

これが出る原因はDLLが読み込めないからなのですが、その原因としては、

  • DLLファイルがみつからない
  • 32bitのDLLを64bitのアプリから読もうとしていて何かがおかしい
  • 64bitのDLLを32bitのアプリから読もうとしている何かがおかしい
  • DLLが別のDLLを参照していて、その参照されるDLLが見つからない

が考えられます。たいていは参照されるDLLが見つからない場合です。

具体的に言うと、Visual C++でプロジェクトを作った場合、デフォルトの設定ではVisualC++のランタイムライブラリのDLLを読み込むように作られてしまいます。そのため、DLLだけを持ってきても開発に使ったPCと異なるPCではロードできないことがよくあります。

 

こんな基本的なことを忘れたまま、いくつかのプログラムを何年もリリースしっぱなしにしていました・・

 

他の人に使ってもらうプログラムやライブラリをリリースするならば、ランタイムを埋め込むのが一番です。

そのやり方を説明します。

Visual C++でプロジェクトを右クリックしてプロパティを出し、C/C++→コード生成→ランタイムライブラリを開きます。

Mtd

ここにあるマルチスレッド/MTとかいう設定で、DLLにライブラリを埋め込むかどうかを決定します。

まず、マルチスレッド/MTに設定した場合。出来上がったDLLをDependencyWalkerというツールで見てみると、kernel32.dllとSetupapi.dllとuser32.dllを参照していることがわかります。これは開発環境によらずにどのようなPCでもロードできるでしょう。DLLファイルのサイズは140kBくらいでした。

Mt

次に、マルチスレッドデバッグ/MTdを指定した場合。この場合も参照するのはシステムDLLだけなので問題ありません。ファイルのサイズは少し増えて386kByteになりました。

Mtd2

さて、マルチスレッドDLL/MD にした場合ですが、ファイルサイズは43kByteと小さくなったものの、VCRUNTIME140.dllを参照するようになってしまいました。DLLの中からVisual C++ランタイムの部分を省いてシステム共通のDLLを参照するようになったと考えればよいでしょう。また、sprintfなどを使っているのでapi-ms-win-crt-***というDLLも参照するようになりました。

Md

最後は、マルチスレッドデバッグDLL/MDd にした場合ですが、VCRUNTIME140D.dllを必要とするようになりました。ファイルサイズは46kByteくらいです。

Mdd

まとめると、

  • マルチスレッド/MT・・・デバッグ情報なし。ランタイムDLLは埋め込まれる
  • マルチスレッドデバッグ/MTd・・・デバッグ情報あり。ランタイムDLLは埋め込まれる
  • マルチスレッドDLL/MD・・・デバッグ情報なし。ランタイムDLLは別途必要となる
  • マルチスレッドデバッグDLL/MDd・・・デバッグ情報なし。ランタイムDLLは別途必要となる

VCRUNTIME140.dllやVCRUNTIME140D.dllを参照するDLLが出来てしまうと、Pythonや他のアプリから呼び出そうとしたりしたときにファイルが見つからないというエラーが出てしまいかねません。そうならないようにするには、 マルチスレッド/MT か、 マルチスレッドデバッグ/MTd を選択するようにしましょう。

 

| | コメント (0)

2023.08.01

CP2104の誤動作?ZYNQの誤動作?

U-Bootの起動中にHit any keyのところで勝手にキーが押されて(シリアルに文字が送られて)起動が止まってしまう問題で、進展がありました。

この現象が起きているときには、

common/autoboot.cの

static int abortboot_single_key(int bootdelay)

という関数がカウントダウンとキー入力を受け付けている関数なのですが、

if (tstc()) { /* we got a key press */
getchar(); /* consume input */
puts("\b\b\b 0");
abort = 1; /* don't auto boot */
}

というところであらかじめキーが押されていたかを判定しています。

しかし、この前に、

flush_stdin();

をしてもダメなのです。

flush_stdin()で入力バッファをフラッシュしているはずなのに、それでも謎の文字列が入力されてカウントダウンが止まってしまいます。

そこで、どのような文字列が入力されているかを調べてみたところ、

Buffer=65 bytes,[2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 3E EE 2E C9 C9 72 2E C9 F9 EE 3E F9 FF 7E FE FF FE 0A 0D 0A 0D 53 55 43 43 45 53 53 46 FF ]

Buffer=65 bytes,[2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E FE ]

Buffer=65 bytes,[2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 6D ]

Buffer=65 bytes,[2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 3E EE 2E C9 F9 EE 3E FF FF 0A 0D 0A 0D 53 55 43 43 45 53 53 46 55 4C 5F 48 41 4E 44 4F 46 C6 0D 0A 0D 0A 55 2D 42 6F 6F 74 20 3E 30 45 FA ]

Buffer=65 bytes,[2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 3E EE 2E C9 C9 72 3E C9 F9 72 FE EF 0A 0D 0A 0D 53 55 43 43 45 53 53 46 55 4C 5F 48 41 4E 44 4F 46 46 FF 0A 0D FF ]

という感じでした。2Eが多いのですが、2Dというのは.....(ピリオド)です。

そして、バッファは65バイトのことがおおく、中に文字列のようなものが見える場合があります。

この文字列を解読すると、SUCCESSFUL_HANDOFFと読めるではないですか!

しかも、0x0d 0x0aという改行の文字列まで見えます。

 

つまり、FSBLが送ったSUCCESSFUL_HANDOFFという文字列をCP2104が受信して、それを送信側に送り返してきている!???という謎の現象であることがわかりました。

 

回路図を見ながら徹底的にデバッグしていると、Cosmo-Z Mini2の新基板ではCP2104の電源をUSBから取ることにしているのですが、USBが挿さっていないとCP2104に電源が供給されない回路になっていました。

すると、CP2104のTX(CP2104からみた送信)ポートは常にLになりつづけてしまい、ZYNQのUART RXはLが与えられ続けられます。UARTでLは信号ありですから、ずっと00の信号が与えられているような形になります。オシロで見たところCP2104がエコーバックしているということはなかったのですが、ZYNQはなぜか送信データの一部を受信データとして解釈してしまうようで、それが原因でブート時のカウントダウンが止まってしまうようでした。

ただし、この現象が起きるZYNQは1つだけだったので個体差なのかもしれません。

基板のピンヘッダをジャンパして、USBが挿さっていなくてもCP2104に電源が供給されるようにしたところ、TXは起動時にHになり、問題はすべて解決しました。

 

| | コメント (0)

« 2023年7月 | トップページ | 2023年9月 »