【XCP】最小構成のMBD事例 第2章 その201【AUTOSAR⑦】

【XCP】最小構成のMBD事例 第2章 その201【AUTOSAR⑦】 事例
【XCP】最小構成のMBD事例 第2章 その201【AUTOSAR⑦】

バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/

はじめに

AUTOSAR-XCPをPCシミュレーションするにあたっていくつかのWindowsAPIが必要となる。
そのためにはwindows.hをincludeすることになるが、これが他の定義と衝突することがある。
よって、stub.cでWindowsAPIのラップ関数を定義することで回避する。

あとはCanIf関連の辻褄合わせが必要であるが、
ここはmain.cでうまくやっているらしいので、それを確認する。

登場人物

博識フクロウのフクさん

指差しフクロウ

イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1

エンジニア歴8年の太郎くん

技術者太郎

イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1

main.c

太郎くん
太郎くん

前回の話だとmain.cでいろいろ辻褄合わせをしてるようなこと言ってたけど、どんな感じになってるの?

フクさん
フクさん

これもまずはソースコードを貼ってしまおう。

int cycle_cnt;

extern Xcp_ConfigType	g_DefaultConfig;

Std_ReturnType _CanIf_Transmit(PduIdType CanTxPduId, const PduInfoType *PduInfoPtr)
{
	size_t i;
	vcanMessage msg = { 0 };
	msg.Dlc = PduInfoPtr->SduLength;
	int fd = 0;

#ifdef CANFD_SUPPORT
	fd = 1;
#endif
	
	if (CanTxPduId == 0) {
		msg.Id = 2;
	}
	msg.Ext = VCAN_ID_STD;

	for (i = 0U; i < PduInfoPtr->SduLength; i++) {
		msg.Data[i] = PduInfoPtr->SduDataPtr[i];
	}

	viratualCanSend(pVcanHandle, &msg, fd);
	return(BUFREQ_OK);
}

int rx_interrupt(void *param, vcanMessage* msg)
{
	_WaitForSigleObject(hMutex, -1);

	// for CAN-FD
	static const uint8 cantp_canfd_dlc_snd_table[] = {
	0U,		1U,		2U,		3U,		4U,		5U,		6U,		7U,
	8U,		12U,	16U,	20U,	24U,	32U,	48U,	64U,
	};

	XcpInfo.SduDataPtr = msg->Data;
	XcpInfo.SduLength = cantp_canfd_dlc_snd_table[msg->Dlc];
	if (msg->Id == 1) {
		Xcp_CanIfRxIndication(1, &XcpInfo);
	}
	_ReleaseMutex(hMutex);
	return 0;
}

int tx_interrupt(void *param, vcanMessage* msg)
{
	return 0;
}

int err_interrupt(void *param, vcanMessage* msg)
{
	return 0;
}

void main_handler()
{
	_WaitForSigleObject(hMutex, -1);
	

	ecu_t1ms_job();
	if (cycle_cnt % 10 == 0) {
		ecu_t10ms_job();
	}

	if (cycle_cnt % 100 == 0) {
		ecu_t100ms_job();
	}
	if (cycle_cnt % 200 == 0) {
		ecu_t200ms_job();
	}

	
	Xcp_MainFunction();

	Xcp_MainFunction_Channel(3);

	if (cycle_cnt % 10 == 0) {
		Xcp_MainFunction_Channel(1);
	}

	if (cycle_cnt % 100 == 0){
		Xcp_MainFunction_Channel(2);
	}
	cycle_cnt++;
	_ReleaseMutex(hMutex);
}

void XcpStandaloneLock()
{
	_WaitForSigleObject(hMutex, -1);
}

void XcpStandaloneUnlock()
{
	_ReleaseMutex(hMutex);
}

void Det_ReportError(uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId)
{
	printf("Det_ReportError ModuleId=%d, InstanceId=%d, ApiId=%d, ErrorId=%d \n", ModuleId, InstanceId, ApiId, ErrorId);
}

int main()
{
	syslog(LOG_NOTICE, "=== MainTask ===");

	hMutex = _CreateMutex(NULL_PTR, FALSE, (char*)NULL_PTR);

	_timeBeginPeriod(1);
	pVcanHandle = viratualCanInit(0, rx_interrupt, tx_interrupt, err_interrupt, 0, "autosar-xcp", 1);
	viratualCanConfig(pVcanHandle, 500000, 2000000);
	viratualCanStart(pVcanHandle);

	syslog(LOG_NOTICE, "== XcpTp_Init ==");
	
	ecu_init();
	Xcp_Init(&g_DefaultConfig);
	

	_Sleep(1);
	setcallback(main_handler);

	return 0;
}

main.c解説

太郎くん
太郎くん

これは、まぁまぁ規模が大きいなー。

太郎くん
太郎くん

パッと見た感じだと
送信関数送信完了割り込み受信割り込みエラー割り込みを定義してる感じか。
これがCanIfの辻褄合わせのところだね。

太郎くん
太郎くん

あとはmain_handlerでecu内部処理の周期を定義して、
同じようにXCP関連のイベントチャンネル毎の処理を定義してるのか。

太郎くん
太郎くん

XcpStandaloneLock、XcpStandaloneUnLockは

AUTOSAR-XCP内から呼ばれてる排他同期用関数ってところだね。

太郎くん
太郎くん

Det_ReportErrorもAUTOSAR-XCP内から呼ばれるエラー通知関数かな。

太郎くん
太郎くん

最後にmain関数がプログラム起動時の関数でいろいろ初期化している。
ってところか。

フクさん
フクさん

大正解だ!

太郎くん
太郎くん

よっしゃ!

そして現在の状態は?

フクさん
フクさん

これでやっとビルドが通った。って状態になる。

太郎くん
太郎くん

まだ動かないのか・・・。

フクさん
フクさん

あとはAUTOSAR-XCPのコンフィグレーションをしないといけないかな。
まぁこれもヘッダ内のdefine定義する部分と内部のデータ構造を定義する部分にわかれるんだけど。

太郎くん
太郎くん

まだまだ先は長そうだな・・・。

まとめ

フクさん
フクさん

まとめだよ。

  • CanIfとかAUTOSAR-XCPから呼び出される関数群の辻褄合わせをmain.cで実施。
    • 送信関数と送信完了割り込み、受信割り込み、エラー割り込み。
    • 排他制御関数。
    • エラー通知関数。
  • main関数で初期化処理関連を実施。
  • これでやっとビルドが通った状態となる。

バックナンバーはこちら。

コメント

タイトルとURLをコピーしました