Dein Warenkorb ist gerade leer!
Freertos mit separaten Task-Datei
Beispiel mit einem Modbus-Task …
------------------------------------------------------------------
Struktur:
------------------------------------------------------------------
Core/
├── Src/
│ ├── freertos.c <- HAL-generiert (belassen)
│ ├── modbus_task.c <- deine Datei
├── Inc/
│ ├── freertos.h <- HAL-generiert (belassen)
│ ├── modbus_task.h <- dein Header
------------------------------------------------------------------
modbus_task.h:
------------------------------------------------------------------
#ifndef INC_MODBUS_TASK_H_
#define INC_MODBUS_TASK_H_
#include "main.h"
void modbus_task(void *argument);
#endif /* INC_MODBUS_TASK_H_ */
------------------------------------------------------------------
modbus_task.c;
------------------------------------------------------------------
#include "modbus_task.h"
#include "usart.h"
#include "config.h"
#include "analog_helper.h" // für analoge Werte ...
#include "gpio.h"
#include "cmsis_os.h"
#include <string.h>
#include <stdlib.h>
#include <math.h>
UART_HandleTypeDef huart4;
#define MODBUS_BUF_LEN 256
static uint8_t rx_buffer[MODBUS_BUF_LEN];
static uint8_t tx_buffer[MODBUS_BUF_LEN];
static uint16_t rx_index = 0;
extern I2C_HandleTypeDef hi2c2;
static uint16_t modbus_crc16(uint8_t *buf, uint16_t len)
{
uint16_t crc = 0xFFFF;
for(uint16_t pos = 0; pos < len; pos++)
{
crc ^= (uint16_t)buf[pos];
for(uint8_t i = 0; i < 8; i++)
{
if((crc & 0x0001) != 0)
{
crc >>= 1;
crc ^= 0xA001;
}
else crc >>= 1;
}
}
return crc;
}
static void modbus_send(uint8_t *buf, uint16_t len)
{
HAL_UART_Transmit(&huart4, buf, len, HAL_MAX_DELAY);
}
static void modbus_handle_request(uint8_t *buf, uint16_t len)
{
if(len < 4) return;
uint8_t id = buf[0];
uint8_t func = buf[1];
if(id != g_config.modbus_slave_id) return;
uint16_t crc_calc = modbus_crc16(buf, len-2);
uint16_t crc_recv = buf[len-2] | (buf[len-1] << 8);
if(crc_calc != crc_recv) return;
uint16_t addr = (buf[2] << 8) | buf[3];
uint16_t count = (buf[4] << 8) | buf[5];
uint16_t response_len = 0;
switch(func)
{
case 1: // Read Coils (Dout lesen)
{
tx_buffer[0] = id;
tx_buffer[1] = func;
tx_buffer[2] = 1;
uint8_t val = 0;
val |= HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_3) ? (1<<0) : 0;
val |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_4) ? (1<<1) : 0;
val |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) ? (1<<2) : 0;
val |= HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) ? (1<<3) : 0;
val |= HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) ? (1<<4) : 0;
val |= HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_15) ? (1<<5) : 0;
val |= HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_10) ? (1<<6) : 0;
tx_buffer[3] = val;
response_len = 4;
break;
}
case 2: // Read Discrete Inputs (Din lesen)
{
tx_buffer[0] = id;
tx_buffer[1] = func;
tx_buffer[2] = 2;
uint16_t val = 0;
val |= HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) ? (1<<0) : 0;
val |= HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_4) ? (1<<1) : 0;
val |= HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_5) ? (1<<2) : 0;
val |= HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_6) ? (1<<3) : 0;
val |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_0) ? (1<<4) : 0;
val |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_1) ? (1<<5) : 0;
val |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_2) ? (1<<6) : 0;
val |= HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_3) ? (1<<7) : 0;
val |= HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) ? (1<<8) : 0;
val |= HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) ? (1<<9) : 0;
val |= HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_2) ? (1<<10) : 0;
tx_buffer[3] = val >> 8;
tx_buffer[4] = val & 0xFF;
response_len = 5;
break;
}
case 3: // Read Holding Registers (Aout lesen, float)
case 4: // Read Input Registers (Ain lesen, float)
{
tx_buffer[0] = id;
tx_buffer[1] = func;
tx_buffer[2] = count * 4;
float values[5] = {0};
if(func == 3)
{
uint16_t aout[4];
analog_read_outputs(aout, 4);
for(int i=0;i<4;i++) values[i] = (float)aout[i];
}
else
{
int32_t ain[5];
analog_read_inputs(ain, 5);
for(int i=0;i<5;i++) values[i] = (float)ain[i];
}
for(uint16_t i = 0; i < count; i++)
{
if(i >= 5) break;
uint32_t fval;
memcpy(&fval, &values[i], sizeof(float));
tx_buffer[3+i*4+0] = (fval >> 24) & 0xFF;
tx_buffer[3+i*4+1] = (fval >> 16) & 0xFF;
tx_buffer[3+i*4+2] = (fval >> 8) & 0xFF;
tx_buffer[3+i*4+3] = fval & 0xFF;
}
response_len = 3 + count * 4;
break;
}
case 5: // Write Single Coil (DO setzen)
{
uint16_t val = (buf[4] << 8) | buf[5];
if(addr == 0)
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, (val ? GPIO_PIN_SET : GPIO_PIN_RESET));
else if(addr == 1)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, (val ? GPIO_PIN_SET : GPIO_PIN_RESET));
else if(addr == 2)
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, (val ? GPIO_PIN_SET : GPIO_PIN_RESET));
else if(addr == 3)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, (val ? GPIO_PIN_SET : GPIO_PIN_RESET));
else if(addr == 4)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, (val ? GPIO_PIN_SET : GPIO_PIN_RESET));
else if(addr == 5)
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_15, (val ? GPIO_PIN_SET : GPIO_PIN_RESET));
else if(addr == 6)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10, (val ? GPIO_PIN_SET : GPIO_PIN_RESET));
memcpy(tx_buffer, buf, 6);
response_len = 6;
break;
}
case 16: // Write Multiple Registers (Aout schreiben, float)
{
uint8_t bytecount = buf[6];
float values[4] = {0};
for(uint16_t i=0; i < count; i++)
{
if(i >= 4) break;
uint32_t fval = (buf[7+i*4+0] << 24) |
(buf[7+i*4+1] << 16) |
(buf[7+i*4+2] << 8) |
buf[7+i*4+3];
memcpy(&values[i], &fval, sizeof(float));
}
// Optional: analog_write_outputs(values);
tx_buffer[0] = id;
tx_buffer[1] = func;
tx_buffer[2] = buf[2];
tx_buffer[3] = buf[3];
tx_buffer[4] = buf[4];
tx_buffer[5] = buf[5];
response_len = 6;
break;
}
default:
{
tx_buffer[0] = id;
tx_buffer[1] = func | 0x80;
tx_buffer[2] = 0x01;
response_len = 3;
break;
}
}
uint16_t crc = modbus_crc16(tx_buffer, response_len);
tx_buffer[response_len++] = crc & 0xFF;
tx_buffer[response_len++] = crc >> 8;
modbus_send(tx_buffer, response_len);
}
void modbus_task(void *argument)
{
HAL_UART_Receive_IT(&huart4, &rx_buffer[rx_index], 1);
for(;;)
{
osDelay(10);
static uint32_t last_index = 0;
static uint32_t last_tick = 0;
if(rx_index != last_index)
{
last_index = rx_index;
last_tick = HAL_GetTick();
}
if((HAL_GetTick() - last_tick) > 5 && rx_index > 0)
{
modbus_handle_request(rx_buffer, rx_index);
rx_index = 0;
memset(rx_buffer, 0, sizeof(rx_buffer));
HAL_UART_Receive_IT(&huart4, &rx_buffer[rx_index], 1);
}
}
}
------------------------------------------------------------------
Hinzufügen in der freertos.c;
------------------------------------------------------------------
...
#include "modbus_task.h"
...
osThreadId_t modbusTaskHandle;
const osThreadAttr_t modbusTask_attributes = {
.name = "modbusTask",
.priority = (osPriority_t) osPriorityNormal,
.stack_size = 512 * 4
};
...
//innerhalb von void MX_FREERTOS_Init(void) hinter dem ersten Task-Handle ...
modbusTaskHandle = osThreadNew(modbus_task, NULL, &modbusTask_attributes); // hinzufügen
...
Tags:

Schreibe einen Kommentar