開發環境:IAR 8.30
FreeRTOS版本:10.1
- 一、移植FreeRTOS
- 二、配置IAR
- 三、配置IO、使能DMA、SPI
- 四、創建任務、開啓任務調度
一、移植FreeRTOS
- 從官網下載FreeRTOS源碼
- 將..\FreeRTOS_v10_1_0\Source目錄下的FreeRTOS源碼複製到工程目錄下
- 將..\FreeRTOS_v10_1_0\Source\portable\IAR\ARM_CM4F下的文件添加到工程目錄下
- 將..\FreeRTOS_v10_1_0\Source\portable\MemMang下的一種內存管理文件添加到工程目錄下
- 打開S32DS下FreeRTOS例程的文件夾,複製其中的FreeRTOSConfig.h到工程目錄下
- 複製S32DS中的連接文件以及腳本文件
二、配置IAR
三、配置IO、使能DMA、SPI
配置IO
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr);
使能DMA
#define EDMA_CHN0_NUMBER 0U
#define EDMA_CHN1_NUMBER 1U
#define EDMA_CHN2_NUMBER 2U
#define EDMA_CHN3_NUMBER 3U
#define EDMA_CONFIGURED_CHANNELS_COUNT 4U
edma_state_t dmaController1_State;
edma_chn_state_t dmaController1Chn0_State;
edma_chn_state_t dmaController1Chn1_State;
edma_chn_state_t dmaController1Chn2_State;
edma_chn_state_t dmaController1Chn3_State;
edma_chn_state_t * const edmaChnStateArray[] = {
&dmaController1Chn0_State,
&dmaController1Chn1_State,
&dmaController1Chn2_State,
&dmaController1Chn3_State
};
void SPI_EDMA_init(void)
{
edma_channel_config_t dmaController1Chn0_Config = {
.channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
.virtChnConfig = EDMA_CHN0_NUMBER,
.source = EDMA_REQ_LPSPI0_RX,
.callback = NULL,
.callbackParam = NULL
};
edma_channel_config_t dmaController1Chn1_Config = {
.channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
.virtChnConfig = EDMA_CHN1_NUMBER,
.source = EDMA_REQ_LPSPI0_TX,
.callback = NULL,
.callbackParam = NULL
};
edma_channel_config_t dmaController1Chn2_Config = {
.channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
.virtChnConfig = EDMA_CHN2_NUMBER,
.source = EDMA_REQ_LPSPI1_RX,
.callback = NULL,
.callbackParam = NULL
};
edma_channel_config_t dmaController1Chn3_Config = {
.channelPriority = EDMA_CHN_DEFAULT_PRIORITY,
.virtChnConfig = EDMA_CHN3_NUMBER,
.source = EDMA_REQ_LPSPI1_TX,
.callback = NULL,
.callbackParam = NULL
};
const edma_channel_config_t * const edmaChnConfigArray[] = {
&dmaController1Chn0_Config,
&dmaController1Chn1_Config,
&dmaController1Chn2_Config,
&dmaController1Chn3_Config
};
const edma_user_config_t dmaController1_InitConfig0 = {
.chnArbitration = EDMA_ARBITRATION_FIXED_PRIORITY,
.notHaltOnError = false,
};
EDMA_DRV_Init(&dmaController1_State, &dmaController1_InitConfig0, edmaChnStateArray,
edmaChnConfigArray, EDMA_CONFIGURED_CHANNELS_COUNT);
}
初始化Master--SPI
lpspi_state_t SendState;
void SPIMasterInit(void)
{
uint32_t ret = 0;
const lpspi_master_config_t Send_MasterConfig0 = {
.bitsPerSec = 10000000U,
.whichPcs = LPSPI_PCS0,
.pcsPolarity = LPSPI_ACTIVE_HIGH,
.isPcsContinuous = false,
.bitcount = 8U,
.lpspiSrcClk = 48000000U,
.clkPhase = LPSPI_CLOCK_PHASE_1ST_EDGE,
.clkPolarity = LPSPI_SCK_ACTIVE_HIGH,
.lsbFirst = false,
.transferType = LPSPI_USING_DMA,
.rxDMAChannel = 0U,
.txDMAChannel = 1U,
.callback = NULL,
.callbackParam = NULL,
};
/* SPI master configuration: clock speed: 500 kHz, 8 bits/frame, MSB first */
ret = LPSPI_DRV_MasterInit(0, &SendState, &Send_MasterConfig0);
printf("\r\n SPI Master Init : 0x%x ", ret);
/* Configure delay between transfer, delay between SCK and PCS and delay between PCS
and SCK */
LPSPI_DRV_MasterSetDelay(0, 1, 1, 1);
}
初始化Slave--SPI
lpspi_state_t ReceiveState;
void SPISlaveInit(void)
{
uint32_t ret = 0;
const lpspi_slave_config_t Receive_SlaveConfig0 = {
.pcsPolarity = LPSPI_ACTIVE_HIGH,
.bitcount = 8U,
.clkPhase = LPSPI_CLOCK_PHASE_1ST_EDGE,
.whichPcs = LPSPI_PCS0,
.clkPolarity = LPSPI_SCK_ACTIVE_HIGH,
.lsbFirst = false,
.transferType = LPSPI_USING_DMA,
.rxDMAChannel = 2U,
.txDMAChannel = 3U,
.callback = NULL,
.callbackParam = NULL,
};
ret = LPSPI_DRV_SlaveInit(0, &ReceiveState, &Receive_SlaveConfig0);
printf("\r\n SPI SlaveInit : 0x%x ", ret);
}
四、創建任務、開啓任務調度
特別注意:
1、關於systick:由於FreeRTOS中的時間片調度已經使能設置了systick,故不必在設置
2、設置中斷的組別:NVIC_SetPriorityGrouping(0x3);
3、由於FreeRTOS的中斷優先級較低,會影響到正常的信號量的獲取等,故需在程序剛開始時調用INT_SYS_SetPriority();修改系統中所有中斷的優先級
創建任務
xTaskCreate((TaskFunction_t )IPC_task, //任務函數
(const char* )"IPC_task", //任務名稱
(uint16_t )IPC_TASK_STK_SIZE, //任務堆棧大小
(void* )NULL, //傳遞給任務函數的參數
(UBaseType_t )IPC_TASK_STK_PRIO, //任務優先級
(TaskHandle_t* )&IPC_Task_Handler); //任務句柄
vTaskStartScheduler(); //開啓任務調度
Master--SPI任務函數
void IPC_task(void *pvParameters)
{
uint8_t TXBuffer[10] = {0,1,2,3,4,5,6,7,8,9};
uint8_t RXBuffer[10] = {0};
while(1)
{
LPSPI_DRV_MasterTransferBlocking(0, TXBuffer, RXBuffer, sizeof(TXBuffer), 10U);
printf("\r\n Master recever 0x%x 0x%x 0x%x 0x%x ", RXBuffer[0], RXBuffer[1],
RXBuffer[2], RXBuffer[3]);
vTaskDelay(1000);
}
}
Slave--SPI任務函數
void IPC_task(void *pvParameters)
{
uint8_t TXBuffer[10] = {9,8,7,6,5,4,3,2,1,0};
uint8_t RXBuffer[10] = {0};
while(1)
{
LPSPI_DRV_SlaveTransfer(0, TXBuffer, RXBuffer, sizeof(RXBuffer), 10U);
printf("\r\n Master recever 0x%x 0x%x 0x%x 0x%x ", RXBuffer[0], RXBuffer[1],
RXBuffer[2], RXBuffer[3]);
vTaskDelay(1000);
}
}