依据pru-icss-5.1.0 SDK内例程,创建了一个pru CCS测试工程,主要功能如下
void main(void)
{
struct pru_rpmsg_transport transport;
uint16_t src, dst, len;
volatile uint8_t *status;
int delay_cnt;
/* Allow OCP master port access by the PRU so the PRU can read external memories */
CT_CFG.SYSCFG_bit.STANDBY_INIT = 0;
/* Clear the status of the PRU-ICSS system event that the ARM will use to 'kick' us */
CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;
/* Make sure the Linux drivers are ready for RPMsg communication */
status = &resourceTable.rpmsg_vdev.status;
while (!(*status & VIRTIO_CONFIG_S_DRIVER_OK));
/* Initialize the RPMsg transport structure */
pru_rpmsg_init(&transport, &resourceTable.rpmsg_vring0, &resourceTable.rpmsg_vring1, TO_ARM_HOST, FROM_ARM_HOST);
/* Create the RPMsg channel between the PRU and ARM user space using the transport structure. */
while (pru_rpmsg_channel(RPMSG_NS_CREATE, &transport, CHAN_NAME, CHAN_DESC, CHAN_PORT) != PRU_RPMSG_SUCCESS);
gpio_dir_set_addr = GPIO3_BASE_ADDR + GPIO_SETDATAOUT_OFFSET;
gpio_dir_clr_addr = GPIO3_BASE_ADDR + GPIO_CLRDATAOUT_OFFSET;
gpio_pul_set_addr = GPIO2_BASE_ADDR + GPIO_SETDATAOUT_OFFSET;
gpio_pul_clr_addr = GPIO2_BASE_ADDR + GPIO_CLRDATAOUT_OFFSET;
/* pulse motor control signal initialization */
/* set pulse motor reverse rotation & power up PUL */
*(uint32_t*)gpio_dir_set_addr |= MOTOR_CTL_DIR;
*(uint32_t*)gpio_pul_set_addr |= MOTOR_CTL_PUL;
/* if default pul_freq = 20Khz , pul_low_delay_cnt = DEF_DELAY_CNT / DELAY_CALIB_FACTOR - PUL_HIGH_DELAY_CNT*/
pul_low_delay_cnt = DEF_DELAY_CNT;
while (1) {
/* Pulse signal control of pulse motor */
if(pul_low_delay_cnt == DEF_DELAY_CNT) {
/* Set MOTOR_CTL_PUL to low level*/
*(uint32_t*)gpio_pul_clr_addr |= MOTOR_CTL_PUL;
} else {
/* Set MOTOR_CTL_PUL to low level*/
*(uint32_t*)gpio_pul_clr_addr |= MOTOR_CTL_PUL;
/* delay cnt form ARM set pulse motor frequency */
delay_cnt = pul_low_delay_cnt;
while (delay_cnt--);
/* Set MOTOR_CTL_PUL to high level*/
*(uint32_t*)gpio_pul_set_addr |= MOTOR_CTL_PUL;
/* The minimum pulse width is 500ns */
delay_cnt = PUL_HIGH_DELAY_CNT;
while (delay_cnt--);
}
/* Check bit 30 of register R31 to see if the ARM has kicked us */
if (__R31 & HOST_INT) {
/* Clear the event status */
CT_INTC.SICR_bit.STATUS_CLR_INDEX = FROM_ARM_HOST;
/* Receive all available messages, multiple messages can be sent per kick */
while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) {
rpmsg_response(len);
}
}
}
}
/* rpmsg response function, make corresponding actions according to the received MSG */
void rpmsg_response(uint16_t len)
{
uint32_t rpmsg_pul_freq = 0;
if (payload[0] == 'F' && payload[1] == 'W' && payload[2] == 'D') {
/* if rpmsg = "FWD", set pulse motor forward rotation */
*(uint32_t*)gpio_dir_clr_addr |= MOTOR_CTL_DIR;
} else if (payload[0] == 'R' && payload[1] == 'E' && payload[2] == 'V') {
/* if rpmsg = "REV", set pulse motor reverse rotation */
*(uint32_t*)gpio_dir_set_addr |= MOTOR_CTL_DIR;
} else {
/* get pulse frequency(Hz) */
rpmsg_pul_freq = atoi((const char *)payload);
/* Convert pul low level time count value */
if (rpmsg_pul_freq > PUL_MOTOR_MIN_FREQ && rpmsg_pul_freq <= PUL_MOTOR_MAX_FREQ)
pul_low_delay_cnt = (int)(PRU_FREQ * 1.0 / rpmsg_pul_freq / DELAY_CALIB_FACTOR - PUL_HIGH_DELAY_CNT);
else if(rpmsg_pul_freq == PUL_MOTOR_MIN_FREQ)
pul_low_delay_cnt = DEF_DELAY_CNT;
}
}
将编译生成的.out文件在ARM加载时报错。

当我如下删减代码后,可以正常加载。
while (pru_rpmsg_receive(&transport, &src, &dst, payload, &len) == PRU_RPMSG_SUCCESS) {
//rpmsg_response(len);
}

这看起来像是内存分配问题,0x1368为工程CMD文件PRU_IMEM段使用大小。我不太清楚需要修改那些地方去解决这个问题,在工程resource_table文件中没有找到有相关定义。
