SAE J1939を開きます
SAE J1939は、トラクター、機械、トラックなどの産業用車両に適した特定の方法で缶バスメッセージを形作るためのプロトコルです。
SAE J1939は非常に簡単なプロトコルですが、Protocolドキュメントのコストにより、SAE J1939に関する情報が不足しており、SAE J1939プロトコル標準に従って缶バスメッセージを形作る方法が利用可能です。したがって、STM32、Arduino、AVR、PICなどの埋め込みシステムで無料で使用できるSAE J1939プロトコルを書いています。
このプロジェクトに基づいて構築することを学ぶには、まずSAE J1939を理解する必要があります。 Cは業界標準であるため、このプロジェクトをC言語で書いています。私が選んだC言語方言はANSI C (C89)であり、このライブラリで動的メモリ割り当ては使用しません。したがって、 MISRA C Standardで動作します。
このライブラリを使用すると、バルブ、エンジン、アクチュエータ、機械、ハードウェアなど、重い産業モバイルアプリケーションに適したすべてのものと通信できます。 SAE J1939が巨大な標準であるため、プロジェクトの基本構造を構築しCた。
組み込みシステム用のC Canopenライブラリをお探しですか? https://github.com/danielmartensson/easy-canopen
USBでOpen SAE J1939を使用するC ++ GUIフレームワークをお探しですか? https://github.com/danielmartensson/goobysoft
Open SAE J1939を使用したC STM32プロジェクトをお探しですか? https://github.com/danielmartensson/stm32-plc
はじめる
最初に知っておく必要があるのは、 Documentationフォルダー内のOpen SAE J1939の私自身のPDFドキュメントを読むことです。プロジェクトの構造を学びます。そうでなければ、SAE J1939を理解できません。プロジェクトを基本的に理解した後、それを構築することができます。シンプルに保ち、SAE J1939標準に従ってください!
プロジェクトの構造を理解したら、 Hardware -> Hardware.hファイルでプロセッサの選択を選択します。ここでは、 STM32 、 Arduino 、 PIC 、 AVRなどを選択するか、最初にPCで実行する場合は、 PROCESSOR_CHOICE 0を選択して例を実行します。これが、内部缶フィードバックのデバッグモードです。
プロジェクトの使用方法
- ステップ1:このリポジトリをダウンロードします
- ステップ2:
Hardware -> Hardware.hに移動してプロセッサを選択してください。利用できない場合は、コードを書き込み、プルリクエストを送信してください - ステップ3:
SrcフォルダーをIDE内のプロジェクトフォルダーにコピーします。 SrcたとえばOpen SAE J1939に変更します。それは良い名前です。 - ステップ4:
Examples -> Open SAE J1939 -> Main.txt例は、SAE J1939プロジェクトの最初の開始コードとしての例です。
/*
* Main.c
*
* Created on: 16 juli 2021
* Author: Daniel Mårtensson
*/
#include <stdio.h>
/* Include Open SAE J1939 */
#include "Open_SAE_J1939/Open_SAE_J1939.h"
/* Include ISO 11783 */
#include "ISO_11783/ISO_11783-7_Application_Layer/Application_Layer.h"
void Callback_Function_Send ( uint32_t ID , uint8_t DLC , uint8_t data []) {
/* Apply your transmit layer here, e.g:
* uint32_t TxMailbox;
* static CAN_HandleTypeDef can_handler;
* This function transmit ID, DLC and data[] as the CAN-message.
* HardWareLayerCAN_TX(&can_handler, ID, DLC, data, &TxMailbox);
*
* You can use TCP/IP, USB, CAN etc. as hardware layers for SAE J1939
*/
}
void Callback_Function_Read ( uint32_t * ID , uint8_t data [], bool * is_new_data ) {
/* Apply your receive layer here, e.g:
* CAN_RxHeaderTypeDef rxHeader = {0};
* static CAN_HandleTypeDef can_handler;
* This function read CAN RX and give the data to ID and data[] as the CAN-message.
* if (HardWareLayerCAN_RX(can_handler, &rxHeader, ID, data) == STATUS_OK){
* *is_new_data = true;
* }
*
* You can use TCP/IP, USB, CAN etc. as hardware layers for SAE J1939
*/
}
/* This function reads the CAN traffic */
void Callback_Function_Traffic ( uint32_t ID , uint8_t DLC , uint8_t data [], bool is_TX ) {
/* Print if it is TX or RX */
printf ( "%st" , is_TX ? "TX" : "RX" );
/* Print ID as hex */
printf ( "%08Xt" , ID );
/* Print the data */
uint8_t i ;
for ( i = 0U ; i < DLC ; i ++ ) {
printf ( "%Xt" , data [ i ]);
}
/* Print the non-data */
for ( i = DLC ; i < 8U ; i ++ ) {
printf ( "%Xt" , 0U );
}
/* New line */
printf ( "n" );
}
/* Apply your delay here */
void Callback_Function_Delay ( uint8_t delay ){
/* Place your hardware delay here e.g HAL_Delay(delay); for STM32 */
}
int main () {
/* Create our J1939 structure */
J1939 j1939 = { 0 };
/*
* Callbacks can be used if you want to pass a specific CAN-function into the hardware layer.
* All you need to do is to enable INTERNAL_CALLLBACK inside hardware.h
* If you don't want to have the traffic callback, just set the argument as NULL.
* If you don't want any callback at all, you can write your own hardware layer by selecting a specific processor choice at hardware.h
*/
CAN_Set_Callback_Functions ( Callback_Function_Send , Callback_Function_Read , Callback_Function_Traffic , Callback_Function_Delay );
/* Load your ECU information */
Open_SAE_J1939_Startup_ECU ( & j1939 );
/* SAE J1939 process */
bool run = true;
while ( run ) {
/* Read incoming messages */
Open_SAE_J1939_Listen_For_Messages ( & j1939 );
/* Your application code here */
}
/* Save your ECU information */
Open_SAE_J1939_Closedown_ECU ( & j1939 );
return 0 ;
} Examples -> SAE J1939 ECUの住所、名前、または識別を変更する方法。
プロジェクトの構造
オープンSAE J1939の構造がどのように行われるか作業例
CODEのこのフローチャートは、SAE J1939ライブラリがどのように機能しているか。この例は、リクエストを送信して回答を得る方法を示しています。
- ステップ1:
ECU XはPGN ECU Yに送信します。 PGN関数コードとして解釈します。 | enum_j1939_status_codes sae_j1939_send_request_ecu_identification ( j1939 * j1939 、 uint8_t da ){ |
| return sae_j1939_send_request ( j1939 、 da 、 pgn_ecu_identification ); |
| } |
- ステップ2:
ECU Y 、 ECU XからのそのPGNメッセージを読み取ります。 | bool is_new_message = can_read_message ( & id 、 data ); |
| if ( is_new_message ){ |
| / *最新の保存 */ |
| J1939- > id = id ; |
| memcpy ( J1939- >データ、データ、 8 ); |
| J1939- > id_and_data_is_updated = true; |
| |
| uint8_t id0 = id >> 24 ; |
| uint8_t id1 = id >> 16 ; |
| uint8_t da = id >> 8 ; /*このECUである宛先アドレス。 DA = 0xff =すべてのECUにブロードキャストの場合。時々daはID番号にもなります */ |
| uint8_t sa = id ; / * ECUのソースアドレスは、 */からメッセージを受け取った |
| |
| / *他のecuからのリクエストを読む */ |
| if ( id0 == 0x18 && id1 == 0xea && ( da == j1939- > information_this_ecu。this_ecu_address || da == 0xff ) { |
| SAE_J1939_READ_REQUEST ( J1939 、 SA 、データ); |
- ステップ3:
PGN関数コードはECU Yによって解釈されます。 | void sae_j1939_read_request ( j1939 * j1939 、 uint8_t sa 、 uint8_t data []){ |
| uint32_t pgn = ( data [ 2 ] << 16 )| (データ[ 1 ] << 8 )|データ[ 0 ]; |
| if ( pgn == pgn_acknowledgement ){ |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 、 SA 、 CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED 、 GROUP_FUNCTION_VALUE_NORMAL 、 PGN ); |
| } else if ( pgn == pgn_address_claided ){ |
| sae_j1939_response_request_address_claimed ( j1939 ); |
| } else if ( pgn == pgn_commanded_address ){ |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 、 SA 、 CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED 、 GROUP_FUNCTION_VALUE_NORMAL 、 PGN ); |
| } else if ( pgn == pgn_address_delete ){ |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 、 SA 、 CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED 、 GROUP_FUNCTION_VALUE_NORMAL 、 PGN ); / * SAE J1939標準ではない */ |
| } else if ( pgn == pgn_dm1 ){ |
| SAE_J1939_RESPONSE_REQUEST_DM1 ( J1939 、 SA ); |
| } else if ( pgn == pgn_dm2 ){ |
| SAE_J1939_RESPONSE_REQUEST_DM2 ( J1939 、 SA ); |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 、 SA 、 CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED 、 GROUP_FUNCTION_VALUE_NORMAL 、 PGN ); |
| } else if ( pgn == pgn_dm3 ){ |
| SAE_J1939_RESPONSE_REQUEST_DM3 ( J1939 、 SA ); |
| } else if ( pgn == pgn_request ){ |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 、 SA 、 CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED 、 GROUP_FUNCTION_VALUE_NORMAL 、 PGN ); |
| } else if ( pgn == pgn_tp_cm ){ |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 、 SA 、 CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED 、 GROUP_FUNCTION_VALUE_NORMAL 、 PGN ); |
| } else if ( pgn == pgn_tp_dt ){ |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 、 SA 、 CONTROL_BYTE_ACKNOWLEDGEMENT_PGN_SUPPORTED 、 GROUP_FUNCTION_VALUE_NORMAL 、 PGN ); |
| } else if ( pgn > = pgn_auxiliary_valve_estimated_flow_0 && pgn <= pgn_auxiliary_valve_estimated_flow_15 ){ |
| ISO_11783_RESPONSE_REQUEST_AUXILIARY_VALVE_ESTIMATED_FLOW ( J1939 、 PGN & 0XF ); / * pgn&0xf = valve_number */ |
| } else if ( pgn == pgn_general_purpose_valve_estimated_flow ){ |
| ISO_11783_RESPONSE_REQUEST_GENERAL_PURPOSE_VALVE_STIMATED_FLOW ( J1939 、 SA ); |
| } else if ( pgn > = pgn_auxiliary_valve_measured_position_0 && pgn <= pgn_auxiliary_valve_measured_position_15 ){ |
| ISO_11783_RESPONSE_REQUEST_AUXILIARY_VALVE_MEASURED_POSITION ( J1939 、 PGN & 0XF ); / * pgn&0xf = valve_number */ |
| } else if ( pgn == pgn_software_identification ){ |
| sae_j1939_response_request_software_identification ( j1939 、 sa ); |
| } else if ( pgn == pgn_ecu_identification ){ |
| sae_j1939_response_request_ecu_identification ( j1939 、 sa ); |
- ステップ4:
PGN関数コードは、 ECU YによるECU Identificationとして解釈されるようになりました。その後、 ECU YはECU IdentificationすべてのECUsにブロードキャストします。- ステップ4.1.1:1パッケージメッセージの場合、
ECU Y ECU Identificationブロードキャストします。 | enum_j1939_status_codes sae_j1939_response_request_ecu_identification ( j1939 * j1939 、 uint8_t da ){ |
| / *配列フィールドの長さを見つける */ |
| uint8_t length_of_each_field = j1939- > information_this_ecu 。 this_identifications 。 ecu_identification 。 length_of_each_field ; |
| if ( length_of_each_field < 2 ){ |
| / *各フィールドに長さ1の場合、通常のメッセージであるため、ECU識別を送信できます */ |
| uint32_t id = ( 0x18fdc5 << 8 )| J1939- > information_this_ecu 。 this_ecu_address ; |
| uint8_t data [ 8 ]; |
| データ[ 0 ] = J1939- > Information_This_ecu 。 this_identifications 。 ecu_identification 。 ECU_PART_NUMBER [ 0 ]; |
| データ[ 1 ] = J1939- > Information_this_ecu 。 this_identifications 。 ecu_identification 。 ECU_SERIAL_NUMBER [ 0 ]; |
| データ[ 2 ] = J1939- > Information_This_ecu 。 this_identifications 。 ecu_identification 。 ECU_LOCATION [ 0 ]; |
| データ[ 3 ] = J1939- > Information_This_ecu 。 this_identifications 。 ecu_identification 。 ECU_TYPE [ 0 ]; |
| データ[ 4 ] = 0xff ; /* 予約済み */ |
| データ[ 5 ] = 0xff ; /* 予約済み */ |
| データ[ 6 ] = 0xff ; /* 予約済み */ |
| データ[ 7 ] = 0xff ; /* 予約済み */ |
| return can_send_message ( id 、 data ); |
| }それ以外{ |
- ステップ4.1.2:
ECU X ECU Identificationがブロードキャストされるため、 ECU Yからの回答を読み取ります。 | } else if ( id0 == 0x18 && id1 == 0xfd && da == 0xc5 ){ |
| SAE_J1939_READ_RESPONSE_REQUEST_ECU_IDENTIFICITION ( J1939 、 SA 、データ); |
- ステップ4.2.1:マルチパッケージメッセージの場合、コントロールバイトはBAMまたはRTSのいずれかです。 BAMは、すべての
ECUsに送信される場合にのみ使用されます。たとえば、アドレス0xFF = 255 。ただし、コントロールバイトがRTSの場合、例えばアドレスが0xFFではない場合、 ECU YはRTSを送信し、 ECU XによるCTS応答をリッスンします。 RTSは、「メッセージを送信できる時期を教えてください」の質問です。そして、CTSは応答でありNow you can transmit the message to me 。 | J1939- > this_ecu_tp_cm 。 total_message_size = 0 ; |
| uint8_t i ; |
| for ( i = 0 ; i < length_of_each_field ; i ++ ){ |
| J1939- > this_ecu_tp_dt 。 data [ i ] = j1939- > information_this_ecu 。 this_identifications 。 ecu_identification 。 ecu_part_number [ i ]; |
| J1939- > this_ecu_tp_dt 。 data [ length_of_each_field + i ] = j1939- > information_this_ecu 。 this_identifications 。 ecu_identification 。 ecu_serial_number [ i ]; |
| J1939- > this_ecu_tp_dt 。 data [ length_of_each_field * 2 + i ] = j1939- > information_this_ecu 。 this_identifications 。 ecu_identification 。 ecu_location [ i ]; |
| J1939- > this_ecu_tp_dt 。 data [ length_of_each_field * 3 + i ] = j1939- > information_this_ecu 。 this_identifications 。 ecu_identification 。 ecu_type [ i ]; |
| J1939- > this_ecu_tp_cm 。 total_message_size += 4 ; |
| } |
| |
| / * tp cmを送信 */ |
| J1939- > this_ecu_tp_cm 。 number_of_packages = j1939- > this_ecu_tp_cm 。 total_message_size % 8 > 0 ? J1939- > this_ecu_tp_cm 。 total_message_size / 8 + 1 : j1939- > this_ecu_tp_cm 。 total_message_size / 8 ; / *丸め */ |
| J1939- > this_ecu_tp_cm 。 pgn_of_the_packeted_message = pgn_ecu_identification ; |
| J1939- > this_ecu_tp_cm 。 control_byte = da == 0xff ? control_byte_tp_cm_bam : control_byte_tp_cm_rts ; / *ブロードキャストの場合は、BAMコントロールバイトを使用します */ |
| enum_j1939_status_codes status = sae_j1939_send_transport_protocol_connection_management ( j1939 、 da ); |
- ステップ4.2.2:
ECU Y RTSを送信している場合、 ECU X CTSを使用してRTSと応答をECU Yに戻します | if ( j1939- > from_other_ecu_tp_cm。control_byte == control_byte_tp_cm_rts ) { |
| J1939- > this_ecu_tp_cm = j1939- > from_other_ecu_tp_cm ; / *コピー - 同じデータが必要です */ |
| J1939- > this_ecu_tp_cm 。 control_byte = control_byte_tp_cm_cts ; / *コントロールバイトをRTSからCTSに変更する必要があります */ |
| sae_j1939_send_transport_protocol_connection_management ( j1939 、 sa ); |
| } |
- ステップ4.2.3:
ECU Y CTSを受信したら、データ、この場合はECU IdentificationデータをECU Xに送信します。 | if ( j1939- > from_other_ecu_tp_cm。control_byte == control_byte_tp_cm_cts ) { |
| SAE_J1939_SEND_TRANSPORT_PROTOCOL_DATA_TRANSFER ( J1939 、 SA ); |
| } |
- ステップ4.2.3:
ECU Yがパッケージの後にパッケージを送信したら... | enum_j1939_status_codes sae_j1939_send_transport_protocol_data_transfer ( j1939 * j1939 、 uint8_t da ){ |
| uint32_t id = ( 0x1ceb << 16 )| ( da << 8 )| J1939- > information_this_ecu 。 this_ecu_address ; |
| uint8_t i 、 j 、パッケージ[ 8 ]; |
| uint16_t bytes_sent = 0 ; |
| enum_j1939_status_codes status = status_send_ok ; |
| for ( i = 1 ; i <= j1939- > this_ecu_tp_cm。number_of_packages ; i ++ ){ |
| パッケージ[ 0 ] = i ; / *パッケージ数 */ |
| for ( j = 0 ; j < 7 ; j ++ ){ |
| if ( bytes_sent <j1939-> this_ecu_tp_cm。total_message_size ) { |
| パッケージ[ J + 1 ] = J1939- > this_ecu_tp_dt 。データ[ bytes_sent ++ ]; / *収集したデータ */ |
| }それ以外{ |
| パッケージ[ j + 1 ] = 0xff ; /* 予約済み */ |
| } |
| } |
| status = can_send_message ( id 、 package ); |
| can_delay ( 100 ); / *重要なことは標準に応じて遅延 */ |
| if ( status != status_send_ok ){ |
| 戻りステータス。 |
| } |
| } |
| 戻りステータス。 |
| } |
- ステップ4.2.4:
ECU X 、各パッケージを受け取り、 PNG関数コードを把握してメッセージを構築しています。 | void SAE_J1939_READ_TRANSPORT_PROTOCOL_DATA_TRANSFER ( J1939 * J1939 、 UINT8_T SA 、 UINT8_T DATA []){ |
| / *シーケンスデータを保存 */ |
| J1939- > from_other_ecu_tp_dt 。 sequence_number = data [ 0 ]; |
| J1939- > from_other_ecu_tp_dt 。 from_ecu_address = sa ; |
| uint8_t i 、 j 、 index = data [ 0 ] -1 ; |
| for ( i = 1 ; i < 8 ; i ++ ){ |
| J1939- > from_other_ecu_tp_dt 。 data [ index * 7 + i -1 ] = data [ i ]; / *すべてのパッケージについて、最初のバイトデータ[0]がシーケンス番号である7バイトのデータを送信します */ |
| } |
| / *メッセージが完了したかどうかを確認します-turn = return notが完了 */ |
| if ( j1939- > from_other_ecu_tp_cm。number_of_packages ! = j1939- > from_other_ecu_tp_dt。sequence_number || j1939- > from_other_ecu_tp_cm 。 |
| 戻る; |
| } |
| |
| / *私たちのメッセージは完全です - それを構築して、それをcomplete_data [total_message_size] */ |
| uint32_t pgn = j1939- > from_other_ecu_tp_cm 。 pgn_of_the_packeted_message ; |
| uint16_t total_message_size = j1939- > from_other_ecu_tp_cm 。 total_message_size ; |
| uint8_t complete_data [ max_tp_dt ]; |
| uint16_t inserted_bytes = 0 ; |
| for ( i = 0 ; i <j1939-> from_other_ecu_tp_dt。sequence_number ; i ++ ) { |
| for ( j = 0 ; j < 7 ; j ++ ){ |
| if ( inserted_bytes < total_message_size ){ |
| complete_data [ inserted_bytes ++ ] = j1939- > from_other_ecu_tp_dt 。データ[ i * 7 + j ]; |
| } |
| } |
| } |
| |
| / *メッセージackの端を送信する */ |
| if ( j1939- > from_other_ecu_tp_cm。control_byte == control_byte_tp_cm_rts ) { |
| SAE_J1939_SEND_ACKNOWLEDGEMENT ( J1939 、 SA 、 CONTROL_BYTE_TP_CM_ENDOFMSGACK 、 GROUP_FUNCTION_VALUE_NORMAL 、 PGN ); |
| } |
そして最後にメッセージを実装します。 | ケースpgn_ecu_identification : |
| SAE_J1939_READ_RESPONSE_REQUEST_ECU_IDENTIFICITION ( J1939 、 SA 、 Complete_Data ); |
| 壊す; |
SAE J1939機能
- SAE J1939:21輸送層
- 了承
- リクエスト
- BAM、CTS、RTS、EOMとの輸送プロトコル接続管理
- 輸送プロトコルデータ転送
- SAE J1939:71アプリケーションレイヤー
- コンポーネントの識別を要求します
- ECU識別をリクエストします
- ソフトウェア識別をリクエストします
- 独自のリクエストa
- 独自のリクエストb
- SAE J1939:73診断層
- DM1
- DM2
- DM3
- DM14
- DM15
- DM16
- SAE J1939:81ネットワーク管理レイヤー
- 主張された住所
- 指揮されたアドレス
- 住所は主張されていません
- アドレスを削除します
追加の機能
- ISO 11783農業と林業のためのトラクターと機械
- ISO 11783-7メッセージアプリケーションレイヤーを実装します
- 補助バルブコマンド
- 補助バルブの推定フロー
- 補助バルブ測定位置
- 汎用バルブコマンド
- 汎用バルブの推定フロー
質問と回答
- Q:このライブラリは
C++で使用できますか? - Q:このライブラリの上に構築したいのですが、どうすればよいですか?
- A:最初に
ANSI C (C89)およびビットワイズ操作を知る必要があります。次に、 SAE J1939:21 Transport Layer構造を理解する必要があります。新しい機能でPDFを更新することを忘れないでください。
- Q:これをArduinoで使用できますか?
- A:はい、この
Cコードは100%純粋なCコードであり、 C標準ライブラリのみを使用しており、コードは使用しているハードウェアを考慮していません。
- Q:ライブラリを使用するためにライブラリをインストールする必要がありますか?
- A:いいえ、
.cおよび.hファイルをプロジェクトにコピーしてコンパイルします。これをQTフレームワークで使用しました。
- Q:このプロジェクトは今ではかなり古く、それほど更新ではありませんが、それを使用する価値はまだ価値がありますか?
- A:はい、このライブラリは、私または他のライブラリがSAE J1939のより多くの機能を含む場合にのみ更新されます。私がこれを
ANSI C (C89)で書いた理由は、それが業界標準であり、常にこのライブラリをコンパイルしてすべてのシステムで使用できるためです。
- Q:図書館でのあなたの計画は何ですか?
- A:SAE J1939をすべての人が利用できるようにするため
- Q:can-busはありませんが、とにかくこのライブラリをuart、usb、wifiなどで使用できますか?
- A:はい。これは、特定の方法でメッセージを形作る方法にすぎません。
- Q:缶を持っていなくても、このライブラリでデータを送信できますか?
- A:はい。 DM14送信要求、DM15ステータス応答、DM16バイナリ転送と呼ばれるものがあります。産業用の方法でデータを転送する場合は、それを使用してください。
- Q:複数のECUから1つのECUにマルチパッケージメッセージを同時に送信できますか?
- A:いいえ。複数のECUから別のECUにマルチパッケージを送信し始めた場合、ECUはメッセージを理解できません。宛先アドレスが同じ場合、その時点でマルチパッケージメッセージのみを送信します。
- Q:Open SAE J1939で
ANSI C (C89)を使用したくありません。 Open SAE J1939で最新のC標準を使用できますか?- はい、このライブラリで最新のC標準を使用できます。
- Q:このライブラリをWindows MS-DOSまたはWindows 95マシンにコンパイルすることは可能ですか?
- C89互換性のあるコンパイラとIDEとIDEは問題ではないはずです
- Q:プログラムが占めるメモリを調整できますか?
- A:はい、ファイル
Structs.hのMAX_PROPRIETARY_A 、 MAX_PROPRIETARY_B 、およびMAX_PROPRIETARY_B_PGNSを使用して調整できます。 「正気」デフォルト値が提供されますが、独自のPGNサポートが必要ない場合は、より多くのPGNを使用する必要がある場合は、最小限に設定できます。
問題と回答
- I:このライブラリをコンパイルすることはできません。
Keil Microvisionを使用しています。- A:
Keil Microvision 、 0b010101などのバイナリ番号を処理できません。 Open SAE J1939がSTM32CubeIDEで作成されているため、代わりにSTM32CubeIDE試してみてください
- I:
STM32など、ハードウェアの例をいくつか提供できますか?- A:はい! STM32の例があり、メッセージの割り込みリスナーを含むcan-busとの接続を取得する方法があります。
CAN_STM32.txtを探して、 Examples -> Hardwareフォルダー。また、 QT C++にはUSB例もあります。