Troško jinak:
V příloze jsou vygenerované soubory pro CANfestival...
V programu mám dva tasky:
canopen_dataprocess_thread - tímto taskem vše nainicializuji...
Kód: Vybrať všetko
static void canopen_dataprocess_thread(void * pvParameters) {
int i;
unsigned char ret_canInit;
Message RxMSG = Message_Initializer;
CANOpen_Message CAN_Rx_m;
/* CANOpen Initialising */
initTimer();
//setNodeId (&ObjDict_CAN2_Data, LIFTER_ID);
setNodeId(&ObjDict_Data, ARM_ID);
CO_D.CO_CAN1 = &ObjDict_Data;
CO_D.CO_CAN1->canHandle = CAN1;
printf("CANOpen OD Get The Lifer NodeID...");
ret_canInit = canInit(CAN1);
if (ret_canInit) {
Vypis("CAN init finished...");
/* State Machine Change to Initialisation and automatic go into Pre_operational*/
setState(&ObjDict_Data, Initialisation);
Vypis("State Machine change to Initialisation...");
/* State Machine change to Pro_operational */
Vypis("State Machine change to Pro_operational...");
} else {
Vypis("CAN init failed...");
}
/*create a queue can store 20 data*/
xQ_CAN_MSG = xQueueCreate(20, sizeof(CANOpen_Message));
/* Success Or Fail */
if (NULL == xQ_CAN_MSG) {
/*failed to creat the queue*/
while (1) {
Vypis("!!!CANOpen Queue created failed!!!");
vTaskDelay(100);
}
}
while (1) {
/*Receive CANBUS data*/
if (xQueueReceive(xQ_CAN_MSG, &(CAN_Rx_m), (TickType_t) 100)) {
RxMSG.cob_id = (uint16_t) (CAN_Rx_m.m.StdId);
RxMSG.rtr = CAN_Rx_m.m.RTR;
RxMSG.len = CAN_Rx_m.m.DLC;
for (i = 0; i < RxMSG.len; i++) {
RxMSG.data[i] = CAN_Rx_m.m.Data[i]; //Transfer data[0-7] from CAN_Rx_m to RxMSG
}
if ((NULL != CO_D.CO_CAN1) && (1 == CAN_Rx_m.CANx)) /*Data From CAN1*/
{
canDispatch(CO_D.CO_CAN1, &RxMSG);
}
} else {
// Vypis("Waiting for a CAN message!\r\n");
vTaskDelay(100);
}
vTaskDelay(CANOpen_THREAD_DELAY_TIMER);
}
}
Nakonec mám druhý task
control_thread, kterým vše zpracovávám....
Kód: Vybrať všetko
void control_thread(void * pvParameters) {
RegisterSetODentryCallBack(CO_D.CO_CAN1, 0x2000, 0x00, &CommandWordUpdate); //Control word
while (1) {
vTaskDelay(ARM_CONTROL_THREAD_DELAY_TIMER);
}
}
Touto funkcí, jsem nastavil callback funkce, vytvořené pomocí CANfestivalu..
Kód: Vybrať všetko
RegisterSetODentryCallBack(CO_D.CO_CAN1, 0x2000, 0x00, &OnArmCommandWordUpdate);
A nyní, pokud odešlu zprávu z CANu, tak bych měl vypsat něco do sériovky:
Kód: Vybrať všetko
volatile uint8_t last_change = 0;
UNS32 CommandWordUpdate(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) {
//printf("chassis control is running\r\n");
if (last_change != (uint8_t)Switch1) {
last_change = Switch1;
Vypis("%d", Switch1);
}
asm("NOP");
return 0;
}
Taky vím, že podmínku splním, tzn. data přijímám a CAN je tudíž OK.
Kód: Vybrať všetko
if (xQueueReceive(xQ_CAN_MSG, &(CAN_Rx_m), (TickType_t) 100))
Problém je, že nic nevypisuji, protože se sem: CommandWordUpdate ani nedostanu. Nějaký nápad, co mám blbě? A myslím si, že chyba je tasku:
control_thread
-- Spojený príspevok 14 Feb 2019, 13:44 --
Hotovo, vyřešeno....
Měl jsem špatně namapovaný callback...
Tzn. místo na adrese 0x2007, jsem to valil na 0x2000 a to je potom jasné, že to nepojede
No co dodat. Snad jedině, 2 dny v řiti a hlavně to neříkat šéfovi.