Dev #1
@@ -0,0 +1,23 @@
|
||||
#ifndef __DS_Accord_8_F-CAN_H
|
||||
#define __DS_Accord_8_F-CAN_H
|
||||
|
||||
#include "main.h"
|
||||
|
||||
// Структура описания CAN-пакета для диспетчера задач (Scheduler)
|
||||
typedef struct {
|
||||
uint16_t id; // CAN ID пакета
|
||||
uint8_t dlc; // Длина кадра (DLC)
|
||||
uint32_t period; // Период отправки в миллисекундах (мс)
|
||||
uint32_t last_time; // Таймер последнего запуска (GetTick)
|
||||
uint8_t alive_cnt; // Текущий шаг Alive Counter (0..3)
|
||||
uint32_t start_phase; // Сдвиг запуска в миллисекундах
|
||||
uint8_t data[8]; // ПОЛЕЗНАЯ НАГРУЗКА:
|
||||
} CanTaskTypeDef;
|
||||
|
||||
/* Прототипы функций для вызова в основном проекте */
|
||||
void run_honda_simulation(void);
|
||||
uint8_t calc_honda_halfbyte_checksum(uint16_t id, uint8_t *data, uint8_t dlc, uint8_t alive_val);
|
||||
|
||||
extern volatile CanTaskTypeDef tasks[];
|
||||
|
||||
#endif /* __DS_Accord_8_F-CAN_H */
|
||||
@@ -1,2 +1,243 @@
|
||||
# Accord_8_F-CAN
|
||||
Список известных пакетов для высокоскоростной шины
|
||||
|
||||
|
||||
| ID (Hex) | DLC | Источник | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Описание флагов и результаты реверса |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x158`** | 8 | ECU (ДВС) | `00` | `00` | `00` | `00` | `40` | `00` | `00` | Линейная скорость. |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание
|
||||
|
||||
* **Byte 0:** — `00`
|
||||
* **Byte 1:** — `00`
|
||||
* **Byte 2:** — `00`
|
||||
* **Byte 3:** — `00`
|
||||
* **Byte 4:** — `40` - скорость. Чистый одиночный 8-битный байт. Шкала имеет завышающий автомобильный коэффициент безопасности на высоких скоростях, но в среднем цена одного деления составляет **2.7 км/ч**.
|
||||
$$\text{Значение Byte 4 (DEC)} = \frac{\text{Желаемая скорость в км/ч}}{2.7}$$
|
||||
* **Byte 5:** — `00`
|
||||
* **Byte 6:** — `00`
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x164`** | 8 | Панель | `00` | `00` | `00` | `00` | `FF` | `00` | `00` | |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание для 0x164
|
||||
|
||||
* **Byte 0:** — `00`
|
||||
* **Byte 1:** — `00`
|
||||
* **Byte 2:** — `00`
|
||||
* **Byte 3:** — `00`
|
||||
* **Byte 4:** — `FF`
|
||||
* **Byte 5:** — `00`
|
||||
* **Byte 6:** — `00`
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x1A4`** | 8 | Блок ABS | `00` | `00` | `00` | `00` | `00` | `00` |`00` | Статус ABS/VSA. Чистый статус тормозной системы — полностью и стабильно гасит «гирлянду» ламп тормозов (VSA/ABS) на панели. |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание
|
||||
|
||||
* **Byte 0:** — `00` -
|
||||
* **Byte 1:** — `00` -
|
||||
* **Byte 2:** — `00` -
|
||||
* **Byte 3:** — `00` -
|
||||
|
||||
биты
|
||||
* 0 -
|
||||
* 1 -
|
||||
* 2 -
|
||||
* 3 -
|
||||
* 4 - жёлтый треугольник
|
||||
* 5 - VSA
|
||||
* 6 - ABS
|
||||
* 7 - Ручник
|
||||
* **Byte 4:** — `00` -
|
||||
|
||||
биты
|
||||
* 0 -
|
||||
* 1 -
|
||||
* 2 -
|
||||
* 3 - непрерывный писк
|
||||
* 4 -
|
||||
* 5 -
|
||||
* 6 -
|
||||
* 7 -
|
||||
* **Byte 5:** — `00` -
|
||||
* **Byte 6:** — `00` -
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x17C`** | 8 | ECU (ДВС) | `00` | `00` | `00` | `00` | `00` | `00` | `00` | лампа CHECK + Предположительно Обороты двигателя (Тахометр) |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание
|
||||
|
||||
* **Byte 0:** — `00` -
|
||||
* **Byte 1:** — `00` -
|
||||
* **Byte 2:** — `00` -
|
||||
* **Byte 3:** — `00` -
|
||||
* **Byte 4:** — `00` -
|
||||
|
||||
биты
|
||||
* 0 -
|
||||
* 1 -
|
||||
* 2 -
|
||||
* 3 - круиз контроль
|
||||
* 4 - CHECK индикатор
|
||||
* 5 - CHECK выводится на главный экран
|
||||
* 6 -
|
||||
* 7 -
|
||||
|
||||
* **Byte 5:** — `00` -
|
||||
* **Byte 6:** — `00` -
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x294`** | 8 | Панель | `02` | `16` | `F1` | `01` | `57` | `FE` | `00` | |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание для 0x294
|
||||
|
||||
* **Byte 0:** — `02`
|
||||
* **Byte 1:** — `16`
|
||||
* **Byte 2:** — `F1`
|
||||
* **Byte 3:** — `01`
|
||||
* **Byte 4:** — `57`
|
||||
* **Byte 5:** — `FE`
|
||||
* **Byte 6:** — `00`
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x324`** | 8 | MICU (Кузов) | `62` | `00` | `00` | `00` | `00` | `00` | `00` | Положение стрелки температуры, статус ламп (АКБ, Масло) и сервисного режима (SCS).
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание для 0x324
|
||||
|
||||
* **Byte 0:** — `62` - температура масла, нелинейная, от 0x60 - нулевая, до 0xA5 - максимальная (уже срабатывает предупреждение о перегреве)
|
||||
* **Byte 1:** — `00` -
|
||||
* **Byte 2:** — `00` -
|
||||
* **Byte 3:** — `00` -
|
||||
* **Byte 4:** — `00` -
|
||||
* **Byte 5:** — `00` -
|
||||
* **Byte 6:** — `00` -
|
||||
|
||||
биты
|
||||
* 0 - режим SCS
|
||||
* 1 - значок аккумулятора
|
||||
* 2
|
||||
* 3
|
||||
* 4 - ключ
|
||||
* 5 - моргающий ключ
|
||||
* 6 -
|
||||
* 7 -
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x374`** | 8 | Панель | `00` | `00` | `00` | `00` | `05` | `00` | - | |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Передаёт текущие данные, отображаемые на панели
|
||||
|
||||
* **Byte 0:** — `00`
|
||||
* **Byte 1:** — `00`
|
||||
* **Byte 2:** — `00`
|
||||
* **Byte 3:** — `00`
|
||||
* **Byte 4:** — `05` содержит информацию о том, какая текущая пиктограмма выведена на главном экране
|
||||
* **Byte 5:** — `00`
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x377`** | 8 | Панель | `00` | `2E` | `DB` | `08` | `9B` | `00` | `04` | |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание для 0x377
|
||||
|
||||
* **Byte 0:** — `00`
|
||||
* **Byte 1:** — `2E`
|
||||
* **Byte 2:** — `DB`
|
||||
* **Byte 3:** — `08`
|
||||
* **Byte 4:** — `9B`
|
||||
* **Byte 5:** — `00`
|
||||
* **Byte 6:** — `04`
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x378`** | 8 | Панель | `7F` | `FF` | `FE` | `FF` | `FF` | `E0` | `00` | |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание для 0x378
|
||||
|
||||
* **Byte 0:** — `7F`
|
||||
* **Byte 1:** — `FF`
|
||||
* **Byte 2:** — `FE`
|
||||
* **Byte 3:** — `FF`
|
||||
* **Byte 4:** — `FF`
|
||||
* **Byte 5:** — `E0`
|
||||
* **Byte 6:** — `00`
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x405`** | 8 | Панель | `81` | `07` | `10` | `02` | `00` | `00` | `00` | |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание для 0x405
|
||||
|
||||
* **Byte 0:** — `81`
|
||||
* **Byte 1:** — `07`
|
||||
* **Byte 2:** — `10`
|
||||
* **Byte 3:** — `02`
|
||||
* **Byte 4:** — `00`
|
||||
* **Byte 5:** — `00`
|
||||
* **Byte 6:** — `00`
|
||||
</details>
|
||||
|
||||
| | | | | | | | | | | |
|
||||
| :---: | :---: | :--- | :---: | :---: | :---: | :---: | :---: | :---: | :---: | :--- |
|
||||
| **`0x428`** | 8 | Панель | `00` | `00` | `00` | `00` | `00` | `00` | - | |
|
||||
|
||||
<details>
|
||||
<summary><b> <i>подробнее</i></b></summary>
|
||||
|
||||
### Описание для 0x428
|
||||
|
||||
* **Byte 0:** — `00`
|
||||
* **Byte 1:** — `00`
|
||||
* **Byte 2:** — `00`
|
||||
* **Byte 3:** — `00`
|
||||
* **Byte 4:** — `00`
|
||||
* **Byte 5:** — `00`
|
||||
</details>
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
#include "DS_Accord_8_F-CAN.h"
|
||||
|
||||
// Внешний дескриптор CAN из main.c
|
||||
extern CAN_HandleTypeDef hcan;
|
||||
|
||||
// Массив пакетов симуляции
|
||||
volatile CanTaskTypeDef tasks[] = {
|
||||
// ID, DLC, Period, Alive, Last_Time, Start_Phase, { Исходные данные DATA[8] }
|
||||
{0x158, 8, 10, 0, 0, 0, {0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00}}, // ECU Скорость
|
||||
{0x17C, 8, 10, 0, 0, 2, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, //
|
||||
{0x1A4, 8, 20, 0, 0, 4, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // ABS/VSA Тормоза
|
||||
{0x324, 8, 20, 0, 0, 6, {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, // MICU Кузов
|
||||
|
||||
// {0x490, 8, 20, 0, 0, 6, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x491, 8, 20, 0, 0, 6, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x492, 8, 20, 0, 0, 8, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x493, 8, 20, 0, 0, 8, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x494, 8, 20, 0, 0, 9, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x495, 8, 20, 0, 0, 9, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x496, 8, 20, 0, 0, 1, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x497, 8, 20, 0, 0, 9, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x498, 8, 20, 0, 0, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x499, 8, 20, 0, 0, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49A, 8, 20, 0, 0, 5, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49B, 8, 20, 0, 0, 5, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49C, 8, 20, 0, 0, 7, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49D, 8, 20, 0, 0, 7, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49E, 8, 20, 0, 0, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}},
|
||||
// {0x49F, 8, 20, 0, 0, 3, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00}}
|
||||
|
||||
};
|
||||
|
||||
static const uint8_t num_tasks = sizeof(tasks) / sizeof(tasks[0]);
|
||||
static const uint8_t alive_seq[] = {0, 1, 2, 3};
|
||||
|
||||
/**
|
||||
* @brief Главный диспетчер циклической симуляции пакетов для Honda Accord 8
|
||||
* @note Должен вызываться в основном бесконечном цикле while(1) в main.c
|
||||
*/
|
||||
void run_honda_simulation(void)
|
||||
{
|
||||
uint32_t current_tick = HAL_GetTick();
|
||||
CAN_TxHeaderTypeDef tx_header;
|
||||
uint8_t tx_data[8]; // Временный буфер для формирования финального кадра
|
||||
uint32_t tx_mailbox;
|
||||
|
||||
for (uint8_t i = 0; i < num_tasks; i++)
|
||||
{
|
||||
// Настройка стартовой фазы при первом запуске
|
||||
if (tasks[i].last_time == 0)
|
||||
{
|
||||
tasks[i].last_time = current_tick + tasks[i].start_phase;
|
||||
}
|
||||
|
||||
// Проверка временной сетки
|
||||
if (current_tick < tasks[i].last_time)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Проверка свободного места в Mailbox пула
|
||||
if (HAL_CAN_GetTxMailboxesFreeLevel(&hcan) == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Сдвигаем временную метку на период вперед
|
||||
tasks[i].last_time += tasks[i].period;
|
||||
|
||||
// Копируем текущие данные из структуры во временный буфер отправки
|
||||
for (uint8_t b = 0; b < 8; b++)
|
||||
{
|
||||
tx_data[b] = tasks[i].data[b];
|
||||
}
|
||||
|
||||
// Конфигурируем заголовок CAN
|
||||
tx_header.StdId = tasks[i].id;
|
||||
tx_header.DLC = tasks[i].dlc;
|
||||
tx_header.RTR = CAN_RTR_DATA;
|
||||
tx_header.IDE = CAN_ID_STD;
|
||||
tx_header.TransmitGlobalTime = DISABLE;
|
||||
|
||||
// Расчитываем динамическую контрольную сумму Honda на основе текущих данных
|
||||
uint8_t current_alive = alive_seq[tasks[i].alive_cnt];
|
||||
uint8_t checksum_nibble = calc_honda_halfbyte_checksum(tx_header.StdId, tx_data, tx_header.DLC, current_alive);
|
||||
|
||||
// Внедряем Alive счетчик и чексумму в самый последний байт пакета
|
||||
tx_data[tx_header.DLC - 1] = (uint8_t)((current_alive << 4) | checksum_nibble);
|
||||
|
||||
// Отправляем пакет в пул Mailbox
|
||||
if (HAL_CAN_AddTxMessage(&hcan, &tx_header, tx_data, &tx_mailbox) == HAL_OK)
|
||||
{
|
||||
tasks[i].alive_cnt = (tasks[i].alive_cnt + 1) % 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Математически выверенный алгоритм подсчета Check Byte для Accord 8 (Сумма полубайт + DLC)
|
||||
*/
|
||||
uint8_t calc_honda_halfbyte_checksum(uint16_t id, uint8_t *data, uint8_t dlc, uint8_t alive_val)
|
||||
{
|
||||
uint32_t sum = 0;
|
||||
|
||||
// 1. Складываем полубайты 11-битного CAN ID
|
||||
sum += (id >> 8) & 0x0F;
|
||||
sum += (id >> 4) & 0x0F;
|
||||
sum += id & 0x0F;
|
||||
|
||||
// 2. Складываем полубайты тела пакета (все, кроме последнего контрольного байта)
|
||||
for (int i = 0; i < (dlc - 1); i++)
|
||||
{
|
||||
sum += (data[i] >> 4) & 0x0F;
|
||||
sum += data[i] & 0x0F;
|
||||
}
|
||||
|
||||
// 3. Добавляем длину пакета и шаг циклического счетчика
|
||||
sum += dlc & 0x0F;
|
||||
sum += alive_val & 0x0F;
|
||||
|
||||
// 4. Реализация правила дополнения до нуля (вычитание накопленного остатка из 16)
|
||||
return (uint8_t)((0x10 - (sum & 0x0F)) & 0x0F);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user