Итак запускаю FreeRTOS в кооперативном режиме.
Создаю несколько задач
1) LCD
2) Термдатчик
3) Светодиоды
4) Usart
Первые три (LCD,T,LED) работают через I2C. Usart сам по себе
Разделение доступа ещё не сделал, но сделаю с использованием мьютекса.
Теперь если рассмотреть две созданные задачи LCD и USART
то выглядит это так:
CODE
Код
void vTaskUsart(void *pvParameters) {
for (;;) {
//-----Происходит передача данных по USART--------------
}
}
void vTaskInitLcd(void *pvParameters) {
unsigned long int delay=0;
for (;;) {
init_I2c(); //инициализация выводов
init_lcd(); //инициализация выводов
F_LCD_INIT(); // инициализация LCD(загрузка команд)
xTaskCreate( RunLcd, ( const char * ) "lcd", configMINIMAL_STACK_SIZE, NULL,2, &xHandleTask1);
vTaskDelete(xTaskInitLcd);
}
}
void ShowLcd(void *pvParameters) {
for (;;) {
//WriteLCDdata- это почти макрос функции I2C_Send_data
//так что можно смело считать WriteLCDdata=I2C_Send_data
WriteLCDdata('H');
WriteLCDdata('E');
WriteLCDdata('L');
WriteLCDdata('L');
WriteLCDdata('O');
taskYIELD();
}
}
void I2C_Send_data(unsigned char data1,unsigned char data2){
/* initiate start sequence */
I2C_GenerateSTART(I2C2, ENABLE);
/* check start bit flag */
while(!I2C_GetFlagStatus(I2C2, I2C_FLAG_SB)){taskYIELD();};
/*send write command to chip*/
I2C_Send7bitAddress(I2C2, I2C2_SLAVE_ADDRESS7, I2C_Direction_Transmitter);
/*check master is now in Tx mode*/
//--------------------------------------------------------------------------
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){taskYIELD();}; //Spead=400KHz delay=1000 clock Spead=1KHz delay=65000 clock
/*mode register address*/
I2C_SendData(I2C2, data1);
//--------------------------------------------------------------------------
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){taskYIELD();}; //3600 Speed=100Khz
/*clear bits*/
I2C_SendData(I2C2, data2);
//--------------------------------------------------------------------------
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){taskYIELD();};
//--------------------------------------------------------------------------
/*generate stop*/
I2C_GenerateSTOP(I2C2, ENABLE);
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF)){taskYIELD();};
}
for (;;) {
//-----Происходит передача данных по USART--------------
}
}
void vTaskInitLcd(void *pvParameters) {
unsigned long int delay=0;
for (;;) {
init_I2c(); //инициализация выводов
init_lcd(); //инициализация выводов
F_LCD_INIT(); // инициализация LCD(загрузка команд)
xTaskCreate( RunLcd, ( const char * ) "lcd", configMINIMAL_STACK_SIZE, NULL,2, &xHandleTask1);
vTaskDelete(xTaskInitLcd);
}
}
void ShowLcd(void *pvParameters) {
for (;;) {
//WriteLCDdata- это почти макрос функции I2C_Send_data
//так что можно смело считать WriteLCDdata=I2C_Send_data
WriteLCDdata('H');
WriteLCDdata('E');
WriteLCDdata('L');
WriteLCDdata('L');
WriteLCDdata('O');
taskYIELD();
}
}
void I2C_Send_data(unsigned char data1,unsigned char data2){
/* initiate start sequence */
I2C_GenerateSTART(I2C2, ENABLE);
/* check start bit flag */
while(!I2C_GetFlagStatus(I2C2, I2C_FLAG_SB)){taskYIELD();};
/*send write command to chip*/
I2C_Send7bitAddress(I2C2, I2C2_SLAVE_ADDRESS7, I2C_Direction_Transmitter);
/*check master is now in Tx mode*/
//--------------------------------------------------------------------------
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)){taskYIELD();}; //Spead=400KHz delay=1000 clock Spead=1KHz delay=65000 clock
/*mode register address*/
I2C_SendData(I2C2, data1);
//--------------------------------------------------------------------------
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){taskYIELD();}; //3600 Speed=100Khz
/*clear bits*/
I2C_SendData(I2C2, data2);
//--------------------------------------------------------------------------
/*wait for byte send to complete*/
while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED)){taskYIELD();};
//--------------------------------------------------------------------------
/*generate stop*/
I2C_GenerateSTOP(I2C2, ENABLE);
while(I2C_GetFlagStatus(I2C2, I2C_FLAG_STOPF)){taskYIELD();};
}
Теперь собственно вопросы:
1) В случае зависания i2c как правильно сделать перезапуск lcd (
Хотел завести счётчик проверок условий(или по времени) в I2C_Send_data и по переполнению его создавать процесс vTaskInitLcd
потом решил что не правильно в функцию I2C_Send_data пихать внешние функции vTaskInitLcd и тд.
)
2) собственно тот же вопрос только при работе всех 4х задач.
3) Как запустить функцию(или задачу) I2C_Send_data с удалением по таймауту.(т.е если процесс запущен больше 10ms значит завис)